一)理解要点
1. docker 与 Paas 平台项目区别
docker 容器区别于之前Paas平台项目,其除了打包应用软件和启停脚本外,还连同运行应用的操作系统环境一同打包
2. 理解 Linux namespace
docker 容器本质就是进程,是运用了Linux namespace 技术对各种基础硬件资源(如网络,文件系统,进程等)进行隔离(通俗理解为障眼法)为一个个单独的空间而得到的一种特殊的进程;其对比于虚拟机,优点是不用额外运行一个虚拟机操作系统,同时减少虚拟机上运行的操作系统对应用的请求调度进行拦截会增加系统的消耗。缺点是,隔离不够彻底,如共用宿主机的内核,时间等;
3. 理解 Linxu Cgroups
Cgroups(全称:Linux Control Group),是Linux的一个使用文件系统作为其配置文件,对各种基础硬件资源(如网络,文件系统,进程等)进行限制的系统;相比于虚拟机,缺点是共用宿主机的/proc文件系统。该文件系统为宿主机的运行状态信息目录。因此在容器中使用top命令查询出来的为宿主机的资源使用情况
4. docker 镜像
docker的镜像实质:根文件系统rootfs.如何理解呢?使用linux的clone()系统调用指定新的mount namespace时,就是容器实现文件系统与宿主机隔离的原理;隔离的前提是在调用clone()前必须进行磁盘的重新挂载操作,换句话说就是文件系统的隔离需要磁盘挂载动作完成后才生效,如果不进行磁盘的挂载,则即使指定了使用mount namespace,也是共享宿主机文件系统;而docker 镜像其实就是重新定义和挂载磁盘后的跟目录,该跟目录是多层(只读层,可读写层,初始化init层等)通过linux系统的联合文件系统特性拼在一起而成,且在宿主机中透明不可见,因此达到了隔离作用。起实际上是使用的chroot系统调用命令达到的效果;
5. docker 容器
docker的容器实质:通过docker exec 去理解。docker exec 是进入一个容器内部?如何实现呢?因为容器其实是一个特殊的进程。进程就有进程号,在 /proc/[进程号]/ns下存放着该进程所有的namespace文件。 通过linux 的 setns(namespace路径,在namespace下执行的命令) 调用,可以在新生成的进程中进入到该namespace中,即共享该namespace;因此可以这么理解,docker exec 其实就是重新运行一个进程,并在新起的进程中,调用setns()进入到某个容器所有的namespace中。这样就达到了进入一个容器空间内部的效果;
6. docker 数据卷
docker volume(数据卷):实质是对宿主机目录与容器进程内某个目录的一个绑定挂载。这个绑定挂载实质是linux inode替换过程。inode 理解为文件对象,对应有个dentry作为指针指向它。如 mount -bind /home /test 其实就是把容器进程内的test 目录的指针dentry 替换为了宿主机/home 的指针;而对应的镜像中各层文件系统存放在 /var/lib/docker/aufs/diff 目录下。当镜像起来变成容器后,由aufs联合文件系统起作用,存放在宿主机的 /var/lib/docker/aufs/mnt/[可读写层ID]/test 上。因此docker volume 挂载其实就是宿主机内一个目录,挂载到 /var/lib/docker/aufs/mnt/[可读写层ID]/test 上而已
二)总结
docker容器技术,其实是使用 linux namespace 进行隔离,使用 linux Cgroups 进行资源限制,mount namespace 和 chroot 进行跟文件系统的重新定义挂载(镜像),以及使用setns()进行共享另外一存在进程的namespace 视图的技术综合运用;