Docker镜像进阶:了解其背后的技术原理

什么是 docker 镜像docker

  docker 镜像是一个只读的 docker 容器模板,含有启动 docker 容器所需的文件系统结构及其内容,所以是启动一个 docker 容器的基础。docker 镜像的文件内容以及一些运行 docker 容器的配置文件组成了 docker 容器的静态文件系统运行环境:rootfs。能够这么理解,docker 镜像是 docker 容器的静态视角,docker 容器是 docker 镜像的运行状态。咱们能够经过下图来理解 docker daemon、docker 镜像以及 docker 容器三者的关系(此图来自互联网):json

Docker镜像进阶:了解其背后的技术原理

  从上图中咱们能够看到,当由 ubuntu:14.04 镜像启动容器时,ubuntu:14.04 镜像的镜像层内容将做为容器的 rootfs;而 ubuntu:14.04 镜像的 json 文件,会由 docker daemon 解析,并提取出其中的容器执行入口 CMD 信息,以及容器进程的环境变量 ENV 信息,最终初始化容器进程。固然,容器进程的执行入口来源于镜像提供的 rootfs。ubuntu

rootfs安全

  rootfs 是 docker 容器在启动时内部进程可见的文件系统,即 docker 容器的根目录。rootfs 一般包含一个操做系统运行所需的文件系统,例如可能包含典型的类 Unix 操做系统中的目录系统,如 /dev、/proc、/bin、/etc、/lib、/usr、/tmp 及运行 docker 容器所需的配置文件、工具等。在传统的 Linux 操做系统内核启动时,首先挂载一个只读的 rootfs,当系统检测其完整性以后,再将其切换为读写模式。而在 docker 架构中,当 docker daemon 为 docker 容器挂载 rootfs 时,沿用了 Linux 内核启动时的作法,即将 rootfs 设为只读模式。在挂载完毕以后,利用联合挂载(union mount)技术在已有的只读 rootfs 上再挂载一个读写层。这样,可读写的层处于 docker 容器文件系统的最顶层,其下可能联合挂载了多个只读的层,只有在 docker 容器运行过程当中文件系统发生变化时,才会把变化的文件内容写到可读写层,并隐藏只读层中的旧版本文件。架构

Docker 镜像的主要特色工具

  为了更好的理解 docker 镜像的结构,下面介绍一下 docker 镜像设计上的关键技术。操作系统

  分层docker 镜像是采用分层的方式构建的,每一个镜像都由一系列的 "镜像层" 组成。分层结构是 docker 镜像如此轻量的重要缘由。当须要修改容器镜像内的某个文件时,只对处于最上方的读写层进行变更,不覆写下层已有文件系统的内容,已有文件在只读层中的原始版本仍然存在,但会被读写层中的新版本所隐藏。当使用 docker commit 提交这个修改过的容器文件系统为一个新的镜像时,保存的内容仅为最上层读写文件系统中被更新过的文件。分层达到了在不的容器同镜像之间共享镜像层的效果。设计

  写时复制docker 镜像使用了写时复制(copy-on-write)的策略,在多个容器之间共享镜像,每一个容器在启动的时候并不须要单独复制一份镜像文件,而是将全部镜像层以只读的方式挂载到一个挂载点,再在上面覆盖一个可读写的容器层。在未更改文件内容时,全部容器共享同一份数据,只有在 docker 容器运行过程当中文件系统发生变化时,才会把变化的文件内容写到可读写层,并隐藏只读层中的老版本文件。写时复制配合分层机制减小了镜像对磁盘空间的占用和容器启动时间。3d

  内容寻址在 docker 1.10 版本后,docker 镜像改动较大,其中最重要的特性即是引入了内容寻址存储(content-addressable storage) 的机制,根据文件的内容来索引镜像和镜像层。与以前版本对每一个镜像层随机生成一个 UUID 不一样,新模型对镜像层的内容计算校验和,生成一个内容哈希值,并以此哈希值代替以前的 UUID 做为镜像层的惟一标识。该机制主要提升了镜像的安全性,并在 pull、push、load 和 save 操做后检测数据的完整性。另外,基于内容哈希来索引镜像层,在必定程度上减小了 ID 的冲突而且加强了镜像层的共享。对于来自不一样构建的镜像层,主要拥有相同的内容哈希,也能被不一样的镜像共享。blog

相关文章
相关标签/搜索