在 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 官方檔案: (請勿在此處插入連結)
步驟說明
- 啟動 Minikube: 使用
minikube start
命令啟動 Minikube 叢集。(請注意,此處的輸出會因系統環境而異,以下僅為範例)
minikube start
- 建立 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: {}
內容解密:
apiVersion
和kind
指定 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 刪除後資料會消失。
- 建立 Pod: 使用
kubectl apply -f multicontainer.yaml
命令建立 Pod。
kubectl apply -f multicontainer.yaml
驗證 Pod 狀態: 使用
kubectl get pods
命令確認 Pod 是否已成功建立並執行。連線容器並檢查網路介面: 使用
kubectl exec
命令進入webcontainer
和sidecarcontainer
,並使用ifconfig
命令檢查網路介面。您會發現兩個容器都擁有相同的 IP 位址,因為它們分享相同的網路名稱空間。驗證 Volume 分享: 在
webcontainer
和sidecarcontainer
中,確認都能存取/usr/share/nginx/html
和/var/log
目錄下的檔案。埠轉發: 使用
kubectl port-forward
命令將 Pod 的 80 埠轉發到本機的 8080 埠。存取應用程式: 在瀏覽器中開啟
http://127.0.0.1:8080/
,檢視應用程式。更新
index.html
檔案: 修改 GitHub 上的index.html
檔案內容,並觀察 sidecar 容器如何自動更新檔案,以及應用程式如何反映這些更新。刪除 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;
內容解密:
此圖顯示一個包含兩個容器 (webcontainer
和 sidecarcontainer
) 的 Pod (multicontainer
)。兩個容器分享同一個網路名稱空間和一個名為 sharedvolume
的 Volume。