Docker镜像
Docker镜像
Docker镜像概述
1. 什么是 Docker 镜像?
一个 Docker 镜像 是一个轻量级、可执行的、独立的软件包,它包含了运行某个应用程序所需的一切:代码、运行时环境、系统工具、系统库和设置。
简单来说,镜像就是 一个容器的蓝图或模板。它本身是只读的。当你通过 docker run
命令启动一个镜像时,Docker 会基于这个只读的镜像创建一个可写的容器层,然后在这个隔离的进程中运行指定的应用程序。
一个生动的比喻:类和对象
- Docker 镜像 就像面向对象编程中的 “类”。它定义了结构、属性和行为。
- Docker 容器 就像这个类的一个 “实例化对象”。你可以创建多个基于同一个类的对象(运行多个基于同一个镜像的容器)。
2. 核心特性
a. 分层存储
这是 Docker 镜像最核心、最精妙的特性。镜像由一系列只读层叠加而成,每一层代表 Dockerfile 中的一条指令。
- Dockerfile 指令与层的对应关系:
FROM ubuntu:20.04
:添加一个基础镜像层。RUN apt-get update && apt-get install -y python3
:在当前镜像之上添加一个新层,包含安装的 Python3。COPY . /app
:添加一个包含你的源代码的层。CMD ["python3", "/app/main.py"]
:添加一个定义容器启动时运行命令的元数据层。
分层带来的巨大优势:
- 存储效率:如果多个镜像共享相同的基础层(例如,相同的
ubuntu:20.04
层),那么它们只需要在磁盘上存储一份。这极大地节省了空间。 - 快速构建:当你重新构建镜像时,Docker 会使用构建缓存。如果某条指令及其之前的层没有变化,Docker 会直接复用缓存中的层,而不是重新执行,这使得构建速度非常快。
- 可复用性:你可以基于一个已有的镜像添加新的层,来创建更 specialized 的镜像。
b. 内容寻址
现代 Docker 版本使用内容寻址存储。每一层都有一个基于其内容计算出来的唯一加密哈希值(ID)。如果层的内容发生变化,其哈希值也会改变。这保证了镜像内容的完整性和一致性。
c. 写时复制
这是容器能够快速启动的关键。当启动一个容器时,Docker 不会复制整个镜像文件,而是在只读的镜像层之上添加一个薄薄的可写容器层。
- 读取操作:容器需要读取文件时,直接从底下的只读镜像层读取。
- 写入操作:容器需要修改文件时,Docker 使用 写时复制 策略。它会将该文件从只读镜像层复制到可写容器层,然后所有修改都作用于这个副本。原始的镜像文件保持不变。
- 删除操作:当删除一个在只读层存在的文件时,Docker 会在可写层创建一个一种特殊的“白名单”文件来隐藏它。
3. 镜像的组成与来源
a. 基础镜像
通常是镜像栈的最底层。它通常是一个精简的操作系统(如 Alpine Linux、Ubuntu、CentOS)或一个运行时环境(如 node:16
, python:3.9-slim
)。使用 FROM
指令指定。
b. 中间层
在基础镜像之上,通过 Dockerfile 中的指令(如 RUN
, COPY
, ADD
)添加的层。
c. 镜像仓库
镜像存储在仓库中,类似于代码存储在 Git 仓库中。
- 公共仓库:最著名的是 Docker Hub。你可以从这里拉取官方镜像(如
nginx
,redis
)或社区发布的镜像。 - 私有仓库:企业可以使用 Docker Trusted Registry 或 Harbor 等搭建自己的私有仓库,用于存储内部镜像。
d. 镜像标签
标签用于标识同一个镜像的不同版本或变体。格式为 <仓库名>/<镜像名>:<标签>
。
- 例如:
nginx:1.21
,nginx:latest
,my-app:v1.2
。 - 如果不指定标签,默认使用
:latest
标签。
docker镜像相关操作
1、列出镜像列表
我们可以使用docker images来列出本地主机上的镜像
[root@hrz3 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 203ad09fc156 7 weeks ago 192MB
httpd latest 2416cb32cb59 2 months ago 117MB
REPOSITORY:表示镜像的仓库源
TAG:镜像的标签
IMAGE ID:镜像ID
CREATED:镜像创建时间
SIZE:镜像大小
2、搜索镜像
可以从Docker Hub网站来搜索镜像,Docker Hub网址为: https://hub.docker.com/。也可以使用 docker
search命令来搜索镜像。比如我们需要一个httpd的镜像。我们可以通过docker search
命令搜索 httpd来寻找适合我
们的镜像。
但国内无法使用 docker search
命令,核心原因是 Docker 默认的镜像仓库(Docker Hub)位于境外,国内网络访问存在限制。
3、获取镜像
当我们在本地主机上使用一个不存在的镜像时,Docker就会自动下载这个镜像。如果我们想预先下载这个镜像,我们可以使用
docker pull命令来下载它。而镜像可以通过Docker Hub官方获取,或者通过国内的阿里云、DaoCloud等厂商所提供的镜像仓库下
载。
[root@hrz3 ~]# docker pull centos:7
7: Pulling from library/centos
2d473b07cdd5: Pull complete
Digest: sha256:be65f488b7764ad3638f236b7b515b3678369a5124c47b8d32916d6487418ea4
Status: Downloaded newer image for centos:7
docker.io/library/centos:7
4、 使用tag命令添加镜像标签
为了方便在后续工作中使用特定镜像,可以使用docker tag命令来作为本地镜像任意添加新的标签。
例如:添加一个myhttpd:latest镜像标签。
[root@hrz3 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
httpd latest 2416cb32cb59 2 months ago 117MB
myhttpd latest 2416cb32cb59 2 months ago 117MB
之后就可以使用myhttpd:latest来表示这个镜像了,通过查看我们可以发现,myhttpd:latest镜像的
ID与httpd:latest是完全一致的,他们实际上指向了同一个镜像文件,只是别名不同而已。docker tag命
令添加的标签实际上起到了类似链接的作用。
5、 镜像历史
可以使用docker history查看镜像的构建历史信息,因为在使用docker时经常会自己构建一些我们所
需要的镜像,所以要会查看镜像的构建信息。
[root@hrz3 ~]# docker history httpd
IMAGE CREATED CREATED BY SIZE COMMENT
2416cb32cb59 2 months ago CMD ["httpd-foreground"] 0B buildkit.dockerfile.v0
......
<missing> 2 months ago # debian.sh --arch 'amd64' out/ 'trixie' '@1… 78.6MB debuerreotype 0.16
6、删除镜像
(1)删除镜像时,后面接镜像名称
可以使用docker rmi或者docker image rm将我们用不到的镜像删除,如果镜像被使用,那么无法删除镜像。删除
的镜像可以是镜像名称标签或者是镜像ID
[root@hrz3 ~]# docker rmi httpd
Untagged: httpd:latest
Untagged: httpd@sha256:997f544807c5221e33832c1213605f5a128cb6bdb5e581ccabb078e7c8426ee5
Untagged: httpd@sha256:ca375ab8ef2cb8bede6b1bb97a943cce7f0a304d5459c05235b47bc2dccb98cd
产看发现已删除
[root@hrz3 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 203ad09fc156 7 weeks ago 192MB
myhttpd latest 2416cb32cb59 2 months ago 117MB
centos 7 eeb6ee3f44bd 4 years ago 204MB
(2)删除镜像时,后面接镜像ID。如果该镜像没有被打标签,可直接删除。
[root@hrz3 ~]# docker rmi 2416cb32cb59
Untagged: httpd:latest
Untagged: httpd@sha256:ca375ab8ef2cb8bede6b1bb97a943cce7f0a304d5459c05235b47bc2dccb98cd
Deleted: sha256:2416cb32cb59e9ac3de2bf99ab60a1e2f889917bb8687af48e3781ae2af41776
.....
(3)如果该镜像被重新打了标签,是无法删除的,那么想一并删除该镜像和此镜像设置的标签后的镜像,可在后面跟-f选项,该选项是强制的意思。
[root@hrz3 ~]# docker rmi 2416cb32cb59
Error response from daemon: conflict: unable to delete 2416cb32cb59 (must be forced) - image is referenced in multiple repositories
[root@hrz3 ~]# docker rmi 2416cb32cb59 -f
Untagged: httpd:latest
Untagged: httpd@sha256:ca375ab8ef2cb8bede6b1bb97a943cce7f0a304d5459c05235b47bc2dccb98cd
Untagged: myhttpd:latest
Deleted: sha256:2416cb32cb59e9ac3de2bf99ab60a1e2f889917bb8687af48e3781ae2af41776
......
7、清理镜像
使用docker一段时间后,系统可能会遗留一些临时的镜像文件,以及一些没有被使用的镜像,可以通
过docker image prune命令来进行清理。支持的选项包括:-a,-all:删除所有无用的镜像,不仅仅是临时镜像;-f,-force:强制删除镜像,而不进行提示确认。
例如,如下命令会自动清理临时的遗留镜像文件层,最后会提示释放的存储空间:
[root@hrz3 ~]# docker image prune -f
Total reclaimed space: 0B
8、导出镜像
可以使用docker image save将一个镜像导出到一个压缩包中,便于在其他主机上运行
[root@hrz3 ~]# docker image save httpd > hrz-httpd.tar.gz
[root@hrz3 ~]# ll
-rw-r--r-- 1 root root 120175616 10月 8 19:47 hrz-httpd.tar.gz
9、导入镜像
可以使用docker image load导入我们需要的镜像压缩包(为了实验效果,首先我们把之前的httpd镜
像删除)。
[root@hrz3 ~]# docker image load -i hrz-httpd.tar.gz
1d46119d249f: Loading layer 81.04MB/81.04MB
7efe7270f90c: Loading layer 2.56kB/2.56kB
5f70bf18a086: Loading layer 1.024kB/1.024kB
d7664d7d8c3f: Loading layer 6.018MB/6.018MB
0e34cd3adc60: Loading layer 33.08MB/33.08MB
d454a00187b1: Loading layer 3.584kB/3.584kB
Loaded image: httpd:latest
[root@hrz3 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
httpd latest 2416cb32cb59 2 months ago 117MB
10、 使用 inspect 命令查看信息
使用 docker [image] inspect 命令可以获取该镜像的详细信息,包括制作者、适应架构、各层的数字摘要等
[root@hrz3 ~]# docker image inspect centos:7
[{"Id": "sha256:eeb6ee3f44bd0b5103bb561b4c16bcb82328cfe5809ab675bb17ab3a16c517c9","RepoTags": ["centos:7"],......"RootFS": {"Type": "layers","Layers": ["sha256:174f5685490326fc0a1c0f5570b8663732189b327007e47ff13d2ca59673db02"]},"Metadata": {"LastTagTime": "0001-01-01T00:00:00Z"}}
]
上面代码返回的是一个 JSON 格式的消息,如果我们只要其中一项内容时,可以使用-f 来指定
[root@hrz3 ~]# docker image inspect -f {{".Architecture"}} centos:7
amd64
[root@hrz3 ~]# docker image inspect -f {{".Os"}} centos:7
linux
[root@hrz3 ~]# docker image inspect -f {{".Size"}} centos:7
203936249
常用信息字段:
Architecture
- 系统架构Os
- 操作系统Size
- 镜像大小RepoTags
- 镜像标签Created
- 创建时间