寫這篇想要分享的重點:
在 Kubernetes 中,Pod 是最小的部署單元。雖然絕大多數情況下一個 Pod 只會有一個容器,但在許多複雜應用情境中,我們需要多個容器共享生命週期、網路與儲存空間,以達成協作。本篇將介紹 Multi-Container Pods 的三個設計模式(Co-located、InitContainers、SidecarContainers)及其生命週期與實作。
💡其實我們在前面Day 04 已經提過一次sidecar的運作方式, 但是這邊我們會把各種模式做一次比較這篇想要講什麼:
- Multi-Container Pod 的基礎與核心共享機制(Lifecycle、Network、Storage)。
- 容器設計模式對比:Co-located Containers、Regular Init Containers 與 Sidecar Containers。
- YAML 實做:如何在
initContainers中設定標準 Init 容器與具備restartPolicy: Always的 Sidecar 容器。為何要寫這篇:
微服務架構提倡職責分離,我們不應把所有功能(如日誌收集、初始化檢查、主服務)全部塞進同一個容器映像檔中。掌握多容器設計模式,能讓我們以解耦、高內聚的方式建構現代化雲端服務。
在微服務(Microservices)架構中,大部分服務是以 1 對 1 的關係獨立運作在不同的 Pod 中。但有時我們需要兩個以上的容器「在同一台機器(節點)上」協同工作。
+--------------------------------------------------------------------+
| Pod |
| |
| +------------------------+ +---------------------------+ |
| | Main App Container | | Sidecar/Helper Container | |
| +------------------------+ +---------------------------+ |
| | | |
| +----------------+----------------+ |
| | |
| [ Shared Network / Storage / Lifecycle ] |
+--------------------------------------------------------------------+
當多個容器放在同一個 Pod 時,它們會共享以下資源:
localhost:<PORT> 直接通訊。Volume(如 emptyDir),實現檔案與資料的即時共享。根據容器的啟動順序與生命週期行為,多容器設計模式主要分為以下三種:
1. Co-located Containers 2. Regular Init Containers 3. Sidecar Containers
+--------------------------+ +--------------------------+ +--------------------------+
| +-------------+ | | +--------------------+ | | +--------------------+ |
| | Container A | | | | Init Container | | | | Sidecar Container | |
| +-------------+ | | | (Runs then exits) | | | | (Starts first, | |
| +-------------+ | | +---------+----------+ | | | runs continuously)| |
| | Container B | | | | | | +---------+----------+ |
| +-------------+ | | v | | | |
| (No startup order check) | | +--------------------+ | | v |
+--------------------------+ | | Main Application | | | +--------------------+ |
| +--------------------+ | | | Main Application | |
+--------------------------+ | +--------------------+ |
+--------------------------+
containers 列表下定義多個容器。initContainers 區段。initContainers 區段,但加上 restartPolicy: Always 設定。fluentbit 或 tail -F)、監控 Proxy、Service Mesh 的 Envoy 代理。在此範例中,init-myservice 與 init-mydb 會按順序依次執行,不斷檢查 DNS 服務,直到 myservice 與 mydb 都 Ready 後,主容器 myapp-container 才開始啟動。
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app.kubernetes.io/name: MyApp
spec:
containers:
- name: myapp-container
image: busybox:1.28
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
initContainers:
- name: init-myservice
image: busybox:1.28
command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
- name: init-mydb
image: busybox:1.28
command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]
主容器 myapp 將日誌寫入 /opt/logs.txt(掛載在 emptyDir 共享卷),而 Sidecar 容器 logshipper 設定了 restartPolicy: Always,會先啟動並持續監控該檔案的日誌輸出。
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
labels:
app: myapp
spec:
replicas: 1
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: alpine:latest
command: ['sh', '-c', 'while true; do echo "logging" >> /opt/logs.txt; sleep 1; done']
volumeMounts:
- name: data
mountPath: /opt
initContainers:
- name: logshipper
image: alpine:latest
# 設定 restartPolicy: Always 使其轉換為標準 Sidecar 容器
restartPolicy: Always
command: ['sh', '-c', 'tail -F /opt/logs.txt']
volumeMounts:
- name: data
mountPath: /opt
volumes:
- name: data
emptyDir: {}
| 模式名稱 | 定義位置 | 啟動順序 | 是否會退出? | 主要目的/用途 |
|---|---|---|---|---|
| Co-located Containers | spec.containers |
無無法保證順序 | 否(長駐運行) | 緊密耦合的輔助服務,但無啟動依賴需求 |
| Regular Init Containers | spec.initContainers |
主程式前,按宣告順序執行 | 是(執行完即 Exit 0) | 環境準備、相依服務就緒檢查、DB Migration |
| Sidecar Containers | spec.initContainers + restartPolicy: Always |
主程式前啟動 | 否(與 Pod 同壽) | 日誌收集、指標監控、Service Mesh 代理 |
本篇總結:
多容器 Pod 模式讓多個容器能夠共享生命週期、網路與儲存空間。透過劃分 Co-located、InitContainers 與 Sidecar 三種模式,我們能解決容器間啟動順序相依、環境前置準備與背景輔助任務等複雜的架構難題。
下一篇預告:
掌握了 Pod 內部的多容器架構設計後,明天 Day 13 我們將邁入 【擴展】自動水平與垂直擴容 (HPA & VPA)——結合 Metrics Server 實現 Pod 的 Horizontal Pod Autoscaler (HPA) 與 Vertical Pod Autoscaler (VPA) 資源自動調配!千萬別錯過!
spec.containers 中的多個容器無法控制啟動先後順序,適合無嚴格啟動相依性的服務。initContainers 欄位中加上 restartPolicy: Always,即可宣告為在主容器啟動前先跑、且會在背景持續執行的原生 Sidecar 容器。