继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Docker镜像瘦身:让部署更快更省心

摇曳的蔷薇
关注TA
已关注
手记 324
粉丝 54
获赞 169
简介

几个月之前,在执行一个关键部署时,我们遇到了一个意想不到的问题:部署过程耗时极长,令人头疼。罪魁祸首竟然是臃肿的 Docker 镜像。这不仅令人沮丧,还导致了我们无法承受的系统停机。

这段经历教会了我一个重要的教训:小小的改变也能带来巨大的不同。通过优化 Docker 镜像,我们成功地将部署时间缩短了一半,节约了存储成本,并提升了 CI/CD 管道的整体效率。今天,我将分享我们实现这一转变所使用的策略。

……

为什么要优化 Docker 镜像?

如果你曾经经历过构建速度慢、部署时间长或镜像仓库中充斥着体积过大的镜像,你不是唯一有这种经历的人。为什么减少镜像大小至关重要:

  1. 更快的构建: 您的开发周期变得更短,您可以专注于更重要的事情。
  2. 高效的存储: 更小的镜像节省了您Docker仓库和机器上的磁盘空间。
  3. 更快的部署: 通过网络部署更小的镜像更快。
  4. 增强的安全性: 组件较少意味着漏洞也较少。

...

或使用省略号(...)来表示暂停或段落间的过渡。

(翻译为:...)

我们让Docker镜像瘦身的那天

我记得我们在优化努力之后第一次使用 docker images 命令时的情景。看到优化前后的镜像大小,感觉就像健身几周后上秤称重一样,能感受到差异,很有成就感。

以下是我們遵循的确切步骤,以完成那次转变:

(注:这里的"exact steps"是专有名词或特定表述,建议保留英文原词,因此翻译为:"exact steps")

此处省略

优化 Docker 镜像的7个有效手段

1. 选择一个最小的基础图像

我们不再以 ubuntu:latest 或其他大型镜像为起点,而是改用 alpine。这改动将镜像大小从 800MB 减至不到 30MB。

例子

在Dockerfile中使用最新版本的alpine镜像:
FROM alpine:latest

切换到全屏 退出全屏

……

2. 使用多步构建。

在许多项目中,例如一个 React 应用程序,我们可能有一些构建依赖项(例如 Node.js 和 npm 这样的工具),这些依赖项仅在构建过程中需要,而在生产镜像中并不需要。通过采用多阶段构建,我们可以把构建环境和运行时环境区分开来,从而生成一个更小的容器镜像。

示例:

在此示例中,我们将为 React 应用程序使用多步构建。

    # 构建阶段
    FROM node:16 AS builder
    WORKDIR /app
    COPY package.json package-lock.json ./  # 将 package.json 和 package-lock.json 复制到工作目录下
    RUN npm install  # 运行 npm install 命令安装依赖
    COPY . .  # 将项目文件复制到工作目录下
    RUN npm run build  # 运行 npm run build 命令构建项目

    # 运行时阶段
    FROM nginx:alpine  # 从 nginx:alpine 镜像创建一个新的容器层
    COPY --from=builder /app/build /usr/share/nginx/html  # 将构建阶段生成的文件复制到 nginx 的静态文件目录
    CMD ["nginx", "-g", "daemon off;"]  # 启动 nginx 并设置不使用守护进程

全屏 退出全屏

在上面的 Dockerfile 中

  • 使用官方的node:16镜像版本来安装依赖,构建React应用,生成静态资源。

  • 我们用较小的 nginx:alpine 镜头来运行构建完成的 React 程序。

这种多阶段构建流程确保只有必要的构建工件(如构建目录)会被包含在最终的镜像中,从而使镜像的大小最小化并优化生产环境。

……

3. 删除不需要的文件

在调试时,我们经常会不小心将临时文件加入到构建过程中。通过添加一个 .dockerignore 文件,我们就能防止这些临时文件被意外打包到镜像中。这样就能确保这些临时文件不会意外地出现在最终的镜像中。

示例 .dockerignore 文件:

