1. 為什麼減少 Docker 鏡像大小很重要
  2. 從最小基礎鏡像開始
  3. 多階段構建
  4. 避免安裝不必要的依賴
  5. 使用 .dockerignore 排除不必要的檔案
  6. 優化 Dockerfile 中的層
  7. 安裝包後清理
  8. 使用更小的語言執行環境
  9. 壓縮鏡像層
  10. 移除除錯資訊
  11. 定期審計您的鏡像
  12. 進階技巧
  13. 結論

DevOps 世界中,優化 Docker 鏡像 對於高效的應用程序部署和編排至關重要。減少 Docker 鏡像的大小可以提高速度、降低存儲成本,並簡化 CI/CD 流程。本綜合指南將引導您了解減少 Docker 鏡像大小的最佳實踐,以及幫助您創建精簡、高效的鏡像的提示和策略。

為什麼減少 Docker 鏡像大小很重要

  • 更快的構建:較小的鏡像導致更快的構建時間和更快的部署。
  • 降低帶寬和存儲成本:大型鏡像在網絡中傳輸的時間更長,並且需要更多存儲,這可能變得很昂貴。
  • 更快的容器啟動時間:較小的鏡像可以加速容器啟動,這在需要快速擴展的動態環境中至關重要。
  • 提高安全性:減少鏡像大小通過限制不必要的軟體和依賴,從而最小化攻擊面。

1. 從最小基礎鏡像開始

基礎鏡像作為您 Docker 鏡像的基礎。選擇輕量級的基礎鏡像可以顯著減少您的鏡像總大小。考慮以下基礎鏡像:

  • Alpine Linux:作為最受歡迎的輕量 Docker 鏡像之一,Alpine Linux 的大小約為 5MB,而 Ubuntu 的大小為 200MB。它設計為簡單和安全,但請注意,使用 Alpine 可能需要為編譯某些依賴進行額外的工作。

    範例

    FROM alpine:3.18
  • Distroless:谷歌的 Distroless 鏡像是另一個優秀的輕量容器選擇。這些鏡像不包含操作系統的命令行外殼,專為安全運行應用程序而設計。

    範例

    FROM gcr.io/distroless/base

2. 多階段構建

多階段構建允許您在 Dockerfile 中使用多個 FROM 指令,將構建過程有效地分解為階段。這對於編譯代碼並僅將最終產物複製到生產鏡像中尤為有用,從而留下不必要的依賴。

多階段構建範例

# 階段 1:構建
FROM golang:1.19 AS builder
WORKDIR /app
COPY . .
RUN go build -o main .

# 階段 2:生產
FROM alpine:3.18
WORKDIR /app
COPY --from=builder /app/main /app/
CMD ["./main"]

在此範例中,構建依賴(例如 Golang 和源代碼)僅存在於第一階段。最終鏡像僅包含編譯後的二進制文件和一個最小的 Alpine 基礎,從而產生更小的鏡像。

3. 避免安裝不必要的依賴

在安裝包或庫時,只包括應用程序運行所需的內容。在最終鏡像中避免安裝開發依賴。在使用基於 Debian 的鏡像中的 apt-get 時,可以使用 --no-install-recommends 來避免額外包的安裝。

範例

