前言:為什麼需要 Pod?

在 Kubernetes 的世界裡,Pod 是一切的基礎。如果把 Kubernetes 比喻成一座城市,那麼 Pod 就是城市中的「最小住宅單位」。

但為什麼 Kubernetes 不直接管理容器(Container),而要多一層 Pod 的抽象?

簡單回答:因為容器太小,Pod 剛剛好。

想像你要管理一座城市的住宅:

  • 如果直接管理每個「房間」(容器)→ 太細碎,管理成本太高
  • 如果直接管理整棟「大樓」(Node)→ 太粗糙,缺乏彈性
  • 所以我們需要「住宅單位」(Pod)→ 大小適中,便於管理

本文將深入探討:

  • Pod 的核心概念與設計哲學
  • Pod 的內部架構與運作機制
  • Pod 網路模型與通訊方式
  • Pod 生命週期與狀態管理
  • Pod 設計模式與最佳實踐
  • 實戰範例與 YAML 配置

Pod 核心概念:容器的邏輯主機

什麼是 Pod?

官方定義:

Pod 是 Kubernetes 中最小的可部署計算單元,可以包含一個或多個容器,這些容器共享網路、儲存和其他資源。

生活化比喻:

graph TB
    subgraph "傳統虛擬機世界"
        VM1[虛擬機 VM]
        VM1 --> App1[應用程式 1]
        VM1 --> App2[應用程式 2]
        VM1 --> App3[應用程式 3]
    end

    subgraph "Kubernetes Pod 世界"
        Pod[Pod = 邏輯主機]
        Pod --> C1[容器 1]
        Pod --> C2[容器 2]
        Pod --> C3[容器 3]
    end

    style Pod fill:#4ade80
    style VM1 fill:#60a5fa

Pod 就像一個「邏輯主機」

  • 在傳統架構中,多個應用程式運行在同一台虛擬機上
  • 在 Kubernetes 中,多個容器運行在同一個 Pod 上
  • Pod 提供了容器之間的「緊密耦合」環境

Pod 的三大核心特性

1. 共享網路命名空間

graph LR
    subgraph "Pod 網路空間"
        IP[共享 IP: 10.244.1.5]
        IP --> C1[容器 1<br/>localhost:8080]
        IP --> C2[容器 2<br/>localhost:9090]
        IP --> C3[容器 3<br/>localhost:3000]
    end

    Outside[外部請求] --> IP

    style IP fill:#4ade80

同一個 Pod 內的容器:

  • ✅ 共享同一個 IP 位址
  • ✅ 可以透過 localhost 互相通訊
  • ✅ 但 Port 不能衝突(每個容器用不同 Port)

2. 共享儲存卷(Volume)

graph TB
    subgraph "Pod 儲存空間"
        Vol1[Volume: logs]
        Vol2[Volume: config]

        Vol1 --> C1[容器 1<br/>寫入日誌]
        Vol1 --> C2[容器 2<br/>讀取日誌]

        Vol2 --> C1
        Vol2 --> C3[容器 3<br/>讀取設定]
    end

    style Vol1 fill:#60a5fa
    style Vol2 fill:#8b5cf6

同一個 Pod 內的容器:

  • ✅ 可以掛載相同的 Volume
  • ✅ 實現檔案共享(例如日誌、設定檔)
  • ✅ 不需要透過網路傳輸

3. 原子化調度

Kubernetes 調度器(Scheduler)將 Pod 視為一個整體:

  • 整個 Pod 會被分配到同一個 Node 上
  • Pod 內的所有容器一起啟動、一起停止
  • 資源限制(CPU、Memory)以 Pod 為單位計算

Pod 架構深度解析

Pod 的內部結構

