热点 做网站和营销 我只服他,常州免费网站建站模板,郑州怎么做外贸公司网站,山西省建设注册中心网站1.容器-我的小世界
不知道大家看没看过小说《完美时间》#xff0c;里面石昊经常进入一个小世界在里面与世隔绝的修炼或者战斗#xff0c;总之就是在一个完全封闭的空间里做他想做的事情而与外界隔离#xff0c;不受侵扰。通过前面的分析我们知道#xff0c;Namepace让应用…1.容器-我的小世界
不知道大家看没看过小说《完美时间》里面石昊经常进入一个小世界在里面与世隔绝的修炼或者战斗总之就是在一个完全封闭的空间里做他想做的事情而与外界隔离不受侵扰。通过前面的分析我们知道Namepace让应用进程只能看到该 Namespace 内的“小世界”而 Cgroups 的作用是“限制”它给这个“小世界”围上了一圈看不见的封印。在小说中的“小世界”不仅仅是这么一个空间里面如同一个真实世界一样有大地及大地上的各种物品对比到容器那么容器这个小世界还缺少文件系统比如启动一个ubuntu或者centos容器里面我们看到是一份完整的操作系统目录这个文件系统就是通过Mount Namescpace来实现的。当我们启动容器进程时先启用Mount Namespace,然后挂载指定的目录。 下面是我启动的一个centos的容器然后进入到容器 我们看到根目录下我们看到的真实的操作系统一样是一个完整的操作系统文件。这是为了让容器这个根目录看起来更真实一般会在容器的根目录下挂载一个完整操作系统的文件系统我们把这个文件系统就是所谓的“容器镜像image”,学名rootfs(根文件系统)。由于Monut Namespace的存在这个挂载对宿主机不可见只对当前容器进程起作用这样就可以随便在容器内部折腾了。那这是怎么做到的呢 其实在 Linux 操作系统里有一个名为 chroot 的命令,可以在 shell 中方便地完成这个工作。它的作用就是帮我们“change root file system”即改变进程的根目录到你指定的位置。 所以docker运行容器就是在宿主机上运行一个特殊的进程docker为这个进程启动Linux Namespace配置设置指定的Cgroups参数、切换进程的根目录Change Root。 虽然这里的rootfs根文件系统包含了一个操作系统完整的文件、目录和配置但是却没系统内核操作系统只有在开机的时候才会加载指定版本的内核镜像。也就是说rootfs很像一完美时间小说中仙体只有躯壳没有灵魂。 部署在同一台机器上的所有容器都共享宿主机操作系统的内核。
2.镜像-对环境一致性的理解
在开始的一掌节我也介绍了docker的好处就是保持环境的一致性这里再加深一下理解。拿java项目来说这里所说的环境一致性不仅仅是说用的jar包的版本一致、jdk的版本一致更重要的是来操作系统都一致正式这种深入到操作系统级别的运行环境一致性才打通了应用在本地开发和远端执行环境之间难以逾越的鸿沟。
3.镜像-联合文件系统
对于联合文件系统之前我也提过但并不是太详情这里我以示例的方式说名一下从根本上理解这个东西。
3.1 联合文件系统-overlayfs
现在docker使用的联合文件系统时overlay,这里我们先简单说一下overlayfs。overlayfs联合文件系统可让你使用2个目录挂载文件系统“下层”目录和“上层”目录。文件系统的下层目录是只读的文件系统的上层目录可以读写。当进程“读取”文件时overlayfs文件系统驱动将优先在上层目录upperdir中查找并从该目录中读取文件找不到则在下层目录lowerdir中查找。当进程写入文件时overlayfs会将其写入上层目录upperdir。
3.2 联合文件系统-overlayfs演示示例
这里我就以overlay来演示一下。
首先创建几个目录在myfile下创建lower、upper、work、merged
mkdir -p myfile/lower myfile/upper myfile/work myfile/merged然后我在upper目录下创建a.txt,m.txt两个文件在lower目录下创建b.txt,m.txt 执行挂载命令
mount -t overlay overlay -o lowerdirlower,upperdirupper,workdirwork /myfile/merged解释下这个命令 lowerdir参数下层目录可以挂载多个下层目录多个目录之间采用分号分隔如下所示
mount -t overlay overlay -o lowerdir/dir1:/dir2:/dir3 ./mergedupperdir参数上层目录 merged目录lower和upper合并后的虚拟目录。同时也是容器挂载点 lowerdir和upperdir整合起来提供统一的视图给容器作为根文件系统 查看merged目录下的文件 我们看到x.txt显示的是upper目录的内容。
3.3联合文件系统-overlayfs合并规则
我这里就不一一演示了把合并和读写规则说一下 合并规则整理如下 1.读规则
upper没有, 而lower有的文件时需从lower读只在upper有的文件时则直接从 upper 读lower 和 upper 都有的文件时则直接从 upper 读。
2.写规则
对只在 upper 有的文件时则直接在 upper 写对在lower 和 upper 都有的文件时则直接在 upper 写。对只在 lower 有的文件写时则会做一个拷贝的操作先从 lower将文件拷贝一份到upper,写的操作只对从lower 复制到 upper 的文件生效而 lower 还是原文件。
3.删除规则
lower 和 upper 都有的文件upper 的会被删除在 upper 目录下创建一个 ‘without’ 文件而 lower 的不会被删除。lower 有而 upper 没有的文件时会为被删除的文件在 upper 目录下创建一个 ‘without’ 文件而 lower 的不会被删除。lower 和 upper 都有的目录时upper 的会被删除在 upper 目录下创建一个类似‘without’ 文件的 ‘opaque’ 目录而 lower 的不会被删除
3.镜像-分层
之前我们介绍过镜像制作是分层的Dockerfile中的每一个命令都是一个层。那么为什么要分层呢其实就是考虑镜像的复用性。· 加入我现在在用 Centos7.6操作系统做了一个 image然后又在里面安装了 Java 环境用来部署我的 Java 应用。这时其他人也希望能够直接使用我安装过 Java 环境的 image而不是重复这个流程。那怎么办号呢 我想到的比较简单的方法是在制作镜像的时候每做一步“有意义”的操作就保存一个镜像出来这样其他人就可以按需求去用他需要的 rootfs 了。可一旦其他人修改了这个镜像新旧两个新旧两个镜像之间就没有任何关系了。这样做的结果就会产生非常的没有任何关联的镜像也就是碎片化严重。那么既然这些修改都基于一个旧的 image我们能不能以增量的方式去做这些修改呢这样做的好处是所有人都只需要维护相对于 base rootfs 修改的增量内容而不是每次修改都制造一个“fork”。由此产生了分层的概念。Docker 在镜像的设计中引入了层layer的概念。即用户制作镜像的每一步操作都会生成一个层也就是一个增量镜像。镜像主要分为三个层只读层、可读写层、init层。
3.1镜像-只读层
只读层位于联合文件系统的最下层对应overlayfs中的lower目录
3.2镜像-可读写层
可读写层位于联合文件系统的最上层对应overlayfs中的upper目录中。他也称为容器层在没有写入文件之前这个目录是空的。而一旦在容器里做了写操作你修改产生的内容就会以增量的方式出现在这个层中。 所以最上面这个可读写层的作用就是专门用来存放你修改 rootfs 后产生的增量无论是增、删、改都发生在这里。
3.3镜像-init层
它是一个以“-init”结尾的层夹在只读层和读写层之间。Init 层是 Docker 项目单独生成的一个内部层专门用来存放 /etc/hosts、/etc/resolv.conf 等信息。
3.4.镜像分层-copy-on-write
这里还有一个copy-on-write机制这里简单说一下。 我们知道最上面的可读写层也被称为容器层下面的只读层称为镜像层所有的增删查改操作都只会作用在容器层相同的文件上层会覆盖掉下层。比如修改一个文件的时候首先会从上到下查找有没有这个文件找到就复制到容器层中然后在容器层中修改修改的结果就会作用到下层的文件这种方式也被称为copy-on-write。
4.小结
这一篇博客我感觉写的不是很好还是没能组织好语言透彻的说明这个原理。看看后续有时间再重新写吧。这个就先这样吧。