# 以下文件不需要版本控制
node_modules # 忽略的文件模式
*.log # 忽略的文件模式
.git # 忽略的文件模式

全屏 退出全屏

省略了内容

4. 合并及减少图层

每个 Dockerfile 中的指令(例如 RUNCOPYADD)都会在 Docker 镜像中创建一个新的层。过多的层可能会使你的镜像变得臃肿。通过将多个指令合并到一个 RUN 指令中,你就可以减少层数,从而优化镜像。

示例:

而不是写:

RUN apt-get update  # 更新软件包列表  
RUN apt-get install -y curl vim  # 安装curl和vim  
RUN apt-get clean  # 清理不必要的下载包  
RUN rm -rf /var/lib/apt/lists/*  # 清除缓存的软件包列表

进入全屏,退出全屏

把它们合并成一个试试看:

RUN # 更新软件包列表并安装curl和vim,然后清理缓存
    apt-get update && apt-get install -y curl vim \
    && apt-get clean && rm -rf /var/lib/apt/lists/*

全屏显示 关闭全屏

这种方法尽可能地减少了层数,并确保临时文件,如缓存,在同层移除,这样就让镜像更小、更干净。

……此处省略……

5、避免安装不必要的依赖

最初,我们的Docker镜像包含了一些额外的库“以防万一。”随着时间的推移,我们发现这导致了镜像过大并增加了安全风险。我们发现,通过只指定运行时依赖项,从而保持了镜像的精简和安全性,这使镜像更符合实际需要。

例如,我们没有为每个项目中的安装大量的库文件,而是专注于最少的依赖并避免使用没必要的包。

此处省略

6. 使用 docker-slim 命令。

对我们流程来说,docker-slim 是一个改变游戏规则的工具。这款工具会自动分析你的镜像,并通过移除不必要的部分,如未使用的文件、二进制文件和库等,来减小其大小,确保功能不受影响。

我们使用docker-slim将图像大小最多减少了80%,使其成为我们优化策略中不可或缺的工具。

指令以缩小图像:

    docker-slim build <image-name> (请替换为实际的镜像名称)
``` 使用docker-slim构建镜像。

全屏切换(进入), 全屏切换(退出)

* * *

### 7. 定期检查并清理镜像

Docker 镜像会随时间积累,未使用的镜像或层会占用宝贵的磁盘空间,这可以清理。定期进行清理未使用的镜像有助于保持环境整洁。

你可以通过运行下面的命令来移除不需要的图像和图层:

**删除未使用镜像的命令:**

运行这条命令 docker system prune -f 可以强制清理所有未使用的 Docker 数据。


全屏模式 退出全屏

**清理所有未使用的图片的命令:**

可以运行以下命令来删除所有未使用的Docker镜像(强制执行):
docker image prune -a -f



进入全屏模式,退出全屏

把定期剪枝纳入你的工作流程,你可以让 Docker 环境保持简洁高效。

* * *

## 如何衡量成功

在实施这些优化之后,我们使用`docker images`命令来比较大小。结果令人惊讶。

* **之前大约是:** 1.2GB。
* **之后大约是:** 250MB。

不仅我们的部署变快了,云存储成本也大幅减少了。

* * *

## 结尾

优化 Docker 镜像可能看起来像是一个小任务,但这能给你的工作流程带来巨大的好处。无论是你是一个单打独斗的开发者,还是一个大型团队的一员,这些策略都能真正产生影响。

所以,还等什么呢?跳进你的 `Dockerfile` 里,开始优化工作,享受更精简、更快的部署带来的好处,享受更精简、更快部署的好处,享受更精简、更快的部署带来的好处。 

(注意:为了避免重复,最终翻译为:)
所以,还等什么呢?跳进你的 `Dockerfile` 里,开始优化工作,享受更精简、更快的部署带来的好处,

* * *

## 参考资料:

1. [Docker 官方文档页面](https://docs.docker.com)
2. [Dockerfile 编写的最佳实践](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/)
打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP