当前位置: 首页 > news >正文

【深入剖析K8s】容器技术基础(三):深入理解容器镜像 文件角度

容器里的进程‘看到’’的文件系统

可能你立刻就能想到,这应该是一个关于MountNamespace的问题:容器里的应用进程理应‘看到”一套完全独立的文件系统°这样它就可以在自己的容器目录(比如 /tmp)下进行操作’而完全不会受宿主机以及其他容器的影响。

容器迸程哪些目录需要重新挂载’比如这个/tmp目录。
可以看到’容器里的/tmp目录是以tmpfS方式单独挂载的。容器以tmpfS(内存盘)格式重新挂载/tmp目录。
在这里插入图片描述
这就是Mount Namespace跟其他Namespace的使用略有不同的地方:它对容器进程视图的改变—定要伴随着挂载操作才能生效。

假设有—个$HOME/test目录’你想把它作为—个/bin/bash进程的根目录。

执行chroot t命令’告诉操作系统我们将使用$HOME/test目录作为/bin/bash进程的根目录。

这个挂载在容器根目录上用来为容器进程提供隔离后执行环境的文件系统’就是所谓的容器镜像。 它还有—个更专业的名字: rootfs(根文件系统)。

dock 最核心原理

Docker项目最核心的原理实际上就是为待创建的用户进程。

  • 启用Linux Namespace配置;
  • 设置指定的Cgroups参数;
  • 切换进程的根目录(change root)

rootfs 只是—个操作系统所包含的文件、配置和目录’并不包括操作系统内核。
在Llnux操作系统中这两部分是分开存放的’操作系统只有在开机启动时才会加载指定版本的内核镜像。

rootfS只是—个操作系统所包含的文件、配置和目录’并不包括操作
系统内核°在Llnux操作系统中’这两部分是分开存放的’操作系统只有在开机启动时才会加载指定版本的内核镜像°

正是由于rootfS的存在’容器才有了—个被反复强调至今的重要特:一致性

由于云端与本地服务器环境不同’因此应用的打包过程一直是使用PaaS时最麻烦的一个步骤。

’有了容器镜像(rootfs)之后,这个问题就被非常优雅地解决了。由于root色里打包的不只是应用’而是整个操作系统的文件和目录,这就意味着’应用以及它运行所需要的所有依赖都被封装在了一起。

难道每开发—个应用或者升级现有应用’都要重复制作—次rootfS吗? 既然这些修改都基于—个旧的rootfs 我们能否以增量的方式去做这些修改呢? 这样所有人都只需要维护相对于base rootfs修改的增量内容。

docker在镜像的设计中引人了层(layer)的概念。也就是说,用户制作镜像的每一步操作都会生成—个层,也就是一个增量 rootfs。

用到了—种叫作UnionFS(unlon∏lesystem’联合文件系统)的能力。它最主要的功能是将不|司位置的目录联合挂载(unionmount)到同—个目录下。比如有两个目录A和B它们分别有两个文件:
在这里插入图片描述
在这个合并后的目录C里’有a、b、x这3个文件并且x文件只有一份。这就是合并的含义。此外,如果你在目录C里对a、b、x文件做修改’这些修改也会在对应的目录A、B中生效

docker run-d ubuntu:latest sleep 3600

这个所谓的‘镜像”’实际上就是一个Ubuntu操作系统的rootfs,它的内容是Ubuntu操作系统的所有文件和目录不过, 与之前介绍的rootfs稍微不同的是, Docker镜像使用的 rootfs往往由多个“层”组成。
在这里插入图片描述
挂载点就是 /var/lib/docker/aufs/mnt/<ID>, AuFS 作为docker 的存储,当前不再使用。

5个镜像层是如何被联合挂载成这样—个完整的Ubuntu文件系统的呢
在这里插入图片描述
在这里插入图片描述
ro+wh 即 readonly+whiteout(删除的时候使用)。
在这里插入图片描述

只读层

这些层都以增量的方式分别包含了Ubuntu操作系统的—部分。

可读写层

你要删除只读层里一个名为foo的文件那么这个删除操作实际上是在可读写层创建了—个名为 .wh.foo的文件。而当我们使用完了这个修改过的容器之后,还可以使用 docker commit 和 push指令保存这个修改过的可读写层’并上传到DockerHub上供他人使用。

Init 层

Init层是—个以-init 结尾的层,夹在只读层和可读写层之间。Init层是Docker项目单独生成的—个内部层’专门用来存放/etc/hosts、 /etc/resolvconf 等信息。

但是用户往往需要在启动容器时写人一些指定的值(比如hostname) 所以需要在可读写层修改它们。
可是这些修改往往只对当前的容器有效,我们并不希望执行 docker commit 时把这些信息连同可读写层一起提交。
所以,Docker做法是在修改了这些文件之后以—个单独的层挂载出来。而用户执
行 docker commit 只会提交可读写层,因此不包含这些内容。

http://www.lryc.cn/news/246225.html

相关文章:

  • 竞赛选题 题目:基于LSTM的预测算法 - 股票预测 天气预测 房价预测
  • 开源WIFI继电器之源代码
  • NX二次开发UF_CURVE_create_arc_point_point_radius 函数介绍
  • Unsupervised MVS论文笔记(2019年)
  • 2-Python与设计模式--前言
  • 如何判别使用的junit是4还是5
  • C#-创建用于测试的父类StartupBase用于服务注入
  • JMeter之压力测试——混合场景并发
  • Python入门04字符串
  • vue3(四)-基础入门之 fetch 与 axios
  • 2016年五一杯数学建模C题二孩政策问题解题全过程文档及程序
  • 学习c#的第二十四天
  • ELK企业级日志分析平台——logstash
  • laravel8中常用路由使用(笔记四)
  • 理解 <script> 标签的 defer 和 async 属性
  • sql中group by和having的使用
  • 用python自行开发的流星监控系统meteor_monitor(第二篇)
  • Slf4j使用Logback时,Logback如何初始化
  • css之svg 制作圆及旋转
  • 学习.NET验证模块FluentValidation的基本用法(续1:其它常见用法)
  • lv11 嵌入式开发 UART实验 11
  • Ubuntu22.04下打包发布Qt5.15应用程序的方法
  • 初级JVM
  • MySQL数据库 编程入门
  • 6.golang函数
  • 软件可靠性测试常见的方法
  • C/C++字节对齐
  • 【Android知识笔记】性能优化专题(四)
  • DC电源模块的散热措施
  • uniapp H5、小程序、APP端自定义不同运行环境(开发、测试、生产)、自定义条件编译平台、以及动态修改manifest.json值讲解