iT邦幫忙

2026 iThome 鐵人賽

DAY 12
0
Kubernetes

Kubernetes學習心得分享系列 第 12

Day 12:【架構】多容器協作設計模式 (Multi-Container Pods)

  • 分享至 

  • xImage
  •  

前言

寫這篇想要分享的重點:
在 Kubernetes 中,Pod 是最小的部署單元。雖然絕大多數情況下一個 Pod 只會有一個容器,但在許多複雜應用情境中,我們需要多個容器共享生命週期、網路與儲存空間,以達成協作。本篇將介紹 Multi-Container Pods 的三個設計模式(Co-located、InitContainers、SidecarContainers)及其生命週期與實作。
💡其實我們在前面Day 04 已經提過一次sidecar的運作方式, 但是這邊我們會把各種模式做一次比較

這篇想要講什麼:

  1. Multi-Container Pod 的基礎與核心共享機制(Lifecycle、Network、Storage)。
  2. 容器設計模式對比:Co-located Containers、Regular Init Containers 與 Sidecar Containers。
  3. YAML 實做:如何在 initContainers 中設定標準 Init 容器與具備 restartPolicy: Always 的 Sidecar 容器。

為何要寫這篇:
微服務架構提倡職責分離,我們不應把所有功能(如日誌收集、初始化檢查、主服務)全部塞進同一個容器映像檔中。掌握多容器設計模式,能讓我們以解耦、高內聚的方式建構現代化雲端服務。

名詞對應

  • Multi-Container Pod: 多容器 Pod
  • Co-located Containers: 共存容器
  • Init Container: 初始化容器
  • Sidecar Container: 側車容器
  • Sidecar Pattern: Sidecar 模式 / 邊車模式

Multi-Container Pod 的基礎概念

在微服務(Microservices)架構中,大部分服務是以 1 對 1 的關係獨立運作在不同的 Pod 中。但有時我們需要兩個以上的容器「在同一台機器(節點)上」協同工作。

+--------------------------------------------------------------------+
| Pod                                                                |
|                                                                    |
|  +------------------------+        +---------------------------+   |
|  |     Main App Container |        |  Sidecar/Helper Container |   |
|  +------------------------+        +---------------------------+   |
|               |                                 |                  |
|               +----------------+----------------+                  |
|                                |                                   |
|            [ Shared Network / Storage / Lifecycle ]                |
+--------------------------------------------------------------------+

當多個容器放在同一個 Pod 時,它們會共享以下資源:

  • Lifecycle(生命週期):一同被排程到相同的 Node,一同建立與銷毀。
  • Network(網路):共享相同的 IP 位址與 Localhost 網路空間,容器間可透過 localhost:<PORT> 直接通訊。
  • Storage(儲存):可掛載相同的 Volume(如 emptyDir),實現檔案與資料的即時共享。

三大多容器設計模式 (Design Patterns)

根據容器的啟動順序與生命週期行為,多容器設計模式主要分為以下三種:

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   |  |
                                 +--------------------------+     |  +--------------------+  |
                                                                  +--------------------------+

1. Co-located Containers(共存容器)

  • 特徵:在 containers 列表下定義多個容器。
  • 啟動順序無法指定或保證啟動順序,所有容器基本上同步啟動。
  • 缺點:若 Container B 依賴 Container A 的網路服務,但 Container B 搶先啟動成功,可能導致 B 因連線失敗而崩潰重啟。

2. Regular Init Containers(一般初始化容器)

  • 特徵:定義於 initContainers 區段。
  • 運作機制:在主應用程式(Main App)啟動之前執行。必須成功執行完畢並正常退出(Exit Code 0)後,主應用程式才會開始啟動。
  • 常見應用:等待外部服務(如 Database、其他 API)Ready 後才允許主程式啟動;或者執行前置的資料庫 Migration。

3. Sidecar Containers(側車容器)

  • 特徵:定義於 initContainers 區段,但加上 restartPolicy: Always 設定。
  • 運作機制會在主應用程式啟動之前先啟動,但與 Init Container 不同的是,它不會退出,而是會在背景持續運行,存在於整個 Pod 的生命週期,直到 Pod 被終止。
  • 常見應用:日誌收集器(Log Shipper,如 fluentbittail -F)、監控 Proxy、Service Mesh 的 Envoy 代理。

實作 YAML 配置

1. Regular Init Containers 範例

在此範例中,init-myserviceinit-mydb 會按順序依次執行,不斷檢查 DNS 服務,直到 myservicemydb 都 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"]

2. Sidecar Container 範例

主容器 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-locatedInitContainersSidecar 三種模式,我們能解決容器間啟動順序相依、環境前置準備與背景輔助任務等複雜的架構難題。

  • 下一篇預告:
    掌握了 Pod 內部的多容器架構設計後,明天 Day 13 我們將邁入 【擴展】自動水平與垂直擴容 (HPA & VPA)——結合 Metrics Server 實現 Pod 的 Horizontal Pod Autoscaler (HPA) 與 Vertical Pod Autoscaler (VPA) 資源自動調配!千萬別錯過!

Takeaway

  • Pod 資源共享機制:同一個 Pod 內的所有容器共享相同的 IP、Network Namespace 以及掛載的 Volume 儲存空間。
  • Co-located 順序不可控:放在 spec.containers 中的多個容器無法控制啟動先後順序,適合無嚴格啟動相依性的服務。
  • InitContainers 阻塞式前置:在主容器啟動前按順序執行,必須順利結束退出(Exit Code 0)後,主容器才會開始啟動。
  • Native Sidecar 語法:在 initContainers 欄位中加上 restartPolicy: Always,即可宣告為在主容器啟動前先跑、且會在背景持續執行的原生 Sidecar 容器。

上一篇
Day 11:【配置】 環境變數抽離:ConfigMaps 與 Secrets 應用
系列文
Kubernetes學習心得分享12
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言