与传统虚拟机不同,docker容器是进程级别的,通过linux namespace对网络、文件系统、进程间通讯等六个方面进行隔离, 见下表
namespace | 系统调用参数 | 隔离内容 |
---|---|---|
UTS | CLONE_NEWUTS | 主机名与域名 |
IPC | CLONE_NEWIPC | 信号量、消息队列和共享内存 |
PID | CLONE_NEWPID | 进程编号 |
Network | CLONE_NEWNET | 网络设备、网络栈、端口等等 |
Mount | CLONE_NEWNS | 挂载点(文件系统) |
User | CLONE_NEWUSER | 用户和用户组 |
并通过cgroup对进程的cpu、memory、IO做限制,从而成为一个容器
在容器环境里可认为是唯一存在的,有自己的网络设备、主机名、用户、进程号
隔离能达到什么样的效果?以网络层举例
比如我们想启动多个nginx服务,每个nginx必须修改监听端口,提供访问地址分别为
:8080 :8081 :8082
而放进容器里后,容器都监听8080端口,并不会和其它进程冲突,访问方式变为
:8080 :8080 :8080
运行环境统一
容器的文件系统继承自docker镜像,简单来说,容器创建时,以只读方式挂载镜像的文件系统,运行时发生的文件变化发生在其它目录,当容器销毁时,这些目录也会删除,而镜像内容不会发生变化
容器运行时发生的文件变化,在容器销毁后不会保留,用同一个镜像创建的多个容器,内容总是一致的
数据持久化
容器销毁后数据不保留,但有些数据是想要做持久化的,docker提供了卷挂载的方式,将外部卷映射到容器的指定目录,卷可以是宿主机上的一个目录,可以是NAS目录,也可以是一个块存储目录,对于容器内的进程来说,什么类型的卷不是关心的内容,它只需要将需要持久化的数据写入对应的目录即可
容器是一次性的
容器内的最后一个命令需要阻塞在前台,当进程退出时容器即销毁,不要以虚拟机的方式使用容器,业务层的一个新版本,要产生新的容器来运行,不需要进入容器来维护