graph TB
    subgraph "Pod: my-app"
        subgraph "基礎設施容器"
            Pause[Pause 容器<br/>負責網路命名空間]
        end

        subgraph "應用容器"
            Main[主容器<br/>nginx:1.21]
            Sidecar[Sidecar 容器<br/>log-collector]
        end

        subgraph "Init 容器"
            Init1[Init 容器 1<br/>db-migration]
            Init2[Init 容器 2<br/>config-setup]
        end

        subgraph "共享資源"
            Network[網路命名空間]
            Vol[Volume: /data]
        end

        Init1 -.執行順序.-> Init2
        Init2 -.完成後.-> Main
        Init2 -.完成後.-> Sidecar

        Pause --> Network
        Main --> Network
        Sidecar --> Network

        Main --> Vol
        Sidecar --> Vol
    end

    style Pause fill:#f97316
    style Main fill:#4ade80
    style Sidecar fill:#60a5fa
    style Init1 fill:#8b5cf6
    style Init2 fill:#8b5cf6

容器類型說明:

1. Pause 容器(基礎設施容器)

  • Kubernetes 自動創建的隱藏容器
  • 作用:建立並持有網路命名空間
  • 極其輕量(~700KB),幾乎不消耗資源
  • Pod 的生命週期由它決定

2. Init 容器(初始化容器)

  • 在應用容器啟動前執行
  • 按順序執行(一個接一個)
  • 用途:資料庫遷移、設定檔準備、等待依賴服務
  • 失敗會導致 Pod 重啟

3. 應用容器(Main Containers)

  • 實際運行業務邏輯的容器
  • 可以有一個或多個
  • 同時啟動(並行)

4. Sidecar 容器(輔助容器)

  • 與主容器同時運行
  • 用途:日誌收集、監控代理、服務網格(如 Envoy)
  • 獨立的生命週期管理

Pod 網路模型

Kubernetes 網路三大原則:

  1. 每個 Pod 有獨立的 IP
  2. Pod 之間可以直接通訊(不需要 NAT)
  3. Node 可以與所有 Pod 通訊
graph TB
    subgraph "Node 1: 192.168.1.10"
        Pod1[Pod A<br/>10.244.1.5]
        Pod2[Pod B<br/>10.244.1.6]
    end

    subgraph "Node 2: 192.168.1.11"
        Pod3[Pod C<br/>10.244.2.5]
        Pod4[Pod D<br/>10.244.2.6]
    end

    Pod1 <-->|直接通訊| Pod3
    Pod2 <-->|直接通訊| Pod4
    Pod1 <-->|同 Node 內| Pod2
    Pod3 <-->|同 Node 內| Pod4

    style Pod1 fill:#4ade80
    style Pod2 fill:#60a5fa
    style Pod3 fill:#f97316
    style Pod4 fill:#8b5cf6

Pod 內部通訊範例:

# Pod 定義
apiVersion: v1
kind: Pod
metadata:
  name: multi-container-pod
spec:
  containers:
  - name: nginx
    image: nginx:1.21
    ports:
    - containerPort: 80

  - name: log-agent
    image: fluent/fluentd:latest
    # 可以透過 localhost:80 存取 nginx

在 log-agent 容器內:

# 直接用 localhost 訪問 nginx
curl http://localhost:80

# 成功!因為共享網路命名空間

Pod 生命週期管理

Pod 的狀態機

stateDiagram-v2
    [*] --> Pending: 建立 Pod
    Pending --> Running: 容器啟動成功
    Running --> Succeeded: 容器正常結束
    Running --> Failed: 容器異常結束
    Failed --> Running: 重啟策略生效
    Running --> Unknown: 節點失聯
    Unknown --> Failed: 節點恢復,Pod 已死

    Pending --> Failed: 無法調度

    note right of Pending
        等待調度
        拉取映像檔
        Init 容器執行
    end note

    note right of Running
        至少一個容器運行中
        可能有容器重啟
    end note

    note right of Succeeded
        所有容器成功結束
        不會重啟(Job/CronJob)
    end note

    note right of Failed
        至少一個容器失敗
        可能觸發重啟
    end note

