docker

关注公众号 jb51net

关闭
首页 > 网站技巧 > 服务器 > 云和虚拟化 > docker > Docker镜像构建

Docker构建镜像的三大优化方法指南

作者:敲上瘾

这篇文章主要为大家详细介绍了Docker构建镜像的三大优化方法,包括CMD/ENTRYPOINT、多阶段构建与缓存优化,下面就跟随小编一起深入了解下吧

一、cmd与entrypoint

基本概念:

CMD指令: 指定容器启动时默认执行的命令。它不会在构建时执行,只是在镜像中记录了"当有人运行这个容器时,默认应该执行什么"。

ENTRYPOINT指令: 类似CMD默认执行一个指令,但它是将配置容器作为一个可执行程序来运行。它让容器表现得像一个独立的二进制文件。

特性:

共同特性:

区别:

指令的两种格式:

示例:

CMD nginx -g "daemon off"(shell模式)

执行:/bin/sh -c "nginx -g "daemon off"

CMD ["nginx","-g","daemon off"](exec模式)

执行:nginx -g "daemon off"

使用推荐:

使用exec模式编辑,CMDENTRYPOINT配合使用:entrypoint负责可执行程序,cmd负责参数传入。

覆盖测试

Dockerfile文件:

FROM busybox
CMD echo "hello world"
CMD echo "hello docker"

构建镜像:docker build -t cmd:v0.1 .

运行镜像:

CMD测试:

ENTRYPOINT测试:

可使用–entrypoint选项指定指令执行:

shell与exec

exec模式:

shell模式:

cmd与entrypoint组合

二、优雅构建镜像(过滤文件)

很多时候我们会将当前目录(构建上下文)中的所有文件拷贝给docker容器。但很多时候,我们的项目中包含一些不需要被打进镜像的文件,这些文件不仅会增加镜像大小,延长构建时间,还可能带来安全风险。这时候.dockerignore就该上场了。

什么是 .dockerignore

.dockerignore 文件是 Docker 构建过程中的一个重要工具,它的作用类似于 .gitignore,用于指定在构建 Docker 镜像时应该忽略哪些文件和目录,防止它们被复制到镜像中。

为什么要使用 .dockerignore

主要好处:

如何使用 .dockerignore

基本语法:

示例:

# * - 匹配任意数量字符(除了路径分隔符)
*.log          # 忽略所有 .log 文件
src/*.js       # 忽略 src 目录下的所有 .js 文件
#-------------------------------------------------------
# ? - 匹配单个字符
file?.txt      # 忽略 file1.txt, file2.txt 等
#-------------------------------------------------------
# ** - 匹配任意层级的目录
**/test        # 忽略所有 test 目录
src/**/*.js    # 忽略 src 下任意层级的 .js 文件
#-------------------------------------------------------
# ! 表示例外(不忽略)
!README.md 	#保留README.md 文件
*.md 			#忽略其他 .md 文件
#-------------------------------------------------------

文件位置:.dockerignore 应该放在 Dockerfile 同一目录下。

实战示例:

三、多阶段构建

Docker 多阶段构建允许你在一个 Dockerfile 中定义多个“构建阶段”(图中的 Stage1, Stage2, …),每个阶段都是一个独立的镜像构建过程,并且你可以有选择地将前一个阶段的产物复制到后一个阶段,最终只产出最后一个阶段的镜像。

这解决了传统单阶段构建模式(图中的“单阶段”)所带来的问题。

1.单阶段构建

2.手动拆分

3.多阶段构建

模式:用一个 Dockerfile 定义多个阶段,自动完成“按需构建和复制”。

如何工作

4.测试

测试文件:

#include <stdio.h>
int main()
{
		printf("hello docker");
		return 0;
}

单阶段构建:

FROM ubuntu:22.04

# 设置国内源(阿里云Ubuntu镜像)
RUN sed -i 's/archive.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list && \
    sed -i 's/security.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list

# 更新软件包列表并安装gcc
RUN apt-get update && \
    apt-get install -y gcc && \
    gcc -v

# 设置工作目录
WORKDIR /src

# 拷贝源文件
COPY demo.c .

# 编译源文件并清理
RUN gcc demo.c -o demo && \
    rm -f demo.c && \
    apt-get remove -y gcc && \
    apt-get autoremove -y && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

# 运行可执行文件
CMD ["/src/demo"]

多阶构建:

FROM ubuntu:22.04 as buildstage

# 设置国内源(阿里云Ubuntu镜像)
RUN sed -i 's/archive.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list && \
    sed -i 's/security.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list

# 更新软件包列表并安装gcc
RUN apt-get update && \
    apt-get install -y gcc && \
    gcc -v

# 设置工作目录
WORKDIR /src

# 拷贝源文件
COPY demo.c .

# 编译源文件并清理
RUN gcc demo.c -o demo && \
    rm -f demo.c && \
    apt-get remove -y gcc && \
    apt-get autoremove -y && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*
    
FROM busybox
COPY --from=buildstage /src/demo /src/
CMD ["/src/demo"]

四、合理使用缓存

Docker 层缓存原理

Docker 镜像由只读层组成,每一层对应 Dockerfile 里的一条指令(RUNCOPYADD 等)。构建时:从第一条指令开始,Docker 检查是否已有缓存层(基于指令字符串和文件内容);如果缓存存在,就复用该层,继续下一条;一旦某条指令的缓存没命中(指令内容变化,或 COPY/ADD 的文件内容变化),后续所有指令都会重新执行,不再使用缓存。

所以为了提高构建效率,通常会把变更频繁的指令或文件放在后面执行。示例:代码常常会被频繁修改,所以我们把它放在后面执行,把编译软件的安装放在前面就能提高二次构建的效率。

注意:两种方式初次构建的时间是一样的,主要影响的是二次构建。

测试方式:

以上就是Docker构建镜像的三大优化方法指南的详细内容,更多关于Docker镜像构建的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文