「Docker 镜像多阶段构建」:让你的容器更小、更快、更安全!

欢迎关注我的公众号「DevOps和k8s全栈技术」,进公众号【服务】栏,可以看到技术群,点击即可加入学习交流群。↓↓↓

关注公众号,免费学技术,免被割哦~

在容器化应用的开发过程中,镜像体积越小,构建速度越快,部署效率也就越高。而 Docker 多阶段构建(Multi-Stage Build)是一种优化 Docker 镜像的利器,可以显著减少最终镜像的体积,同时保持构建过程的灵活性。本文将详细介绍多阶段构建的基本原理、优化技巧,并结合实战案例,帮助你打造更轻量、高效的 Docker 镜像。

1. 传统构建 vs. 多阶段构建

在没有使用多阶段构建之前,我们通常会在一个 Dockerfile 中完成所有的构建步骤,包括编译、打包、安装依赖等。这种方式的主要问题是:

1)冗余依赖:构建时的工具和库会被打包进最终镜像,导致体积庞大。

2)安全性低:多余的工具和开发环境增加了安全风险。

3)构建效率低:每次构建都会重新拉取和安装所有依赖。

多阶段构建的核心思想是:将构建过程拆分成多个阶段,只在最终阶段保留必要的文件,避免无关的构建工具、编译器等被打包进最终镜像,从而优化镜像体积,提高安全性和构建效率。


2. 多阶段构建的基本用法

示例:构建 Go 应用

假设我们有一个简单的 Go Web 应用(main.go):

package main
import (    "fmt"    "net/http")
func handler(w http.ResponseWriter, r *http.Request) {    fmt.Fprintf(w, "Hello, Docker Multi-Stage Build!")}
func main() {    http.HandleFunc("/", handler)    http.ListenAndServe(":8080", nil)}

如果直接编写 Dockerfile,可能会这样做:

FROM golang:1.21 AS builderWORKDIR /appCOPY . .RUN go build -o app
FROM alpine:latestWORKDIR /root/COPY --from=builder /app/app .CMD ["./app"]