Pod 生命週期階段詳解

1. Pending(等待中)

Pod 已被 Kubernetes 接受,但還沒開始運行:

$ kubectl get pod my-pod

NAME     READY   STATUS    RESTARTS   AGE
my-pod   0/1     Pending   0          5s

可能原因:

  • ⏳ 等待調度器分配 Node
  • ⏳ 正在拉取容器映像檔
  • ⏳ Init 容器正在執行
  • ❌ 資源不足(CPU、Memory)
  • ❌ PersistentVolumeClaim 無法綁定

排查指令:

# 查看詳細事件
kubectl describe pod my-pod

# 常見錯誤訊息
Events:
  Type     Reason            Message
  ----     ------            -------
  Warning  FailedScheduling  0/3 nodes are available: insufficient memory

2. Running(運行中)

至少一個容器正在運行:

$ kubectl get pod my-pod

NAME     READY   STATUS    RESTARTS   AGE
my-pod   2/2     Running   0          1m

READY 欄位解讀:

  • 2/2 → 2 個容器都就緒
  • 1/2 → 只有 1 個容器就緒(另一個可能在啟動或崩潰)
  • 0/2 → 沒有容器就緒(可能在重啟)

3. Succeeded(成功完成)

所有容器都成功結束(退出碼 0):

$ kubectl get pod my-job-pod

NAME          READY   STATUS      RESTARTS   AGE
my-job-pod    0/1     Completed   0          2m

適用於:

  • Kubernetes Job
  • CronJob
  • 一次性任務(資料遷移、批次處理)

4. Failed(失敗)

至少一個容器以非零退出碼結束:

$ kubectl get pod my-pod

NAME     READY   STATUS   RESTARTS   AGE
my-pod   0/1     Error    0          30s

常見失敗狀態:

  • Error - 容器退出碼非零
  • CrashLoopBackOff - 容器反覆崩潰
  • ImagePullBackOff - 無法拉取映像檔
  • OOMKilled - 記憶體不足被殺掉

5. Unknown(未知)

無法獲取 Pod 狀態(通常是 Node 失聯):

$ kubectl get pod my-pod

NAME     READY   STATUS    RESTARTS   AGE
my-pod   0/1     Unknown   0          5m

Pod 重啟策略

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  restartPolicy: Always  # Always | OnFailure | Never
  containers:
  - name: app
    image: myapp:v1

重啟策略對照表:

策略說明適用場景
Always容器退出就重啟(預設)長期運行的服務(Web、API)
OnFailure只有失敗時才重啟批次處理、資料處理
Never從不重啟一次性任務、偵錯

重啟行為:

sequenceDiagram
    participant K8s
    participant Pod
    participant Container

    Container->>Pod: 退出(Exit Code)
    Pod->>K8s: 報告容器退出

    alt restartPolicy=Always
        K8s->>Pod: 立即重啟容器
        Note over K8s,Container: 等待時間:10s, 20s, 40s...<br/>最大 5 分鐘
    else restartPolicy=OnFailure AND Exit Code ≠ 0
        K8s->>Pod: 重啟容器
    else restartPolicy=Never OR Exit Code = 0
        K8s->>Pod: 不重啟
        Note over Pod: 狀態變為 Succeeded/Failed
    end

Pod 設計模式

1. Sidecar 模式(最常見)

**概念:**在主容器旁邊放一個輔助容器,提供額外功能。

使用場景:

  • 日誌收集(Fluentd、Filebeat)
  • 監控代理(Prometheus exporter)
  • 服務網格(Istio Envoy)
  • 配置熱更新

架構圖:

graph LR
    subgraph "Pod: web-app"
        Main[主容器<br/>Nginx Web Server<br/>:80]
        Sidecar[Sidecar<br/>日誌收集器<br/>讀取 /var/log]

        Vol[Volume: logs<br/>/var/log/nginx]

        Main -->|寫入日誌| Vol
        Sidecar -->|讀取日誌| Vol
    end

    Sidecar -->|傳送| LogServer[日誌伺服器<br/>Elasticsearch]

    style Main fill:#4ade80
    style Sidecar fill:#60a5fa

