之前对docker的了解一直只是停留在听说过,一些名词诸如集装箱,打包,隔离,轻量级等等。最近有参与到公司弹性扩容的建设中,因此对docker的实现原理也有了一些了解,在此总结一下。
容器和虚拟机相比
容器和虚拟机都有资源隔离和分配的优点, 但不同虚拟机运行在不同的操作系统kernal上,而容器之间则是共享kernal,各个容器在宿主机上互相隔离,并在用户态下运行。这导致虚拟机镜像一般比容器要打很多,同时虚拟机的启动速度也比容器更慢。
docker的资源隔离
登录到docker容器中,只能访问到本容器中的进程、用户、网络设备等。这个技能就是通过linux kernal提供的Namespace实现的。
docker的资源限制
资源限制是指为不同的容器分配不同配置的资源,比如一台宿主机上有5个容器,为了使不同容器能充分使用且只能使用自己属于自己的资源,就需要进行资源限制。资源限制是通过linux的cgroups实现的。Linux Cgroups(Control Groups)提供了对一组进程及将来子进程的资源限制、控制和统计的能力,这些 资源 包括 CPU、内存、存储、网络等。
关于镜像打包和存储
每一个docker image 都是由一系列的read only layer组成的。当启动一个容器的时候,docker会为其创建一个read only的init layer,用来存储容器内环境相关的内容,除此之外,docker还会为其创建一个read write layer来执行所有的写操作。如果写操作影响到镜像文件,docker会把受到影响的文件复制一份再进行写操作。这个技能则是通过linux提供的AUFS实现的。AUFS起源于UnionFS,通过它可以把多个文件系统联合到一个挂载点。它使用branch把不同文件的文件和目录透明地覆盖,形成一个单一一致的文件系统。这些branch或者是read-only的,或者是read-write的,所以当对这个虚拟后的联合文件系统进行写操作的时候,系统是真正写到了一个新的文件中。看起来这个虚拟后的联合文件系统是可以对任何文件进行操作 的,但是其实它并没有改变原来的文件,这是因为unionfs用到了一个重要的资源管理技术,叫写时复制。它的 思想是,如果一个资源是重复的,但没有任何修改,这时并不需要立即创建一个新的资源,这个资源可以被新旧 实例共享。创建新资源发生在第一次写操作,也就是对资源进行修改的时候。