解析:

  1. 第一阶段(builder):
  • 使用 golang:1.21 作为基础镜像,包含 Go 语言环境。

  • 复制源代码并编译,生成二进制文件 app

  • 第二阶段(alpine):
    • 仅使用 alpine:latest 作为运行环境,体积仅 5MB。

    • 从 builder 阶段拷贝编译好的二进制文件 app,避免携带 Go 开发环境。

    • 运行时只保留最小化的环境,提高安全性和效率。

    优化效果:如果使用 golang:1.21 直接构建,最终镜像大小可能超过 900MB;但采用多阶段构建后,最终镜像只有 10MB 左右!

    3. 深入优化 Docker 多阶段构建

    多阶段构建虽然能优化镜像大小,但仍有进一步优化的空间。

    1️⃣ 减少层数,优化缓存

    Docker 镜像的构建是分层的,每一条 RUNCOPYADD 指令都会创建新的层。为了提高构建效率,可以:

    1)合并 RUN 指令,减少层数,例如:

    RUN apt-get update && apt-get install -y \    curl \    git \    && rm -rf /var/lib/apt/lists/*

    2)合理利用缓存:尽量避免频繁变更 COPY 指令,以减少不必要的缓存失效。例如:

    COPY go.mod go.sum .  RUN go mod download  COPY . .  RUN go build -o app
    • 优化点:先复制 go.mod 和 go.sum 并执行 go mod download,可以利用 Docker 层缓存,加速构建。

    2️⃣ 使用更小的基础镜像

    基础镜像的选择直接影响最终镜像大小。建议:

    • 使用 Alpine:例如 

    alpine:latest 体积仅 5MB,比 ubuntu(约 29MB)更小。

    • 使用 Distroless:Google 提供的 

    distroless 镜像进一步精简,仅包含运行时环境。

    优化后的 Dockerfile 示例:

    FROM golang:1.21 AS builderWORKDIR /appCOPY . .RUN go build -o app
    FROM gcr.io/distroless/staticCOPY --from=builder /app/app /CMD ["/app"]

    最终镜像 甚至小于 5MB,比 Alpine 方案更精简!

    3️⃣ 避免 root 运行,提高安全性

    默认情况下,容器中的进程以 root 运行,存在安全风险。可以在 Dockerfile 中添加一个非 root 用户:

    RUN addgroup -S appgroup && adduser -S appuser -G appgroupUSER appuser

    这样,容器中的应用将以 appuser 运行,避免潜在的权限提升漏洞。

    4️⃣ 构建参数化,提升可维护性

    可以通过 ARG 传递变量,使 Dockerfile 更加通用,例如:

    ARG GO_VERSION=1.21FROM golang:${GO_VERSION} AS builder

    这样,可以在构建时指定 Go 版本:

    docker build --build-arg GO_VERSION=1.20 -t myapp .

    让 Dockerfile 更加灵活,可复用性更高。

    4. 总结

    ✅ 多阶段构建的核心优势

    1. 减小镜像体积:去除构建依赖,仅保留运行时环境。
    2. 提升构建效率:合理利用缓存,提高 CI/CD 速度。
    3. 增强安全性:减少无用软件,避免 root 运行,提高安全性。
    4. 提高可维护性:使用 ARG变量,让构建更灵活。

    通过 Docker 多阶段构建,我们可以在保持开发体验的同时,构建更加轻量、高效、安全的容器镜像。如果你还在为 Docker 镜像太大、构建慢、漏洞多而头疼,不妨试试多阶段构建,让你的容器更快、更安全、更高效!

    欢迎关注我的公众号「DevOps和k8s全栈技术」,进公众号【服务】栏,可以看到技术群,点击即可加入到学习交流群。↓↓↓

    END

    ➤  往期精彩回顾

    「Docker 镜像多阶段构建」:让你的容器更小、更快、更安全!_第1张图片

    • 云计算架构师韩先超亲身经历 | 记录从大学到现在工作经历

    • 我的2024年终总结:在坚持中成长,在选择中前行

    • 云计算架构师韩先超对咪咕进行【K8S超大规模集群与AI赋能算力网络调度】培训

    • 合肥电信进行线下Kubernetes技术培训

    • 推荐书籍:《Kubernetes从入门到DevOps企业应用实战》——韩老师以企业实战为背景出版的一本高质量书籍:销量突破1万

    • docker镜像加速器又又被封了:新整理一批可以用的|无需代理,国内可访问

    • 运维秘籍:20个常识,关键时刻能救命!

    • 深度解析 Kubernetes API Server 性能优化:关键参数配置指南|k8s调优指南

    • 提升运维效率:Linux和Kubernetes常见故障的20种解决方案

    • K8s Scheduler Pod 启动失败:Error: failed to reserve container name

    • Dockerfile超详细教程:案例+指令+编写技巧

    • 全面掌握:Linux运维面试必备题库(服务器、网络、Docker、K8s、DevOps等)

    • 大规模场景下K8S集群设计|大企业5000个节点k8s架构设计|第1集

    • 大规模K8S集群的网络与存储优化:5000+节点规模| 第2集

    • 高效运用 GPU:在 Kubernetes 集群中动态管理 GPU 资源

    • Centos停更了,基于业务场景选择合适的操作系统替代Centos。

    • docker镜像加速器又又被封了:新整理一批可以用的|无需代理,国内可访问

    • 生产故障排查记录:Redis 中间件疑难错误排查与修复

    • 运维秘籍:20个常识,关键时刻能救命!

    • Linux 运维命令汇总:含shell、sed、awk等

    • K3K:Kubernetes 套娃式集群管理,轻松运行多个 K3s

    • 如何零成本云端部署deepseek模型

    • 国产神器 !!! 解锁 Docker 运维新姿势

    • K8S 1.30环境中私有化部署 Ollama 和 DeepSeek-R1(671B模型)

    「Docker 镜像多阶段构建」:让你的容器更小、更快、更安全!_第2张图片

    欢迎关注我的公众号「DevOps和k8s全栈技术」,进公众号【服务】栏,可以看到技术群,点击即可加入到学习交流群。↓↓↓

你可能感兴趣的:(docker,安全,容器,运维)