首页 > 其他分享 >Docker镜像与容器的工作原理

Docker镜像与容器的工作原理

时间:2022-12-06 10:01:59浏览次数:63  
标签:Pull complete 文件 容器 内核 镜像 Docker

提纲
1、bootfs和rootfs
2、镜像层和镜像
3、容器层和容器
4、联合文件系统​



1、bootfs和rootfs

一般而言,Linux的操作系统由两类文件系统组成:bootfs(boot file system)和rootfs(root file system)。它们分别对应着系统内核与根目录文件。bootfs层主要为系统内核文件,这层的内容是无法修改的。当我们的系统在启动时会加载bootfs,当加载完成后整个内核都会存到内存中,然后系统会将bootfs卸载掉。而rootfs层则包含了系统中常见的目录和文件,比如/bin,/etc,/proc等等。

Docker的镜像是使用宿主机的bootfs层的,这使得镜像本身只需要包含rootfs层所需的文件和工具即可。因此,镜像占用的存储空间比较少,如部分极精简的镜像只有几MB大小。

不同Linux发行版本的主要区别在于rootfs层,比如ubuntu使用apt管理软件,而Centos使用yum方式。而在内核层面,两者的差别并不大。因此,可以在一台宿主机上同时运行不同Linux发行版的镜像而不出错,如在一个安装了centos的宿主机上同时启动Centos镜像的容器和Ubuntu镜像的容器。

但需要注意的是,不管容器对应的镜像使用什么操作系统,实际的内核版本都与镜像操作系统的内核无关,都采用的是宿主机的内核。如ubuntu16.04 的容器跑在Centos7.x的宿主机上,虽然ubuntu的内核版本是4.x.x,但我们在容器中看到内核为centos 7.x 的内核,即 3.x.x。如果是对内核版本的要求的程序,可能会因此受到影响。



2、镜像层和镜像

Docker镜像采用分层的结构,由一些松耦合的只读层堆叠而成,并对外展示为一个统一的对象。所有的镜像都开始于一个基础的镜像层,当我们进行修改或内容添加时,会在镜像层上面创建新的一层。

最底层通常为基础层镜像,然后再层层叠加上来,比如安装一个Python软件,此时会在基础层上面添加一个新的层,上面包含了我们所安装的Python程序。

镜像做为所有镜像层的组合,如果镜像中有相同路径的文件,则上层镜像会覆盖下层镜像的内容,最终展示为所有层的数据汇总。

如下图所示,由于第二层的文件2与第一层具有相同的文件路径,则镜像将以第二层的文件2内容进行展示,第一层只有文件1会被显示。

我们再来回顾一下前面镜像拉取时的输出内容,Pull complete结尾的每一行代表镜像中某个被拉取的层,每个层级通过一个唯一的ID进行标识。

$ docker pull nginx:1.20
1.20: Pulling from library/nginx
5eb5b503b376: Pull complete
cdfeb356c029: Pull complete
d86da7454448: Pull complete
7976249980ef: Pull complete
8f66aa6726b2: Pull complete
c004cabebe76: Pull complete
Digest: sha256:02923d65cde08a49380ab3f3dd2f8f90aa51fa2bd358bd85f89345848f6e6623
Status: Downloaded newer image for nginx:1.20
docker.io/library/nginx:1.20

镜像层的松耦合代表着它不属于某个镜像独有,当不同镜像包含相同的层时,系统只会存储该层的一份内容,这是Docker镜像的重要特点,这样的好处有利于减少存储空间的占用。如下所示,当我们拉取另一个版本的Nginx镜像时,其中ID号为5eb5b503b376的层已经存在,则会显示为Already exists,直接使用此镜像层。

$ docker pull nginx:1.21
1.21: Pulling from library/nginx
5eb5b503b376: Already exists
1ae07ab881bd: Pull complete
78091884b7be: Pull complete
091c283c6a66: Pull complete
55de5851019b: Pull complete
b559bad762be: Pull complete
Digest: sha256:2834dc507516af02784808c5f48b7cbe38b8ed5d0f4837f16e78d00deb7e7767
Status: Downloaded newer image for nginx:1.21
docker.io/library/nginx:1.21


3、容器层和容器

我们前面说到镜像层是只读模板,那么当我们使用镜像生成容器时,为什么又能写入数据呢?这个问题的答案涉及到一个概念:容器层。

