在 Kubernetes 環境中,Sidecar 模式允許我們將輔助功能以容器的形式佈署在主應用程式容器旁,形成多容器 Pod。這種模式讓應用程式更容易擴充套件和維護,無需修改主程式碼即可新增日誌、監控、安全等功能。Sidecar 容器和主容器分享相同的網路和儲存資源,實作高效的協同工作。本文將以一個資料同步的實際案例,帶領讀者逐步瞭解如何運用 Sidecar 模式構建和管理多容器 Pod。

Kubernetes Sidecar 模式實戰:多容器 Pod 的設計與應用

Kubernetes 的 Sidecar 模式是一種設計方法,讓輔助容器(Sidecar)與主要應用容器在同一個 Pod 中執行。此模式能為主要應用程式新增功能或支援,而無需修改其程式碼。Sidecar 容器與主要容器分享相同的網路和儲存空間,使其在特定場景下非常有效率。

Sidecar 容器的應用場景

Sidecar 容器可用於處理各種任務,例如:

  • 日誌記錄: 收集、彙整及轉發應用程式日誌(例如:Fluentd)。
  • 監控: 收集應用程式指標並將其傳送到監控系統(例如:Prometheus)。
  • 代理/網路: 作為服務代理,用於服務網格實作(例如:Envoy 或 Istio)。
  • 安全性: 處理憑證輪換或安全地將機密注入應用程式。
  • 資料同步: 同步來自外部來源的檔案或資料(例如:S3、FTP)。
  • 網路代理和安全性: 作為反向代理(例如:NGINX)或處理 SSL/TLS。
  • 快取: 提供快取層(例如:Redis、Memcached)。
  • 測試和除錯: 在 Sidecar 容器中執行除錯工具(例如:tcpdump)或產生測試流量。
  • 背景任務: 處理定期的作業,例如清理或健康檢查。
  • API Gateway/轉換器: 轉換或調整 API 請求(例如:gRPC 轉換為 REST)。
  • CI/CD: 作為 CI/CD 流程中的輔助功能 (例如:Gitlab runner helpers)。
  • 自動備份: 定期將資料函式庫資料備份到遠端儲存位置(例如:AWS S3)。
  • 日誌歸檔: 壓縮和歸檔主要容器的舊日誌。
  • 漏洞掃描: 掃描應用程式是否存在風險(例如:Clair、Trivy)。
  • 重試和斷路器: 協助重試失敗的請求,管理服務健康狀況(例如:Envoy)。
  • 資料備份: 協助定期進行資料函式庫備份(例如:mysqldump、AWS CLI)。
  • 速率限制: 協助限制 API 請求(例如:Kong、Envoy)。

實戰範例:資料同步

以下例項說明一個簡單的資料同步案例,展現如何建立多容器 Pod,以及容器如何在同一個 Pod 中分享網路介面、儲存空間和進行埠轉發。

環境準備:Minikube 安裝

Minikube 是一個輕量級的 Kubernetes 本地叢集,方便學習和開發 Kubernetes。其包含 Kubernetes 的核心元件,例如 API 伺服器、排程器、控制器管理器和 etcd,以及可選的附加元件,例如儀錶板和 Ingress。

安裝步驟請參考 Minikube 官方檔案: (請勿在此處插入連結)

步驟說明

  1. 啟動 Minikube: 使用 minikube start 命令啟動 Minikube 叢集。(請注意,此處的輸出會因系統環境而異,以下僅為範例)
minikube start
  1. 建立 YAML 檔案 (multicontainer.yaml): 建立一個名為 multicontainer.yaml 的檔案,並將以下內容複製到檔案中:
apiVersion: v1
kind: Pod
metadata:
  name: multicontainer
spec:
  containers:
  - name: webcontainer
    image: nginx
    ports:
    - containerPort: 80
    volumeMounts:
    - name: sharedvolume
      mountPath: /usr/share/nginx/html
  - name: sidecarcontainer
    image: busybox
    command: ["/bin/sh"]
    args: ["-c", "while true; do wget -O /var/log/index.html https://raw.githubusercontent.com/omerbsezer/Fast-Kubernetes/main/index.html; sleep 15; done"]
    volumeMounts:
    - name: sharedvolume
      mountPath: /var/log
  volumes:
  - name: sharedvolume
    emptyDir: {}

內容解密:

  • apiVersionkind 指定 YAML 檔案的版本和型別。
  • metadata.name 指定 Pod 的名稱。
  • spec.containers 定義 Pod 中的容器。
  • webcontainer 容器使用 nginx 映像,並將 80 埠對映到容器內部。
  • sidecarcontainer 容器使用 busybox 映像,每 15 秒從指定的 GitHub 連結下載 index.html 檔案到 /var/log 目錄。
  • volumeMounts 指定容器掛載的 Volume。
  • volumes.sharedvolume 定義一個 emptyDir 型別的 Volume,此 Volume 只在 Pod 存在時有效,Pod 刪除後資料會消失。
  1. 建立 Pod: 使用 kubectl apply -f multicontainer.yaml 命令建立 Pod。
kubectl apply -f multicontainer.yaml
  1. 驗證 Pod 狀態: 使用 kubectl get pods 命令確認 Pod 是否已成功建立並執行。

  2. 連線容器並檢查網路介面: 使用 kubectl exec 命令進入 webcontainersidecarcontainer,並使用 ifconfig 命令檢查網路介面。您會發現兩個容器都擁有相同的 IP 位址,因為它們分享相同的網路名稱空間。

  3. 驗證 Volume 分享:webcontainersidecarcontainer 中,確認都能存取 /usr/share/nginx/html/var/log 目錄下的檔案。

  4. 埠轉發: 使用 kubectl port-forward 命令將 Pod 的 80 埠轉發到本機的 8080 埠。

  5. 存取應用程式: 在瀏覽器中開啟 http://127.0.0.1:8080/,檢視應用程式。

  6. 更新 index.html 檔案: 修改 GitHub 上的 index.html 檔案內容,並觀察 sidecar 容器如何自動更新檔案,以及應用程式如何反映這些更新。

  7. 刪除 Pod: 使用 kubectl delete -f multicontainer.yaml 命令刪除 Pod。

#多容器 Pod 架構

  graph LR
    D[D]
    A[Pod: multicontainer] --> B(Container: webcontainer);
    A --> C(Container: sidecarcontainer);
    B --> D{Shared Volume: sharedvolume};
    C --> D;
    B --> E[Network Namespace];
    C --> E;

內容解密:

此圖顯示一個包含兩個容器 (webcontainersidecarcontainer) 的 Pod (multicontainer)。兩個容器分享同一個網路名稱空間和一個名為 sharedvolume 的 Volume。