镜像管理
什么是 Docker 镜像
Docker 镜像是一个只读的 Docker 容器模板。Docker 镜像中含有容器启动所需要的的文件系统结构及其内容。
rootfs
在之前的介绍中,提及容器化技术与宿主机其实是共享一套操作系统的,那么 Docker 镜像作为一个未运行的容器,必然与操作系统中的静态部分有可被操作系通共用的部分。我们可以类似的理为一个接口下不同的实现方法,或者时 Bean 加载时使用的不同的配置文件。
roofts 是 Docker 容器启动时内部进程可见的文件系统。它由 Docker 镜像的文件系统以及一些运行 Docker 容器的配置文件组成。
传统 Linux 操作系统启动时,首先会挂在一个只读的 rootfs,当系统检测其完整性后,再将其切换为读写模式。
在 Docker 架构中,Docker deamon 挂载 rootfs 时,沿用了 Linux 内核的启动方法,将 rootfs 设置称为只读模式,在挂载完毕后,使用联合挂载技术,将只读的 rootfs 挂载在读写层下。
其中一个读写层下可以挂载多个 rootfs。只有在 Docker 容器运行过程中,文件系统发生变化时,才会把变化的文件内容写到可读写层,并隐藏只读层中的老版本。
Docker 的主要特点
分层
Docker 镜像是采用分层的方式构建的,每个镜像都由一个镜像层组成。分层的特性使得 Docker 变的更加轻量化。
当需要对 Docker 容器中的文件进行改动时,只会对上放的读写层进行改动,不复写下层已有的文件系统。即上层的文件的只读版本会被隐藏,不会被删除和替换,仍然得到保留。
当使用 Docker 提交自己的更改时,系统会形成一个新的镜像,该镜像只保留了上层被更新的文件系统。
分层的镜像其实是上层的镜像依赖于下层的镜像,有可能是多个上层对象共同依赖一个下层对象。即分层实现了不同镜像间共享镜像的效果。
写时复制
一个镜像往往有多个运行中的容器,所以着多个容器是共享一个镜像的,也就是说多个容器共享一份数据。
当其中有一个容器需要对文件系统中的文件进行改动时,如果直接修改共享的数据部分会对其他的容器也产生影响。Docker 在镜像层上覆盖了一个读写层,即一个可以读写的容器层。在容器需要对文件进行修改时,才会把文件写到读写层,并隐藏只读层中的老版本文件。
写时复制配合分层机制减少了镜像对磁盘的占用和容器启动时间。
内容寻址
Docker 在 1.10 版本后引入了内容寻址存储的机制,根据文件内容来索引镜像和镜像层。内容寻址存储根据文件内容来索引镜像和镜像层。
内容寻址存储会对镜像层的内容计算校验和,然后生成一个内容哈希值,并以此替代之前为新的镜像层生成随机的 UUID 作为镜像层唯一标识的行为。
基于内容哈希来索引镜像层,在一定程度上减少了 ID 的冲突,并增强了镜像层的共享。对于来自不同构件镜像层,只要拥有相同的内容哈希,也能被不同的镜像共享
联合挂载
联合挂载就是一个点可以挂载多个文件系统。即将挂载点的原目录与被挂载的内容进行整合,是的最终文件系统会包含整合之后的各层的文件和目录。实现这种联合挂在技术的文件系统通常被称为联合文件系统。
对于联合挂载的文件系统从不同镜像层的角度看类似于下图
但是从用户体验来看,是如同下图
当需要修改镜像内某个文件时,只对处于最上方的读写层进行变动,不覆写下层已有的文件系统,已有文件的在只读层的院士版本仍然存在。
Docker 容器的文件系统
Docker 容器的文件系统是一个相对独立的组织,Docker 容器的文件系统分为三个层,可读写部分 ()read-write layer 和 volumes)、init-layer、只读层 (read-only layer) 这三部分共同构成了一个容器所需要的的下层系统,他们通过联合挂在的方式,使其对外表现出一层
Docker 镜像相关概念
1. registry
registry 用以保存 Docker 镜像及其层次结构和关于镜像的元数据。可以说 registry 是专门用于保存镜像的仓库
Docker 官方的公用 registry 为 Docker Hub。Docker Hub 中分为用户仓库 (User registry) 和顶层仓库 (top-level registry)。用户仓库由普通的Docker Hub 用户创建,顶层仓库由 Docker 公司负责维护
2. repository
repository 是由具有某个功能的 Docker 镜像的所有迭代版本构成的镜像组。由上下文可知,registry 是由一系列经过命名的repository 组成。repository 通过命名规范对仓库内的镜像进行有效组织。
用户仓库采用 username/repository_name 的形式对镜像进行管理,顶层仓库则只会保留repository_name 部分。
3. manifest
manifest 是描述文件,是 registry 中 Docker 镜像的元数据文件,在 pull、push、save 和 load 中作为镜像结构和基础信息的描述文件。在镜像被 load 到 Docker 宿主机时,manifest 会被转化为本地镜像的配置文件。
manifest 列表指某个镜像标签支持的架构列表,其支持的每种架构都在自己的 manifest 中有过定义,其中列举该镜像的构成。
4. image 和 layer
image 用来存储一组镜像相关的元数据信息,包含架构、镜像默认配置信息,构件镜像的容器配置信息,所有镜像层信息的 rootfs。
layer 是 Docker 用来管理镜像层的中间概念,layer 主要存放了镜像层的 diff_id、size、cache_id 和 parent 等,实际文件内容由存储驱动管理
5. Docker file
Docker file 是在 docker build 命令构建自己的 Docker 镜像时需要使用到的定义文件。
镜像的操作
切换 Docker 镜像源
# 使用 vim 编辑 docker 的镜像源配置文件
vi /etc/docker/daemo.json
# 在 registry-mirrors 中添加
> 搜索镜像
搜索 Docker 仓库的镜像的命令格式为docker search [OPTIONS] TERM
-
TERM
: 需要搜索的词汇
OPTIONS
名称 | 默认值 | 描述 |
–filter , -f | 用于过滤输出 | |
–limit | 25 | 限制最大输出个数 |
–format | 使用特定格式打印结构 | |
–no-trunc | 不截断输出 |
示例
docker search ubuntu
> 拉取镜像
拉取Docker 镜像的格式如下docker [image] pull [OPTIONS] NAME[:TAG|@DIGEST]
-
NAME
: 镜像名称 -
:TAG
: 是镜像标签,往往用来表示版本信息,默认情况下标签为 :latest -
@DIGEST
: 这个是镜像的签名值,可以让我们能够准确的拉取到想要的镜像,该值是一个 SHA256 编码
OPTIONS
名称 | 默认值 | 描述 |
-a,–all_tags | true/false | 是否获取镜像仓库中所有镜像 |
–disable-content-trust | true/false | 取消镜像内容校验 |
–platform | docker 版本需要在1.32 以上,用于设置平台 | |
–quiet , -q | 不展示详细信息 |
示例
[root@localhost docker]# docker pull ubuntu:18.04
18.04: Pulling from library/ubuntu
f22ccc0b8772: Pull complete
3cf8fb62ba5f: Pull complete
e80c964ece6a: Pull complete
Digest: sha256:fd25e706f3dea2a5ff705dbc3353cf37f08307798f3e360a13e9385840f73fb3
Status: Downloaded newer image for ubuntu:18.04
docker.io/library/ubuntu:18.04
> 查看本地镜像
Docker 查看本地镜像的命令为docker images [OPTIONS] [REPOSITORY[:TAG]]
或docker image ls [OPTIONS] [REPOSITORY[:TAG]]
-
REPOSITORY
: 就是镜像组 -
:TAG
: 是镜像标签
OPTIONS
名称 | 默认值 | 描述 |
-a,–all | 展示所有格的镜像 | |
–digests | 展示镜像的签名值 | |
–filter , -f | 用于过滤输出 | |
–limit | 25 | 限制最大输出个数 |
–format | 使用特定格式打印结构 | |
–no-trunc | 不截断输出 | |
–quiet , -q | 不展示详细信息 |
示例
[root@localhost docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 18.04 2c047404e52d 2 months ago 63.3MB
# 只展示特定标签
[root@localhost docker]# docker images --format "{{.ID}}: {{.Repository}}"
2c047404e52d: ubuntu
> 查看镜像详细信息
查看 Docker 镜像的详细信息的命令为docker [image] inspect [OPTIONS] IMAGE [IMAGE...]
-
IMAGE
: 是镜像
OPTIONS
名称 | 默认值 | 描述 |
–format,-f | 使用特定格式打印结构 |
> 查看镜像历史
查看镜像历史的命令格式为docker [image] history [OPTIONS] IMAGE
OPTIONS
名称 | 默认值 | 描述 |
–format,-f | 使用特定格式打印结构 | |
–no-trunc | 不截断输出 | |
–quiet , -q | 不展示详细信息 | |
–human , -H | 以可读的方式打印日期和大小 |
> 添加镜像标签
添加镜像标签命令的格式为docker [image] tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
-
SOURCE_IMAGE[:TAG]
: 原先的镜像标签 -
TARGET_IMAGE[:TAG]
: 附加的镜像标签
> 删除镜像标签
删除镜像标签的命令格式为docker rmi [OPTIONS] IMAGE [IMAGE...]
或 docker image rm [OPTIONS] IMAGE [IMAGE...]
OPTIONS
名称 | 默认值 | 描述 |
–force , -f | 强制移除镜像 | |
–no-prune | 不清理位未带标签的父镜像 |
> 清理镜像
清理镜像的命令格式为docker image prune [OPTIONS]
OPTIONS
名称 | 默认值 | 描述 |
-a,–all | 移除所有未使用的镜像 | |
–filter | 添加过滤条件 | |
–force , -f | 强制清理,不给任何提示 |
> 存储镜像
存储镜像的功能为将镜像导出为本地文件其命令格式为docker [image] save [OPTIONS] IMAGE [IMAGE...]
名称 | 默认值 | 描述 |
–output , -o | 将镜像导出为文件,而不是使用 STDOUT |
> 载入镜像
将导出的tar文件再导入到本地镜像库,其命令格式为docker [image] load [OPTIONS]
名称 | 默认值 | 描述 |
–input , -i | 从 tar 文件中读取镜像,而不是从 STDIN | |
–quiet , -q | 不展示详细信息 |
> 上传镜像
上传镜像的命令格式为docker [image] push [OPTIONS] NAME[:TAG]
OPTIONS
名称 | 默认值 | 描述 |
-a,–all | 推送镜像组中的所有标签的镜像 | |
–disable-content-trust | 跳过镜像签名 | |
–quiet , -q | 不展示详细信息 |
> 基于容器创建对象
docker [container] commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
OPTIONS
名称 | 默认值 | 描述 |
–author , -a | 镜像的作者 | |
–change , -c | 提交时执行 Dockerfile 指令 | |
–message , -m | 提交信息 | |
–pause , -p | 提交时暂停容器运行 |
> 基于本地模板导入镜像
docker [image] import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]
OPTIONS
名称 | 默认值 | 描述 |
–change , -c | 使用 Dockerfile 创建镜像 | |
–message , -m | 设置导入镜像时的提交信息 | |
–platform | 平台设置 |
> 使用 Dockerfile 构件镜像
docker [image] build [OPTIONS] PATH | URL | -
OPTIONS
名称 | 默认值 | 描述 |
–add-host | 添加 host | |
–pull | 总是拉取最新镜像 | |
–no-cache | 构件镜像时不使用缓存 | |
–memory , -m | 内存限制 | |
–tag , -t | 为镜像设置标签 | |
–quiet , -q | 不输出构建时的信息,只打印构建成功后的 image_id |