實戰範例:Nginx + 日誌收集

apiVersion: v1
kind: Pod
metadata:
  name: nginx-with-logging
spec:
  containers:
  # 主容器:Nginx Web Server
  - name: nginx
    image: nginx:1.21
    ports:
    - containerPort: 80
    volumeMounts:
    - name: logs
      mountPath: /var/log/nginx

  # Sidecar 容器:日誌收集
  - name: log-collector
    image: fluent/fluentd:latest
    volumeMounts:
    - name: logs
      mountPath: /var/log/nginx
      readOnly: true  # 只讀,避免誤刪

  volumes:
  - name: logs
    emptyDir: {}  # 臨時儲存

2. Ambassador 模式(大使模式)

**概念:**Sidecar 容器作為主容器與外部世界的代理。

使用場景:

  • 資料庫連線池代理
  • Redis 集群代理
  • gRPC 負載平衡

架構圖:

sequenceDiagram
    participant App as 應用容器<br/>(localhost:6379)
    participant Ambassador as Ambassador 容器<br/>Redis Proxy
    participant Redis1 as Redis Master
    participant Redis2 as Redis Replica

    App->>Ambassador: 連線 localhost:6379
    Note over App,Ambassador: 應用不知道外部複雜度

    Ambassador->>Redis1: 寫入請求
    Ambassador->>Redis2: 讀取請求(負載平衡)

    Redis1-->>Ambassador: 回應
    Ambassador-->>App: 回應

實戰範例:應用 + Redis Ambassador

apiVersion: v1
kind: Pod
metadata:
  name: app-with-redis-proxy
spec:
  containers:
  # 主容器:應用程式
  - name: app
    image: myapp:v1
    env:
    - name: REDIS_HOST
      value: "localhost"  # 連到 Sidecar
    - name: REDIS_PORT
      value: "6379"

  # Ambassador 容器:Redis Proxy
  - name: redis-proxy
    image: haproxy:2.4
    ports:
    - containerPort: 6379
    volumeMounts:
    - name: config
      mountPath: /usr/local/etc/haproxy

  volumes:
  - name: config
    configMap:
      name: redis-proxy-config

3. Adapter 模式(適配器模式)

**概念:**標準化主容器的輸出格式。

使用場景:

  • 日誌格式轉換(JSON → Plain Text)
  • 監控指標轉換(Prometheus 格式)
  • 資料格式標準化

架構圖:

graph LR
    subgraph "Pod"
        Main[主容器<br/>Legacy App<br/>非標準日誌]
        Adapter[Adapter<br/>格式轉換器]

        Main -->|原始日誌| Vol[Volume]
        Vol -->|讀取| Adapter
    end

    Adapter -->|標準 JSON 格式| Monitor[監控系統<br/>Prometheus]

    style Main fill:#f97316
    style Adapter fill:#60a5fa

實戰範例:日誌格式轉換

apiVersion: v1
kind: Pod
metadata:
  name: app-with-adapter
spec:
  containers:
  # 主容器:舊版應用(非標準日誌)
  - name: legacy-app
    image: old-app:1.0
    volumeMounts:
    - name: logs
      mountPath: /var/log/app

  # Adapter 容器:日誌格式轉換
  - name: log-adapter
    image: busybox
    command:
    - sh
    - -c
    - |
      tail -f /var/log/app/app.log | \
      awk '{print "{\"timestamp\":\""strftime("%Y-%m-%dT%H:%M:%S")"\"
,\"message\":\""$0"\"}"}' \
      > /var/log/standardized/app.json
    volumeMounts:
    - name: logs
      mountPath: /var/log/app
      readOnly: true
    - name: standardized-logs
      mountPath: /var/log/standardized

  volumes:
  - name: logs
    emptyDir: {}
  - name: standardized-logs
    emptyDir: {}

