《Docker进阶与实战》——3.3节Docker image的组织结构

简介:

本节书摘来自华章社区《Docker进阶与实战》一书中的第3章,第3.3节Docker image的组织结构,作者华为Docker实践小组,更多章节内容可以访问云栖社区“华章社区”公众号查看

3.3 Docker image的组织结构
上节讲到Docker image是用来启动容器的只读模板,提供容器启动所需要的rootfs,那么Docker是怎么组织这些数据的呢?

3.3.1 数据的内容
Docker image包含着数据及必要的元数据。数据由一层层的image layer组成,元数据则是一些JSON文件,用来描述数据(image layer)之间的关系以及容器的一些配置信息。下面使用overlay存储驱动对Docker image的组织结构进行分析,首先需要启动Docker daemon,命令如下:

# docker daemon -D –s overlay –g /var/lib/docker

这里从官方镜像库下载busybox镜像用作分析。由于前面已经下载过该镜像,所以这里并没有重新下载,而只是做了简单的校验。可以看到Docker对镜像进行了完整性校验,这种完整性的凭证是由镜像仓库提供的。相关内容会在后面的章节提到,这里不再展开
介绍。

$ docker pull busybox
Using default tag: latest
latest: Pulling from library/busybox
cf2616975b4a: Already exists 
8c2e06607696: Already exists 
Digest: sha256:38a203e1986cf79639fb9b2e1d6e773de84002feea2d4eb006b52004ee8502d
Status: Image is up to date for busybox:latest
$  docker history busybox      #为了排版对结果做了一些整理
IMAGE                CREATED           CREATED BY                   SIZE
8c2e06607696     4 months ago                                       0 B
6ce2e90b0bc7     4 months ago      /bin/sh -c #(nop) ADD file        2.43 MB
cf2616975b4a     4 months ago      /bin/sh -c #(nop) MAINTAINER     0 B
该镜像包含cf2616975b4a、6ce2e90b0bc7、 8c2e06607696三个layer。让我们先到本地存储路径一探究竟吧。
# ls  -l /var/lib/docker
total 44
drwx------ 2 root root 4096 Jul 24 18:41 containers           #存放容器运行相关信息
drwx------ 3 root root 4096 Apr 13 14:32 execdriver 
drwx------ 6 root root 4096 Jul 24 18:43 graph                #Image各层的元数据
drwx------ 2 root root 4096 Jul 24 18:41 init
-rw-r--r-- 1 root root 5120 Jul 24 18:41 linkgraph.db
drwxr-xr-x 5 root root 4096 Jul 24 18:43 overlay              #Image各层数据
-rw------- 1 root root  106 Jul 24 18:43 repositories-overlay #Image总体信息
drwx------ 2 root root 4096 Jul 24 18:43 tmp
drwx------ 2 root root 4096 Jul 24 19:09 trust                #验证相关信息
drwx------ 2 root root 4096 Jul 24 18:41 volumes              #数据卷相关信息

1.总体信息
从repositories-overlay文件可以看到该存储目录下的所有image以及其对应的layer ID。为了减少干扰,实验环境之中只包含一个镜像,其ID为8c2e06607696bd4af,如下。

# cat repositories-overlay  |python -m json.tool
{
"Repositories": {
    "busybox": {
        "latest": "8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55"
            }
        }
}

2.数据和元数据
graph目录和overlay目录包含本地镜像库中的所有元数据和数据信息。对于不同的存储驱动,数据的存储位置和存储结构是不同的,本章不做深入的讨论。可以通过下面的命令观察数据和元数据中的具体内容。元数据包含json和layersize两个文件,其中json文件包含了必要的层次和配置信息,layersize文件则包含了该层的大小。

# ls -l graph/8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/
total 8
-rw------- 1 root root 1446 Jul 24 18:43 json       
-rw------- 1 root root    1 Jul 24 18:43 layersize  
# ls -l overlay/8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/
total 4
drwxr-xr-x 17 root root 4096 Jul 24 18:43 root

可以看到Docker镜像存储路径下已经存储了足够的信息,Docker daemon可以通过这些信息还原出Docker image:先通过repositories-overlay获得image对应的layer ID;再根据layer对应的元数据梳理出image包含的所有层,以及层与层之间的关系;然后使用联合挂载技术还原出容器启动所需要的 rootfs和一些基本的配置信息。

3.3.2 数据的组织
从上节看到,通过repositories-overlay可以找到某个镜像的最上层layer ID,进而找到对应的元数据,那么元数据都存了哪些信息呢?可以通过docker inspect得到该层的元数据。为了简单起见,下面的命令输出中删除了一些与讨论无关的层次信息。

意 docker inspect并不是直接输出磁盘中的元数据文件,而是对元数据文件进行了整理,使其更易读,比如标记镜像创建时间的条目由created改成了Created;标记容器配置的条目由container_config改成了ContainerConfig,但是两者的数据是完全一致的。

