Docker镜像管理
介绍
Docker镜像管理涉及Docker镜像的创建、管理和分发。Docker镜像是Docker容器的构建基石,Docker容器是轻量级、可移植的虚拟化环境,可以在任何地方运行。Docker镜像采用分层架构进行构建和管理。Docker镜像中的每一层都代表对前一层的一组特定更改或添加。
Docker 镜像存档
Docker 提供了两种不同的方法来保存和加载 Docker 镜像:
- docker 保存/docker 加载
- docker export/docker import
👉docker save用于docker load保存和加载整个 Docker 镜像及其所有层和元数据。
👉docker export用于docker import将容器导出和导入为 tar 文件。Docker export 和 docker import 命令不包含元数据或有关镜像层的信息。
简短的实践
保存/读取
创建一个空目录
mkdir /image_backup
检查当前图像细节
docker images;
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 904b8cb13b93 4 days ago 142MB
ubuntu bionic b89fba62bc15 4 days ago 63.1MB
mysql latest 4f06b49211c0 10 days ago 530MB
mysql 5.7 be16cf2d832a 4 weeks ago 455MB
保存特定图像的备份
docker save -o /image_backup/ubuntu.tar ubuntu:bionic
所以现在如果我们删除图像
docker rmi ubuntu:bionic
# Checking for the image
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 904b8cb13b93 4 days ago 142MB
mysql latest 4f06b49211c0 10 days ago 530MB
mysql 5.7 be16cf2d832a 4 weeks ago 455MB
我们可以ubuntu:bionic从备份目录加载镜像。
docker load -i /image_backup/ubuntu.tar
检查结果
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 904b8cb13b93 4 days ago 142MB
ubuntu bionic b89fba62bc15 4 days ago 63.1MB
mysql latest 4f06b49211c0 10 days ago 530MB
mysql 5.7 be16cf2d832a 4 weeks ago 455MB
出口/进口
使用 Ubuntu 镜像创建一个新容器
docker run -d --name image_con ubuntu:bionic
正在导出此容器
docker export image_con -o /image_backup/image_con.tar
ls -l /image_backup/
total 127984
-rw------- 1 root root 65521664 Mar 6 09:34 image_con.tar
-rw------- 1 root root 65529856 Mar 6 09:30 ubuntu.tar
现在我们可以使用不同的标签导入这张图片。
docker import /image_backup/image_con.tar myubuntu:v1
检查结果
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myubuntu v1 3e3a5217f941 3 seconds ago 63.1MB
nginx latest 904b8cb13b93 4 days ago 142MB
ubuntu bionic b89fba62bc15 4 days ago 63.1MB
Docker 镜像提交和构建
docker commit和docker build都是用于创建 Docker 镜像的 Docker 命令。
docker commit该命令用于从现有容器创建新的 Docker 镜像。当您对正在运行的容器进行了更改,并希望将这些更改保存为新镜像时,此命令非常有用。
docker build该命令用于根据 Dockerfile 创建新的 Docker 镜像。Dockerfile 是一个脚本,其中包含有关如何构建 Docker 镜像的指令。
一些常用的 Dockerfile 指令:
- 来自:此指令用于指定新镜像将构建在其上的基础镜像。
- 标签:此指令用于向图像添加元数据。
- 运行:此指令用于在容器内执行命令。
- 添加:此指令用于将文件从主机系统复制到容器中。
- WORKDIR:此指令用于设置 Dockerfile 中后续命令的工作目录。
- EXPOSE:此指令用于指定容器在运行时将监听的端口。
- CMD:此指令用于指定容器启动时要执行的默认命令
- 入口点:此指令用于指定容器启动时要执行的命令,并且在容器运行时无法覆盖此命令。
简短的实践
Docker 提交
要检查 Ubuntu 镜像中有多少层。
docker inspect ubuntu:bionic
"Layers": [
"sha256:52c5ca3e9f3bf4c13613fb3269982734b189e1e09563b65b670fc8be0e223e03"
]
-it使用以下选项创建容器
docker run -it --name commit_con ubuntu:bionic
从容器内部,
cat > TestFile
TestFile
ls
TestFile boot etc lib media opt root sbin sys usr
bin dev home lib64 mnt proc run srv tmp var
现在从主机上
docker commit -a "MyName" -m "Image Comment" commit_con myubuntu:v1.0.0
我们可以使用以下命令确认此提交:
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myubuntu v1.0.0 2e214faf96f7 32 seconds ago 63.1MB
正在检查我们的 v1.0.0 Ubuntu 镜像
"Layers": [
"sha256:52c5ca3e9f3bf4c13613fb3269982734b189e1e09563b65b670fc8be0e223e03",
"sha256:cea6ad35f448cdba9f2bb5c32b245c497e90cafa36c8f856706c8257bb666e34"
]
👉 我们可以看到,当我们提交对 Ubuntu 容器的更改时,创建了一个带有额外层的新镜像。
Docker 构建
为我们的 Dockerfile 创建一个空目录
mkdir /DockerFile_root
cd /DockerFile_root
创建一个空的 Dockerfile
vi Dockerfile # Using this default name is more efficient
在此文件中添加以下内容
FROM ubuntu:bionic
LABEL maintainer "Author <Author@localhost.com>" # (Key : Value) Format
RUN apt-get update && apt-get install apache2 -y
ADD index.html /var/www/html
WORKDIR /var/www/html # works just like 'cd'
RUN ["/bin/bash", "-c", "echo RunTest > Test.html"]
EXPOSE 80
CMD ["apachectl", "-DFOREGROUND"] # Either have to use 'CMD' or 'ENTRYPOINT' to run the service
创建一个index.html
echo Test > index.html
我们当前的工作目录/DockerFile_root也称为构建上下文目录。
这里应该进行 Docker 构建。
docker build -t my:v1.0.0 ./
Successfully built e5581d044d20
Successfully tagged my:v1.0.0
检查我们的新图像
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
my v1.0.0 e5581d044d20 28 seconds ago 204MB
创建并启动容器
docker run -d --name apache2_con -p 80:80 my:v1.0.0
891473bcd83ed3f94830e5595aa698f3e40652183183a205bc3aa60fe8eef843
如果我们检查容器内部。
docker exec -it apache2_con /bin/bash
root@891473bcd83e:/var/www/html# cat ./Test.html
RunTest
返回主机系统并检查端口 80
curl localhost:80
Test
curl localhost:80/Test.html
RunTest
Docker 构建缓存和镜像大小
最后,我想讨论一下 Docker 构建大小以及如何管理它们。
创建一个新的 Dockerfile
vi Dockerfile_L
FROM ubuntu:bionic
LABEL maintainer "Author <Author@localhost.com>"
RUN mkdir /dummy
RUN fallocate -l 100m /dummy/A
RUN rm -rf /dummy/A
为了构建这个图像
docker build -t dummy:v1.0.0 ./ -f Dockerfile_L
👉 -fdocker build 命令中的选项指定在构建过程中要使用的 Dockerfile 名称,当 Dockerfile 不名为“Dockerfile”时使用。
这将按如下方式构建映像
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
dummy v1.0.0 4ef94c4001fe 2 minutes ago 168MB
👉 我们可以看到它占用了 168MB 的空间。我们知道 ubuntu:bionic 系统只有大约 63MB。在 Dockerfile 中,我们创建了一个虚拟目录,并删除了目录中的一个文件,结果却占用了超过 100MB 的空间。
为了减小 Dockerfile 的大小,我们可以尝试编辑它。
FROM ubuntu:bionic
LABEL maintainer "Author <Author@localhost.com>"
RUN mkdir /dummy && \
fallocate -l 100m /dummy/A && \
rm -rf /dummy/A
现在,如果我们检查构建这个新图像后的图像大小。
docker build -t dummy:v1.0.1 ./ -f Dockerfile_L
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
dummy v1.0.1 6ced40e23a77 11 seconds ago 63.1MB
dummy v1.0.0 4ef94c4001fe 8 minutes ago 168MB
✨ 另一件重要的事情是Docker 缓存
💡 Docker 会缓存构建层以加快后续 Dockerfile 的构建速度。但是,当使用 GitHub 进行构建时,由于缓存层的存在,源代码的更改可能无法正确反映。要强制重新构建所有层并确保更改正确合并,请
--no-cache在 docker build 命令中使用相应的选项。
C我们也可以尝试编译一段代码。
vi ./app.c
#include <stdio.h>
void main()
{
printf("Hello World\n");
}
要编译我们的C代码,我们需要gcc编译器。
vi Dockerfile_M
FROM gcc:latest
LABEL maintainer "Author <Author@localhost.com>"
ADD app.c /root
WORKDIR /root
RUN gcc -o ./app ./app.c
CMD ["./app"]
现在正在构建这个 Dockerfile
docker build -t multi:v1.0.0 ./ -f Dockerfile_M
👉 这将首先从 Docker Hub 网站拉取 gcc:latest 镜像。
如果我们检查图像尺寸
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
multi v1.0.0 8b00f89eb22c 23 seconds ago 1.27GB
gcc latest c6aa7ca27d67 4 days ago 1.27GB
通过在容器中运行来测试镜像。
docker run -it --rm --name pritn_c multi:v1.0.0
Hello World
虽然这个方法可行,但是图片尺寸对于这么简单的任务来说也太大了😥
为了解决这个问题,我们可以按如下方式编辑 Dockerfile。
# GCC Compile Block
FROM gcc:latest as compile_base
LABEL maintainer "Author <Author@localhost.com>"
ADD app.c /root
WORKDIR /root
RUN gcc –o ./app ./app.c
# APP Running Block
FROM alpine:latest
RUN apk add --no-cache gcompat
WORKDIR /root
COPY --from=compile_base /root/app ./ # we set an alias in the compile block as "compile_base" which is being used here
CMD ["./app"]
这称为多阶段构建。Docker 中的多阶段构建允许您在单个 Dockerfile 中使用多个 FROM 语句来创建多个中间镜像,每个镜像都有自己的一组指令和层。
✨ 使用多阶段构建的优势在于,它可以创建更小、更高效的 Docker 镜像。
现在我们将构建这个图像
docker build -t multi:v1.0.1 ./ -f Dockerfile_M
检查此图像尺寸
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
multi v1.0.1 1cc2b8149d7d 6 seconds ago 7.23MB
通过在容器中运行来测试镜像。
docker run -it --rm --name print_c multi:v1.0.1
Hello World
我们甚至可以通过拆分软件包安装块来进一步减小图像大小。
vi Dockerfile_M2
# GCC Compile Block
FROM gcc:latest as compile_base
LABEL maintainer "Author <Author@localhost.com>"
ADD app.c /root
WORKDIR /root
RUN gcc –o ./app ./app.c
# Package Install Block
FROM alpine:latest as package_install
RUN apk add --no-cache gcompat
WORKDIR /root
COPY --from=compile_base /root/app ./
# App running Block
FROM package_install as run
WORKDIR /root
CMD ["./app"]
构建图像
docker build -t multi:v1.0.2 ./ -f Dockerfile_M2
检查尺寸
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
multi v1.0.2 60500955b71d 4 seconds ago 7.23MB
通过在容器中运行来测试镜像。
docker run -it --rm --name print_c multi:v1.0.2
Hello World
💡 在上述例子中,由于实际编译后的文件与实际程序相比非常小,因此无法看出大小差异。
结论
总之,管理 Docker 镜像对于使用 Docker 容器至关重要。通过理解我上面讨论的各种 Docker 镜像管理命令和最佳实践,用户可以有效地管理 Docker 镜像,从而优化容器环境和工作流程 ✔
文章来源:https://dev.to/waji97/docker-image-management-3558







