该笔记将记录:什么是镜像,以及镜像的管理,镜像的创建,存储,修改,共享等方面的内容;
分层文件系统
容器镜像基于分层文件系统的概念,其中每个层都包含应用程序的一部分或一个组件。
镜像(image)由多个文件系统叠加而成:
在 Docker 中,将这些文件系统称为镜像;
一个镜像可以放到另一个镜像的顶部。位于下面的镜像成为父镜像,最底层的镜像称之为基础镜像。当从镜像中启动容器时,Docker 会在镜像的最顶层加载一个读写文件系统,我们运行的程序都是在这个读写文件系统中执行的;
在 Docker 中,使用到了一种写时复制机制。在初始化时,读写层是空的。当文件系统发生修改时,所有的变化都存在与该读写层中。比如修改一个文件,该文件会被从只读层复制到读写层,在读写层进行修改。但是该文件的只读版本依旧存在,但是它被读写层中的该文件隐藏,正是因为使用了联合挂载技术。上面的这些层共同构成了镜像。
镜像名称
docker pull | Docker Documentation
Where can I find the sha256 code of a docker image? – Stack Overflow
[registry-hostname/][username/]repository-name[:tag][@digest]
registry-hostname/ | 主机名,可选
- 作用:指定镜像所在的 Docker Registry 地址,默认是 docker.io(即 Docker Hub)。
username/ | 用户名或组织名,可选
- 在 Docker Hub 或其他 Registry 中,表示镜像所属的用户或组织。如果省略,Docker 会使用 library/(官方镜像)。
repository-name | 仓库名称,必选
- 镜像的基本名称,通常代表软件或应用名称。
tag | 标签,可选
- 标识镜像的版本,默认是 latest。
- 最大长度:未知
- 允许字符:
digest | 摘要 | DIGEST
- 作用:基于镜像内容的唯一哈希值(SHA256),比 tag 更精确,确保拉取的是特定构建。digest 是镜像的唯一身份,不会被修改(而 tag 会被修改),通过 digest 能够获取确定版本的镜像;
- 但是,当 docker tag 后,不同仓库地址的 Digest 不同;
常见问题
关于父镜像与父镜像层
Is docker inspect -f ‘{{.Parent}}’ a safe way to get the base image ID?
命令 docker image inspect b7b28af77ffe --format '{{.Parent}}‘ 输出确实是父镜像,但是这个“父镜像”是“父镜像层”,而非 Dockerfile 中 FROM 引用的镜像层(除非 Dockerfile 中只有一个 FROM 指令);
待办事项
WIP ! Docker 是如何存储镜像的,以及镜像的大小
About images, containers, and storage drivers
Docker Image Size – Does It Matter?
moby/daemon/graphdriver/driver.go
Where are Docker images stored on the host machine?
镜像信息 | docker image inspect …
Changing the IMAGE ID of a docker image?
DeepSeek / 解释 docker image inspect 输出中,各个参数的含义
[ { "Id": "sha256:09508d094ad5c8eec96b8aeba128d4d86c55c741fbe189e5873befdd665eb159", "RepoTags": [ "dreamacro/clash:v1.18.0" ], "RepoDigests": [ "dreamacro/clash@sha256:8d10815afb37cc49d262f64e82d9346b15ea889b2ba7fd566c1369a2630b807c" ], "Parent": "", "Comment": "buildkit.dockerfile.v0", "Created": "2023-08-17T14:47:27.620903309Z", "DockerVersion": "", "Author": "", "Config": { "Hostname": "", "Domainname": "", "User": "", "AttachStdin": false, "AttachStdout": false, "AttachStderr": false, "Tty": false, "OpenStdin": false, "StdinOnce": false, "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ], "Cmd": null, "Image": "", "Volumes": null, "WorkingDir": "", "Entrypoint": [ "/clash" ], "OnBuild": null, "Labels": { "org.opencontainers.image.source": "https://github.com/Dreamacro/clash" } }, "Architecture": "amd64", "Os": "linux", "Size": 24589149, "GraphDriver": { "Data": { "LowerDir": "/var/lib/docker/overlay2/c42c25da8cf3ce31954eddf4163c00302deefe79027ecb86e2fc8e0ea065a207/diff:/var/lib/docker/overlay2/9915f00caf7f29a60b1863ce8b66a2f1a1a77900c29db181bad23ec5cf24edeb/diff:/var/lib/docker/overlay2/0b0be3b5e72d5e032e9b6228afa866efa45b6ed3c77e64ccc343ff96630d4509/diff:/var/lib/docker/overlay2/0e5f4984de2fe946debcb160ae94c67881a1b6dcb21a930daf5cb774a57cdbb9/diff", "MergedDir": "/var/lib/docker/overlay2/64095f9eea7b63c2d5da891cd3ac19e8ca371a48d72b8629f8909e46874d1f61/merged", "UpperDir": "/var/lib/docker/overlay2/64095f9eea7b63c2d5da891cd3ac19e8ca371a48d72b8629f8909e46874d1f61/diff", "WorkDir": "/var/lib/docker/overlay2/64095f9eea7b63c2d5da891cd3ac19e8ca371a48d72b8629f8909e46874d1f61/work" }, "Name": "overlay2" }, "RootFS": { "Type": "layers", "Layers": [ "sha256:4693057ce2364720d39e57e85a5b8e0bd9ac3573716237736d6470ec5b7b7230", "sha256:c11d3c6d457e9d188582ed01ec27ba02aea5bd476727bafd1e9a04a6bf00dcb6", "sha256:c7df344fa7e00b73d82f3cf8a3e147ed4d417c96d5a469abadb0f64856f8ddfb", "sha256:391f1b610f5899799dcf2804d2d67f70be8a69d536ff06c70f10b72b3cf12ffd", "sha256:8594e1b784e95f6cffae70fc430bc7a15f32b56488e9f78e0ce6a368cc60c066" ] }, "Metadata": { "LastTagTime": "0001-01-01T00:00:00Z" } } ]
The image id is calculated from the content of the image, you can’t customize it.
基本信息
- Id: 镜像的唯一标识符(SHA256哈希值)。Id 是一个关键字段,表示 Docker 镜像的唯一标识符。
- 它基于镜像的配置和文件系统内容计算得出,确保不同内容的镜像具有不同的 ID。
- 修改镜像的任意文件或配置(如 ENV、CMD)都会生成新的 Id。我们通常使用 ID 来唯一标识一个镜像。Id 与镜像的文件系统层(Layers)关联(见 RootFS.Layers 字段),用于存储和复用镜像层。
- RepoTags: 镜像的仓库标签列表(如 [“nginx:latest”, “myrepo/nginx:v1”])
- RepoDigests: 镜像的摘要列表(如 [“nginx@sha256:…”])
构建信息
- Parent: 父镜像的ID(如果是基于其他镜像构建的)
- Comment: 构建镜像时添加的注释
- Created: 镜像创建时间(ISO 8601格式)
- Container: 构建此镜像的容器ID
- DockerVersion: 构建此镜像时使用的Docker版本
- Author: 镜像作者
配置信息
- ContainerConfig: 构建容器时的配置(等同于 docker run 时的参数):Hostname, Domainname, User, Env, Cmd, Image, Volumes, WorkingDir, Entrypoint, Labels 等
- Config: 镜像的运行时配置(会覆盖ContainerConfig中的设置)
系统信息
- Architecture: 目标架构(如 amd64, arm64 等)
- Os: 操作系统(如 linux, windows)
- Size: 镜像的磁盘大小(字节)
- VirtualSize: 包含所有层的总大小(字节)
存储驱动信息
- GraphDriver: 使用的存储驱动信息。Name: 驱动名称(如 overlay2);Data: 驱动特定数据(如 lowerdir, upperdir, mergeddir 等)
文件系统信息
- RootFS: 根文件系统信息。Type: 通常是 layers;Layers: 组成镜像的各层ID列表(SHA256哈希值);
元数据
- Metadata: 镜像的元数据。LastTagTime: 最后一次打标签的时间(ISO 8601格式)