$ docker inspect busybox:latest
[
{
    "Id": "8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55",
    "Parent": "6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea",
    "Comment": "",
    "Created": "2015-04-17T22:01:13.062208605Z",
    "Container": "811003e0012ef6e6db039bcef852098d45cf9f84e995efb93a176a11e9aca6b9",
    "ContainerConfig": {
        "Hostname": "19bbb9ebab4d",
        "Domainname": "",
        "User": "",
        "AttachStdin": false,
        "AttachStdout": false,
        "AttachStderr": false,
        "ExposedPorts": null,
        "PublishService": "",
        "Tty": false,
        "OpenStdin": false,
        "StdinOnce": false,
        "Env": null,
        "Cmd": [
            "/bin/sh",
            "-c",
            "#(nop) CMD [\"/bin/sh\"]"
        ],
    "DockerVersion": "1.6.0",
    "Author": "Jevome Petazzoni \u003cjerome@docker.com\u003e",
    "Config": {
        "Hostname": "19bbb9ebab4d",
        "Domainname": "",
        "User": "",
        "AttachStdin": false,
        "AttachStdout": false,
        "AttachStderr": false,
        "ExposedPorts": null,
        "PublishService": "",
        "Tty": false,
        "OpenStdin": false,
        "StdinOnce": false,
        "Env": null,
        "Cmd": [
            "/bin/sh"
        ],
    "Architecture": "amd64",
    "Os": "linux",
    "Size": 0,
    "VirtualSize": 2433303,
    "GraphDriver": {
        "Name": "aufs",
        "Data": null
    }
}
]

对于上面的输出,有几项需要重点说明一下:
Id:Image的ID。通过上面的讨论,可以看到image ID实际上只是最上层的layer ID,所以docker inspect也适用于任意一层layer。
Parent:该layer的父层,可以递归地获得某个image的所有layer信息。
Comment:非常类似于Git的commit message,可以为该层做一些历史记录,方便其他人理解。
Container:这个条目比较有意思,其中包含哲学的味道。比如前面提到容器的启动需要以image为模板。但又可以把该容器保存为镜像,所以一般来说image的每个layer都保存自一个容器,所以该容器可以说是image layer的“模板”。
Config:包含了该image的一些配置信息,其中比较重要的是:“env”容器启动时会作为容器的环境变量;“Cmd”作为容器启动时的默认命令;“Labels”参数可以用于docker images命令过滤。
Architecture:该image对应的CPU体系结构。现在Docker官方支持amd64,对其他体系架构的支持也在进行中。
通过这些元数据信息,可以得到某个image包含的所有layer,进而组合出容器的rootfs,再加上元数据中的配置信息(环境变量、启动参数、体系架构等)作为容器启动时的参数。至此已经具备启动容器必需的所有信息。

相关文章
|
3月前
|
Docker 容器
电子书阅读分享《4天实战 轻松玩转docker》
电子书阅读分享《4天实战 轻松玩转docker》
123 3
|
3月前
|
分布式计算 Java Linux
【深入浅出Docker原理及实战】「原理实战体系」零基础+全方位带你学习探索Docker容器开发实战指南(Dockerfile使用手册)
Docker 是一套构建在 Linux 内核之上的高级工具,旨在帮助开发人员和运维人员更轻松地交付应用程序和依赖关系,实现跨系统和跨主机的部署。使用安全且轻量级的容器环境来实现这一目标。容器可以手动创建,也可以通过编写 Dockerfile 自动创建。开发人员和运维人员可以将应用程序及其依赖打包到容器中,实现应用程序的可移植性和环境一致性。
114 5
【深入浅出Docker原理及实战】「原理实战体系」零基础+全方位带你学习探索Docker容器开发实战指南(Dockerfile使用手册)
|
13天前
|
JavaScript 前端开发 Docker
全栈开发实战:结合Python、Vue和Docker进行部署
【4月更文挑战第10天】本文介绍了如何使用Python、Vue.js和Docker进行全栈开发和部署。Python搭配Flask创建后端API,Vue.js构建前端界面,Docker负责应用的容器化部署。通过编写Dockerfile,将Python应用构建成Docker镜像并运行,前端部分使用Vue CLI创建项目并与后端交互。最后,通过Nginx和另一个Dockerfile部署前端应用。这种组合提升了开发效率,保证了应用的可维护性和扩展性,适合不同规模的企业使用。
|
1月前
|
Unix Docker 容器
【超强图解Docker常见命令与实战】
【超强图解Docker常见命令与实战】
51 0
|
1月前
|
Java 网络安全 开发者
【Docker】5、Dockerfile 自定义镜像(镜像结构、Dockerfile 语法、把 Java 项目弄成镜像)
【Docker】5、Dockerfile 自定义镜像(镜像结构、Dockerfile 语法、把 Java 项目弄成镜像)
43 0
|
2月前
|
Java Linux Docker
Docker入门到实战
Docker入门到实战、Centos7安装Docker
|
2月前
|
Cloud Native Go 数据安全/隐私保护
自定义Docker镜像推送到Docker Hub实战
自定义Docker镜像推送到Docker Hub实战
81 2
自定义Docker镜像推送到Docker Hub实战
|
2月前
|
KVM 虚拟化 Android开发
DP读书:鲲鹏处理器 架构与编程(十二)鲲鹏软件实战案例Docker+KVM的部署
DP读书:鲲鹏处理器 架构与编程(十二)鲲鹏软件实战案例Docker+KVM的部署
54 1
|
3月前
|
Linux Docker Python
Python实战技术 - Python虚拟隔离环境 和 Docker技术
Python实战技术 - Python虚拟隔离环境 和 Docker技术
204 0
|
3月前
|
Kubernetes 监控 应用服务中间件
深入Docker实战(第2版):构建、部署和优化容器化应用
深入Docker实战(第2版):构建、部署和优化容器化应用
44 0