RUN apt-get update && apt-get install --no-install-recommends -y \
    curl \
    ca-certificates \
    && rm -rf /var/lib/apt/lists/*

此方法可以防止安裝推薦但不必要的包,從而減少鏡像大小。

4. 使用 .dockerignore 排除不必要的檔案

類似於 .gitignore.dockerignore 文件幫助排除 Docker 構建上下文中不必要的檔案和目錄,防止它們被複製到您的鏡像中。

範例 .dockerignore 文件

node_modules
.git
.env
tmp/
logs/

通過排除這些檔案,您可以顯著減少鏡像的大小並加快構建過程。

5. 優化 Dockerfile 中的層

Dockerfile 中的每一行都會在最終鏡像中創建一個新層。為了最小化鏡像大小,當可能時,將多個命令組合為單一的 RUN 指令。這有助於避免在中間層中累積未使用的檔案。

優化前範例

RUN apt-get update
RUN apt-get install -y python3
RUN apt-get clean

優化後範例

RUN apt-get update && apt-get install -y python3 && apt-get clean

通過組合這些命令,您減少了層的數量並消除了本來會被緩存的臨時檔案。

6. 安裝包後清理

在鏡像構建過程中,經常會創建諸如快取或日誌等臨時檔案,這會增加鏡像的大小。在安裝軟體後,始終清理包管理器快取和其他臨時檔案。

對於基於 Debian 的鏡像

RUN apt-get update && apt-get install -y python3 && apt-get clean && rm -rf /var/lib/apt/lists/*

對於基於 Alpine 的鏡像

RUN apk add --no-cache python3

使用 --no-cacheapk 一起確保不會創建臨時快取檔案,保持鏡像大小最小。

7. 使用更小的語言執行環境

如果您的應用程序是用 Python、Node.js 或 Java 等語言編寫的,考慮使用更小的執行環境鏡像。許多語言提供其運行環境的 "slim" 或 "alpine" 版本。

範例

# 而不是使用這個:
FROM python:3.11

# 使用瘦身版本:
FROM python:3.11-slim

這些瘦身版本移除了不必要的組件,同時仍提供語言執行環境的核心功能。

8. 壓縮鏡像層

Docker 在構建過程中自動壓縮鏡像層。然而,您可以通過手動使用壓縮工具進一步優化這一點。例如,在安裝包或二進制文件時,可以利用 gziptar 等壓縮工具,在將它們複製到最終鏡像之前減少它們的大小。

9. 移除除錯資訊

如果您的應用程序包含除錯符號或元數據,通常在生產環境中是多餘的。移除這些數據可以節省空間。

範例

RUN strip /path/to/binary

10. 定期審計您的鏡像

隨著時間的推移,您的鏡像可能因過時的依賴或未使用的軟體而膨脹。使用像 docker image lsdocker image prune 的工具定期審計和清理舊鏡像。

您還可以使用 Docker 的內建 --squash 標誌將所有層合併為一個層,以減少大小,儘管這目前是實驗性的。

清理未使用的鏡像

docker image prune -f

進階技巧

11. 使用 Docker 鏡像掃描

像 Docker Scout 或第三方服務(例如 Trivy 或 Clair)這樣的工具可以分析您的 Docker 鏡像,查找漏洞和過時的包。這些工具通常提供建議以減少不必要的庫和依賴。

12. 使用 OverlayFS 和共享層

在 Kubernetes 或其他編排環境中,您可以利用 OverlayFS 在鏡像之間共享層。這個檔案系統允許 Docker 僅存儲容器層之間的差異,從而減少磁碟上的總大小。

13. 考慮 Unikernels

如果需要極端的大小優化,考慮使用 Unikernels。這些是單一用途、輕量級的虛擬機,僅打包應用程序及其最小所需的操作系統組件。它們比傳統的 Docker 容器小得多,儘管實施起來更加複雜。


結論

優化 Docker 鏡像大小是保持高效和可擴展的容器化環境的關鍵方面。通過從最小基礎鏡像開始,利用多階段構建以及清理不必要的檔案,您可以顯著減少您的鏡像大小。遵循這些最佳實踐不僅能提高您部署的性能,還能增強安全性並降低成本。

通過定期審計和精簡您的 Docker 鏡像,您可以確保您的容器是精簡、安全且準備好進入生產環境的。這些步驟將節省帶寬、降低啟動時間並為您的 DevOps 流水線提供更高效的開發工作流程。


通過應用這些技術,您可以幫助 DevOps 工程師創建優化的 Docker 鏡像,提高應用程序的整體效率。較小的鏡像不僅更快部署;還有助於在雲原生環境中改善安全性、可靠性和成本效率。

👤 作者

banner


原文出處:https://dev.to/prodevopsguytech/how-to-reduce-docker-image-size-best-practices-and-tips-for-devops-engineers-1ahg

按讚的人:

共有 0 則留言