阿川私房教材:學程式,拿 offer!

63 個專案實戰,直接上手!
無需補習,按步驟打造你的面試作品。

立即解鎖你的轉職秘笈

Docker是一個強大的工具,使開發人員能夠容器化他們的應用程式並確保跨各種環境的一致性。

然而,如果不仔細考慮,Docker 映像可能會變得臃腫、緩慢且容易受到安全風險的影響。在本指南中,我將引導您了解最佳化 Docker 映像大小和安全性的策略,確保高效、安全的部署。


優化 Docker 映像的大小

Docker 映像的大小直接影響拉取和部署的速度,這將顯著減少管道執行時間和工件儲存成本,因此減小映像大小對於效能和資源效率至關重要。

在本節的最後,我將向您展示我的作品集網站的圖像尺寸縮小了近 96%!

以下是最小化影像尺寸的方法:

1) 使用官方最小基礎鏡像

建置 Docker 映像時,請始終從官方基礎映像開始。不要使用像ubuntu這樣的全尺寸作業系統映像,而是選擇像alpinedebian-slim這樣的輕量級版本。這些最小的圖像僅包含必需的內容,從而顯著減少了圖像大小。

節點圖像為例,以下是node:latestnode:alpine的圖像大小:

圖片說明

幾乎是原來的 7 倍!

透過使用最少的基礎映像,您可以避免不必要的套件,從而加快建置速度並縮小映像。

2)最小化層數

Dockerfile 中的每個指令( RUNCOPY等)都會在最終映像中建立一個新圖層。將相關指令組合到單一圖層中可以減少層數,從而減少影像大小。

  • 而不是這樣做
RUN apt-get update
RUN apt-get install -y curl
RUN rm -rf /var/lib/apt/lists/*
  • 這樣做
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*

3)使用“.dockerignore”排除不需要的文件

建置 Docker 映像時,除非您另外指定,否則 Docker 會將整個上下文(專案目錄中的所有內容)複製到映像中。為了防止包含不必要的文件,請建立一個 .dockerignore 文件。

  • 範例.dockerignore
node_modules
.git
logs
tmp

該文件的工作方式與 .gitignore 類似

4) 使用靜態二進位檔案和「臨時」基礎鏡像

如果您的應用程式可以編譯為靜態二進位文件,則可以使用臨時基礎映像,它本質上是一個空映像。這導致最終圖像非常小。

  • 例子
FROM scratch
COPY myapp /
CMD ["/myapp"]

非常適合不需要作業系統層級依賴項的應用程式。

5)多階段建構(最有效)

多階段建置可讓您將建置過程與執行時間環境分開。當您的應用程式需要編譯工具但在最終映像中不需要它們時,這尤其有用。

  • 例子
# Stage 1: Build
FROM golang:1.16-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp .

# Stage 2: Runtime
FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/myapp .
CMD ["./myapp"]

定量比較

我的作品集網站是使用 React 建立的,之前是使用Node:14-alpine映像建立的,該圖像仍然比Node:latest圖像小。

  • Dockerfile 是這樣的:
# Use an official Node runtime as a parent image
FROM node:14-alpine

# Set the working directory
WORKDIR /app

# Copy package.json and package-lock.json to the working directory
COPY package*.json ./

# Install dependencies
RUN npm install

# Copy the rest of the application code to the working directory
COPY . .

# Build the React app
RUN npm run build

# Install a lightweight HTTP server to serve the app
RUN npm install -g serve

# Set the default command to serve the build folder
CMD ["serve", "-s", "build"]

# Expose the port the app will run on
EXPOSE 3000
  • 建構的圖像大小為:

圖片說明

很久以後,我了解了多階段建置並重新設計了我的 Dockerfile。

  • 新的 Dockerfile 如下所示:
# Build environment (Stage - I)
FROM node:14-alpine as build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# Production environment (Stage - II)
FROM nginx:alpine
COPY --from=build /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

令人驚訝的是,新的圖像尺寸是...

圖片說明

該應用程式的工作方式與以前完全相同,並且該版本的啟動速度要快得多!

所產生的差異約為1079 MB ,減少了近96%

這是多階段建構效果的圖示


優化 Docker 映像的安全性

1) 使用可信的官方基礎鏡像

始終使用來自受信任來源(例如 Docker Hub 或組織的受信任註冊表)的官方基礎映像。這些映像會定期更新,並且與自訂或非官方映像相比更安全。讓您的基礎映像保持最新,以減少任何漏洞。

2)以非root使用者身分執行容器

以 root 身分執行容器可能會使您的主機系統面臨安全風險。在 Dockerfile 中建立一個非 root 用戶,並將容器配置為在該用戶下執行。

  • 例子:
RUN adduser --disabled-password myuser
USER myuser

這種簡單的更改透過限制對系統資源的存取來減少攻擊面並提高安全性。

3) 掃描影像是否有漏洞

使用下列工具定期掃描 Docker 映像是否有已知漏洞:

  • Trivy:開源漏洞掃描器。

  • Docker Scan:內建於 Docker CLI 中。

  • Clair:用於發現漏洞的靜態分析工具。

這些工具會掃描您的影像中是否有過時或不安全的軟體包,並提醒您潛在的威脅。

4)限制網路暴露

透過限制容器偵聽的連接埠和 IP 位址來限制容器的網路暴露。預設情況下,Docker 會向所有介面公開連接埠。如果不需要外部存取,請將它們綁定到本機。

  • 例子:
docker run -p 127.0.0.1:8080:8080 myimage

這將對容器服務的存取限制為僅限本機計算機,從而防止外部存取。

4)保密管理

避免將 API 金鑰或密碼等敏感資訊直接硬編碼到 Dockerfile 或環境變數中。相反,請使用 Docker 金鑰或外部金鑰管理工具,例如 AWS Secrets Manager 或 HashiCorp Vault。

  • 使用 Docker Secret 的範例:
docker secret create my_secret secret.txt

Docker 機密可確保敏感資料僅可供所需的服務使用,而不會在容器檔案系統中留下痕跡。


結論

透過遵循這些策略,您可以建立既輕量又安全的 Docker 映像。優化大小有助於減少部署時間、節省資源、降低成本並提高效能,而安全最佳實踐可保護您的應用程式和基礎架構免受漏洞影響。

請記住,容器化提供了許多優勢,但也帶來了新的挑戰。透過深思熟慮的映像優化,您可以充分利用 Docker 的潛力,同時保持強大的安全態勢。

如果您覺得這篇文章有幫助,請按讚。

關注我,了解更多這類內容。

快樂學習!


獨家創作,

👨‍💻 阿克沙特·高塔姆

谷歌認證助理雲端工程師 |全端開發人員

請隨時在LinkedIn上與我聯絡。


原文出處:https://dev.to/akshat_gautam/optimizing-docker-images-for-size-and-security-a-comprehensive-guide-4df0

按讚的人:

共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。

阿川私房教材:學程式,拿 offer!

63 個專案實戰,直接上手!
無需補習,按步驟打造你的面試作品。

立即解鎖你的轉職秘笈