“ 上次的问题主要总结了Namespace和Cgroups,在来讲讲另外两个容器技术rootfs和Volume”
小鲸鱼有大能量
01.容器镜像
1.rootfs,容器的举家搬迁
容器启动时,一般会通过chroot等命令切换进程的根目录,已达到让容器的目录结构更真实。
chroot的作用就是帮忙我们“changeroot file system”,改变进程的根目录到指定的位置。
例如指定$HOME/test作为/bin/bash进程的根目录
chroot $HOME/test /bin/bash
所以,为了能够让容器的根目录更真实,一般会在这个容器的根目录下挂载一个完整的操作系统的文件系统,比如CentOS 7的ISO。这样当容器启动之后,我们在容器中通过“ls /”查看跟目录下的内容,就和CentOS 7的内容一样。
这个挂载在容器根目录上,用来为容器进程提供隔离后执行环境的文件系统,就是“容器镜像”,叫做:rootfs(根文件系统)。Docker镜像是Docker容器的静态视角,Docker容器是 Docker镜像的运行状态。rootfs只是一个操作系统所包含的文件、配置和目录,并不包括操作系统内核。实际上,同一台机器上的所以容器,都共享主机操作系统的内核!!
同时Docker镜像又是由多个文件系统叠加而成的(联合挂载),每个层仅包含了前一层的差异部分。这些层通过联合文件系统(Union File System)叠加在一起,使得我们看起来Docker只有一层。
通俗地讲,联合挂载技术可以在一个挂载点同时挂载多个文件系统,将挂载点的原目录与被挂载内容进行整合,使得最终可见的文件系统将会包含整合之后的各层的文件和目录。实现这种联合挂载技术的文件系统通常被称为联合文件系统。
2.layer,分层的好处
Docker镜像rootfs包含了三个部分:只读层(镜像层),init层,读写层(容器层)
只读层,包含了最原始的rootfs文件,包括文件目录,基础配置等
读写层,最开始是一个空白的层,一旦在容器里做了写操作,内容就会以增量的方式出现在该层。而在需要修改或删除只读层的文件时,会在该层生成新的文件来覆盖(其实只是隐藏)只读层文件。当Docker commit或push这个修改过的容器文件系统为一个新的镜像时,保存的内容仅为最上层读写文件系统中被更新过的文件,原来的只读层的内容不会有任何变化。
Init层,是夹在只读层和可读写层中间的层,专门用来存放/etc/hosts, /etc/resolv.conf等文件。对该层的修改,同样只会在当前容器生效,不会因为Docker commit或push而影响到Docker Hub里的镜像。
说了这么多,其实分层的好处就是我下载同一个镜像的不同版本,增加的大小只有读写层那部分,只读层是不再需要下载的,因为我们在本地已经有了呀,同时我们修改也不会影响其他人,我“无法修改”只读层。
附上一张图片,希望能够帮助理解
02.容器的最核心
容器核心原理,三板斧
1. 启用Linux Namespace配置
2. 设置指定的Cgroups参数
3. 切换进程的根目录,rootfs
03.Volume
1.Volume,内外沟通的桥梁
为了能够保存(持久化)数据以及共享容器间的数据,Docker提出了Volume的概念。简单来说,Volume就是目录或者文件,它可以绕过默认的联合文件系统,而以正常的文件或者目录的形式存在于宿主机上。
Volume机制,允许我们将宿主机上指定的目录或文件,挂载到容器里面进行读取和修改。
把宿主机目录挂载进容器
指定宿主机目录
$ docker run –v /home:/test …(也可以在Dockerfile里面定义VOLUME来实现挂载)
把宿主机/home目录挂载到容器的/test目录上,这样就可以内外传输数据了。
注意:容器中对test目录的操作,都不会跟随docker commit提交。
2. 把它做成数据容器
不同的容器之间,还可以通过Volume来共享数据
$ docker run -it -h NEWCONTAINER --volumes-from container-test
这样,在NEWCONTAINER这个容器里,就能够看到container-test的目录了,且无论container-test容器是否在运行着。
基于这个特性,就产生了数据容器的应用,最常用的就是用来持久化数据库,配置文件和数据文件等。
以持久化postgres数据库为例
$ docker run --name dbdata postgres echo "Data-only container for postgres"
该命令将会创建一个已经包含在Dockerfile里定义过Volume的postgres镜像,运行echo命令然后退出,当中持久化仓库。当我们运行docker ps命令时,echo可以帮助我们识别某镜像的用途。
$ docker run -d --volumes-from dbdata --name db1 postgres
运行真正的postgres数据库容器,并且共享dbdata的Volume。
使用数据容器的两个注意点:
不要运行数据容器,这纯粹是在浪费资源。
不要为了数据容器而使用“最小的镜像”,如busybox或scratch,只使用数据库镜像本身就可以了。我们已经拥有该镜像,所以并不需要占用额外的空间。
04. 下期预告
到底啥时Overlay技术,怎么看起来这么高端呢;怎么来自己build一个容器呢,后面我们一起学习把,希望能够和大家一起成长,毕竟在现在这个AI大潮中,我们也不能落下啊!!
如果喜欢我的文章,那就关注我吧!
万分感谢!