《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
AI 代码解读

这里从官方镜像库下载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              #数据卷相关信息
AI 代码解读

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

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

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
AI 代码解读

可以看到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
    }
}
]
AI 代码解读

对于上面的输出,有几项需要重点说明一下:
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,再加上元数据中的配置信息(环境变量、启动参数、体系架构等)作为容器启动时的参数。至此已经具备启动容器必需的所有信息。

目录
打赏
0
0
0
0
1408
分享
相关文章
Docker Image即Docker镜像
Docker 镜像是 Docker 容器的基础,包含了运行应用程序所需的一切。通过 Dockerfile 可以方便地创建自定义镜像,并且利用 Docker 提供的命令可以轻松管理和使用这些镜像。掌握 Docker 镜像的创建、管理和使用,是进行容器化应用开发和部署的基础技能。希望本文能帮助读者更好地理解 Docker 镜像的概念和操作,提高开发和运维效率。
85 13
《docker基础篇:4.Docker镜像》包括是什么、分层的镜像、UnionFS(联合文件系统)、docker镜像的加载原理、为什么docker镜像要采用这种分层结构呢、docker镜像commit
《docker基础篇:4.Docker镜像》包括是什么、分层的镜像、UnionFS(联合文件系统)、docker镜像的加载原理、为什么docker镜像要采用这种分层结构呢、docker镜像commit
254 70
实战~如何组织一个多容器项目docker-compose
本文介绍了如何使用Docker搭建Nginx、PHP和MySQL的环境。首先启动Nginx容器并查看IP地址,接着启动Alpine容器并安装curl测试连通性。通过`--link`方式或`docker-compose`配置文件实现服务间的通信。最后展示了Nginx配置文件和PHP代码示例,验证了各服务的正常运行。
113 3
实战~如何组织一个多容器项目docker-compose
Docker容器性能调优的关键技巧,涵盖CPU、内存、网络及磁盘I/O的优化策略,结合实战案例,旨在帮助读者有效提升Docker容器的性能与稳定性。
本文介绍了Docker容器性能调优的关键技巧,涵盖CPU、内存、网络及磁盘I/O的优化策略,结合实战案例,旨在帮助读者有效提升Docker容器的性能与稳定性。
323 7
云原生之旅:Docker容器化实战
本文将带你走进云原生的世界,深入理解Docker技术如何改变应用部署与运维。我们将通过实际案例,展示如何利用Docker简化开发流程,提升应用的可移植性和伸缩性。文章不仅介绍基础概念,还提供操作指南和最佳实践,帮助你快速上手Docker,开启云原生的第一步。
深入探索容器化技术——Docker 的实战应用
深入探索容器化技术——Docker 的实战应用
176 0
深入探索容器化技术——Docker的实战应用
深入探索容器化技术——Docker的实战应用
66 0
Docker 的实战应用与优化策略
Docker 的实战应用与优化策略
65 0
深入探索容器化技术——Docker 的实战应用
深入探索容器化技术——Docker 的实战应用
83 0