實戰配置範例

基本 Pod 配置

apiVersion: v1
kind: Pod
metadata:
  name: simple-web-app
  labels:
    app: web
    tier: frontend
spec:
  containers:
  - name: nginx
    image: nginx:1.21
    ports:
    - containerPort: 80
      protocol: TCP

    # 資源限制
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"

    # 健康檢查
    livenessProbe:
      httpGet:
        path: /
        port: 80
      initialDelaySeconds: 30
      periodSeconds: 10

    readinessProbe:
      httpGet:
        path: /
        port: 80
      initialDelaySeconds: 5
      periodSeconds: 5

使用 Init 容器

apiVersion: v1
kind: Pod
metadata:
  name: app-with-init
spec:
  # Init 容器(按順序執行)
  initContainers:
  - name: init-db-check
    image: busybox:1.35
    command:
    - sh
    - -c
    - |
      until nc -z db-service 5432; do
        echo "Waiting for database..."
        sleep 2
      done
      echo "Database is ready!"

  - name: init-migration
    image: myapp:v1
    command: ["python", "manage.py", "migrate"]
    env:
    - name: DATABASE_URL
      valueFrom:
        secretKeyRef:
          name: db-secret
          key: url

  # 主容器
  containers:
  - name: app
    image: myapp:v1
    ports:
    - containerPort: 8000

多容器 Pod(完整範例)

apiVersion: v1
kind: Pod
metadata:
  name: full-stack-pod
  labels:
    app: my-app