当容器启动时,会有一个新的可写层被加载到镜像的顶部,这一层通常被称为容器层。所有对容器的修改都会发生在容器层,只有容器层是可写入的,容器层以下的镜像层都是只读的。

当我们对容器进行操作时,底层的工作原理如下:

读取文件:当容器需要读取文件时,会先在容器层寻找,如果没有发现,则会从最上层的镜像层往下寻找,当找到文件后读取到内存使用。

增加文件:当增加文件时,文件会直接写到最上面容器层,不会影响到镜像层内容。所以,当我们将容器删除时,容器中的文件也会随着消失。

修改文件:此时,如果该文件是在容器层的,则会直接修改。否则的话,Docker会从上往下依次在各层镜像中查找此文件 ,当找到后将其复制到容器层中,并进行修改。这被称为容器的写时复制特性(Copy-on-Write),这个技术保证了我们对容器的修改不会影响到底层的镜像,也实现了一个镜像可以被多个容器共用。

删除文件:当我们需要删除文件时,Docker也是由上往下寻找该文件 ,如果在容器层的文件会被直接删除,而在镜像层的文件则会被标记,此时在容器将不会再出现此文件,但镜像中的文件并不会做更改。



4、联合文件系统

关于镜像与容器功能的实现,依赖其使用了联合文件系统(UnionFS)技术,这是一种分层、轻量级并且高性能的文件系统。Docker 目前支持的联合文件系统包括 ​​OverlayFS​​​, ​​AUFS​​​, ​​VFS​​​ ​​Device Mapper等​​,而默认的存储驱动为Overlay2。



参考资料:
1、https://www.jb51.net/article/249144.htm

标签:Pull,complete,文件,容器,内核,镜像,Docker
From: https://www.cnblogs.com/zhangzl419/p/16954369.html

相关文章

  • docker 镜像、容器的导入导出
    1.本地镜像的载入载出1.镜像载出tar包dockersavemysql:8>/root/mysql-8.tardockersavecd3ed0dfff7e-o/root/mysql-8.targzip包dockersavemysql:8|g......
  • 为你的手机内核开启docker支持
    欢迎来到猫猫的Docker实验室喵!在这里,你将会学习如何为自己的手机开启docker支持,期待你的成果喵~文章会包含一些小技巧和docker基本异常处理,毕竟这只可爱的猫猫是不会向你......
  • 从零开始实现一个Linux容器
    欢迎来到猫猫的C语言实验室喵!序言:文中所述源码是以MIT协议开源的,本文转载请注明原创作者为Moe-hacker,除此之外无其他要求。作者其实想将本文改名为《Re:从零开始的conta......
  • 浅谈Linux容器安全:chroot,capability与namespace技术
    作者只是个萌新,大佬轻喷。文章最终确定以时间顺序浅谈Linux容器安全原理。安全原理相关知识网上已经有很多了,咱通过几个具体攻击实例来讲讲它们的真实作用。演示均在猫......
  • 离线安装docker
    #!/bin/bash#url=https://download.docker.com/linux/static/stable/x86_64docker_version=$1get_docker(){[-d"/opt/docker-${docker_version:-20.10.9}"]||......
  • Spring源码-03-容器创建
    Spring源码-03-容器创建注解Bean方式publicclassAnnotationCtxMain02{ publicstaticvoidmain(String[]args){ newAnnotationConfigApplicationContext(MyCf......
  • Spring源码-02-Bean容器
    Spring源码-02-Bean容器一类关系二宏观视角......
  • 20221205 常用Docker部署
    MySQLMySQL-DockerHub准备my.cnf配置文件[mysqld]character_set_server=utf8[client]default-character-set=utf8上传my.cnf到宿主机/data/docker/my......
  • 【最新】最全的Google镜像站地址
    写在前面遇到问题,有时光靠Baidu有时解决不了问题,所以需要求助Google,里面有好多国外网友的博客、StackoverFlow、GithubIssues、官方文档等等的大量一手英文资料,如果你想......
  • Docker远程挂载volumn插件vieux/sshfs
    通常,用在本地容器需要挂载一个远程目录的时候来使用安装vieux/sshfs插件dockerplugininstall--grant-all-permissionsvieux/sshfs使用镜像加速,我是没有下载成功......