spec:
  # Init 容器:準備工作
  initContainers:
  - name: setup-config
    image: busybox
    command:
    - sh
    - -c
    - |
      echo "Preparing configuration..."
      cp /config-template/* /app-config/
    volumeMounts:
    - name: config-template
      mountPath: /config-template
    - name: app-config
      mountPath: /app-config

  # 主容器們
  containers:
  # 1. 應用程式
  - name: app
    image: myapp:v2.1
    ports:
    - containerPort: 8080
    env:
    - name: CONFIG_PATH
      value: /app-config
    volumeMounts:
    - name: app-config
      mountPath: /app-config
    - name: logs
      mountPath: /var/log/app
    resources:
      requests:
        memory: "256Mi"
        cpu: "500m"
      limits:
        memory: "512Mi"
        cpu: "1000m"
    livenessProbe:
      httpGet:
        path: /health
        port: 8080
      initialDelaySeconds: 60
      periodSeconds: 10
    readinessProbe:
      httpGet:
        path: /ready
        port: 8080
      initialDelaySeconds: 10
      periodSeconds: 5

  # 2. 日誌收集 Sidecar
  - name: log-collector
    image: fluent/fluentd:v1.14
    volumeMounts:
    - name: logs
      mountPath: /var/log/app
      readOnly: true
    - name: fluentd-config
      mountPath: /fluentd/etc
    resources:
      requests:
        memory: "128Mi"
        cpu: "100m"
      limits:
        memory: "256Mi"
        cpu: "200m"

  # 3. 監控 Exporter Sidecar
  - name: metrics-exporter
    image: prom/node-exporter:latest
    ports:
    - containerPort: 9100
    resources:
      requests:
        memory: "64Mi"
        cpu: "50m"
      limits:
        memory: "128Mi"
        cpu: "100m"

  # Volumes
  volumes:
  - name: config-template
    configMap:
      name: app-config-template
  - name: app-config
    emptyDir: {}
  - name: logs
    emptyDir: {}
  - name: fluentd-config
    configMap:
      name: fluentd-config

  # Pod 設定
  restartPolicy: Always
  serviceAccountName: my-app-sa
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    fsGroup: 2000

Pod 管理與操作

常用 kubectl 指令

查看 Pod:

# 列出所有 Pod
kubectl get pods

# 查看特定 namespace 的 Pod
kubectl get pods -n production

# 查看所有 namespace 的 Pod
kubectl get pods --all-namespaces

# 查看詳細資訊
kubectl get pods -o wide

# 查看 YAML 定義
kubectl get pod my-pod -o yaml

# 持續監控 Pod 狀態
kubectl get pods -w

查看 Pod 詳情:

# 查看 Pod 詳細資訊(包含事件)
kubectl describe pod my-pod

# 查看特定容器的資訊
kubectl describe pod my-pod | grep -A 10 "Container ID"

查看 Pod 日誌:

# 查看 Pod 日誌
kubectl logs my-pod

# 查看特定容器的日誌(多容器 Pod)
kubectl logs my-pod -c nginx

# 即時查看日誌(類似 tail -f)
kubectl logs -f my-pod

# 查看之前崩潰的容器日誌
kubectl logs my-pod --previous

# 查看最近 100 行日誌
kubectl logs my-pod --tail=100

# 加上時間戳記
kubectl logs my-pod --timestamps

進入 Pod 容器:

# 進入 Pod 的第一個容器
kubectl exec -it my-pod -- /bin/bash

# 進入特定容器
kubectl exec -it my-pod -c nginx -- /bin/sh

# 執行單一指令
kubectl exec my-pod -- ls /app

# 在特定容器執行指令
kubectl exec my-pod -c nginx -- nginx -t

複製檔案:

# 從 Pod 複製到本地
kubectl cp my-pod:/var/log/app.log ./app.log

# 從本地複製到 Pod
kubectl cp ./config.yaml my-pod:/etc/config/

# 複製到特定容器
kubectl cp my-pod:/data/export.csv ./export.csv -c app

刪除 Pod:

# 刪除單個 Pod
kubectl delete pod my-pod

# 刪除多個 Pod
kubectl delete pod pod1 pod2 pod3

# 使用標籤選擇器刪除
kubectl delete pods -l app=nginx

# 強制刪除(不等待 Grace Period)
kubectl delete pod my-pod --grace-period=0 --force

# 刪除所有 Pod
kubectl delete pods --all

Pod 最佳實踐

1. 資源管理

總是設定資源請求和限制:

spec:
  containers:
  - name: app
    resources:
      requests:  # 最小保證
        memory: "256Mi"
        cpu: "500m"
      limits:    # 最大限制
        memory: "512Mi"
        cpu: "1000m"

原則:

  • requests 用於調度決策
  • limits 用於資源限制
  • ✅ 避免設定過大的 limits(容易 OOMKilled)
  • ✅ CPU 可以超賣,Memory 不可以

2. 健康檢查

同時設定 Liveness 和 Readiness Probe:

spec:
  containers:
  - name: app
    livenessProbe:   # 檢查是否存活
      httpGet:
        path: /health
        port: 8080
      initialDelaySeconds: 60
      periodSeconds: 10
      failureThreshold: 3

    readinessProbe:  # 檢查是否就緒
      httpGet:
        path: /ready
        port: 8080
      initialDelaySeconds: 10
      periodSeconds: 5
      failureThreshold: 3

差異:

  • livenessProbe 失敗 → 重啟容器
  • readinessProbe 失敗 → 從 Service 移除,但不重啟

3. 優雅關閉

spec:
  containers:
  - name: app
    lifecycle:
      preStop:
        exec:
          command:
          - sh
          - -c
          - |
            # 停止接受新請求
            echo "Stopping accepting new requests..."
            # 等待現有請求完成
            sleep 15
            # 清理資源
            echo "Cleaning up..."

  terminationGracePeriodSeconds: 30  # 給予 30 秒關閉時間

4. 避免單一容器做太多事

❌ 不好的做法:

# 單一容器包含 Web Server + Database + Cache
containers:
- name: all-in-one
  image: my-monolith:v1

✅ 好的做法:

# 分離關注點
containers:
- name: web
  image: nginx:1.21
- name: app
  image: myapp:v2
- name: cache
  image: redis:6.2

5. 使用標籤和註解

metadata:
  name: my-pod
  labels:
    app: web
    tier: frontend
    version: v2.1
    environment: production
  annotations:
    prometheus.io/scrape: "true"
    prometheus.io/port: "9090"
    description: "Main web application pod"

常見問題與解決方案

Q1: 什麼時候該用多容器 Pod?

應該用多容器:

  • ✅ 容器之間需要緊密耦合(Sidecar 模式)
  • ✅ 容器需要共享檔案系統
  • ✅ 容器需要在同一台機器上(例如 localhost 通訊)

不應該用多容器:

  • ❌ 獨立的微服務(應該用多個 Pod)
  • ❌ 可以透過網路通訊的服務
  • ❌ 需要獨立擴展的應用

Q2: Pod 和 Deployment 有什麼區別?

特性PodDeployment
層級最小單元控制器
副本單一實例管理多個副本
自癒不會自動重建自動重建
更新不支援滾動更新支援滾動更新
使用場景偵錯、測試生產環境

**結論:**生產環境應該使用 Deployment,而不是直接創建 Pod。

Q3: 為什麼我的 Pod 一直 Pending?

排查步驟:

# 1. 查看 Pod 事件
kubectl describe pod my-pod

# 常見原因:
# - Insufficient CPU/Memory(資源不足)
# - No nodes available(沒有可用節點)
# - PVC not bound(儲存卷未綁定)
# - Image pull error(映像檔拉取失敗)

# 2. 查看節點資源
kubectl top nodes

# 3. 查看 PVC 狀態
kubectl get pvc

Q4: 如何在 Pod 之間共享資料?

不推薦在 Pod 之間直接共享 Volume(不同 Pod 可能在不同 Node)

推薦方案:

  1. 使用網路儲存(NFS、S3)
  2. 使用資料庫或快取(Redis、PostgreSQL)
  3. 使用訊息佇列(RabbitMQ、Kafka)

Q5: Init 容器失敗了怎麼辦?

Init 容器失敗會導致 Pod 無法啟動:

# 查看 Init 容器日誌
kubectl logs my-pod -c init-db-check

# Pod 會不斷重試 Init 容器
# 直到成功或達到 BackoffLimit

解決方案:

  • 修正 Init 容器的錯誤
  • 檢查依賴服務是否就緒
  • 調整超時設定

總結與收穫

關鍵要點

Pod 核心概念:

  • Pod 是 K8s 最小部署單元:容器的邏輯主機
  • 共享網路和儲存:Pod 內容器可以用 localhost 通訊
  • 原子化調度:整個 Pod 被視為一個整體

Pod 設計模式:

  • Sidecar:輔助容器提供額外功能(日誌、監控)
  • Ambassador:代理容器簡化外部通訊
  • Adapter:轉換容器標準化輸出

生產環境建議:

  • ✅ 使用 Deployment 而非直接創建 Pod
  • ✅ 設定資源 requests 和 limits
  • ✅ 配置健康檢查(Liveness & Readiness)
  • ✅ 實現優雅關閉
  • ✅ 使用標籤和註解管理

從 Pod 到 Kubernetes 生態

理解 Pod 只是第一步,接下來你可以探索:

  1. Deployment - 管理 Pod 副本和滾動更新
  2. Service - 為 Pod 提供穩定的網路端點
  3. ConfigMap / Secret - 管理設定和敏感資料
  4. PersistentVolume - 持久化儲存
  5. StatefulSet - 有狀態應用
  6. DaemonSet - 每個節點運行一個 Pod
  7. Job / CronJob - 批次任務

Pod 是 Kubernetes 的基石,掌握 Pod 的概念和使用方式,你就能理解整個 Kubernetes 生態系統的運作原理。


參考資源

官方文件:

實用工具:

延伸閱讀: