Chuyển đến nội dung chính

第4課:Deployments、DaemonSets & StatefulSets

Deployment 策略(RollingUpdate/Recreate)。DaemonSet 使用場景。 StatefulSet 與穩定的網路身份。CKA 考試中的工作負載管理。

Deployment、DaemonSet、StatefulSet 比較

1. Deployment 詳解

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1         # 滾動更新時可額外增加的 Pod 數
      maxUnavailable: 0   # 滾動更新時可不可用的 Pod 數
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: nginx
        image: nginx:1.25
        ports:
        - containerPort: 80
策略行為停機時間
RollingUpdate新舊 Pod 逐步替換無(零停機)
Recreate先停止所有 Pod → 再啟動新 Pod有(部署間有停機)
# 回滾
kubectl rollout undo deployment/web-app
kubectl rollout undo deployment/web-app --to-revision=2

# 查看部署歷史
kubectl rollout history deployment/web-app
kubectl rollout status deployment/web-app

2. DaemonSet

DaemonSet 確保每個節點上運行一個 Pod。

使用場景範例
日誌收集fluentd、filebeat
監控代理Prometheus node exporter、Datadog
網路kube-proxy、Calico、Cilium
儲存CSI node driver
# 建立 DaemonSet(沒有直接指令 — 需要 YAML)
# 技巧:從 Deployment 轉換
kubectl create deployment ds-template --image=fluentd --dry-run=client -o yaml > ds.yaml
# 修改 kind: DaemonSet,移除 replicas,移除 strategy

3. StatefulSet

StatefulSet vs Deployment:
  - 穩定的網路身份:pod-0, pod-1, pod-2(Deployment 使用隨機後綴)
  - 有序部署:按 0 → 1 → 2 順序啟動
  - 穩定的持久化儲存:每個 Pod 各自分配 PVC
  - 需要 Headless Service

使用場景:資料庫、分散式系統(MySQL、Redis Cluster、Kafka)

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  serviceName: mysql-headless  # Headless Service 名稱
  replicas: 3
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:8.0
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 10Gi

4. 速查表

任務指令
建立 Deploymentkubectl create deploy NAME --image=IMG --replicas=N
更新映像檔kubectl set image deploy/NAME CONTAINER=IMAGE:TAG
回滾kubectl rollout undo deploy/NAME
檢查 DaemonSetkubectl get daemonset -A
檢查 StatefulSetkubectl get statefulset

5. 練習題

Q1:使用 Deployment strategy type: Recreate 時,部署過程中會發生什麼?

  • A) 新舊 Pod 同時運行
  • B) 所有舊 Pod 先停止,然後才啟動新 Pod — 會有停機時間 ✓
  • C) 一次更新一個 Pod
  • D) 流量自動路由到新 Pod

解析:Recreate 策略會停止所有舊 Pod 後才啟動新 Pod。RollingUpdate 可以零停機更新,但如果應用程式不支援新舊版本同時運行,則需要使用 Recreate。

Q2:DaemonSet 的 Pod 如何排程?

  • A) kube-scheduler 選擇節點
  • B) DaemonSet controller 自動在每個節點放置一個 Pod ✓
  • C) 使用者需要手動設定 nodeSelector
  • D) 隨機分配到節點

解析:DaemonSet controller 自動在每個節點放置一個 Pod。當新節點加入時,會自動建立 Pod。可以使用 toleration 來在控制平面節點上也放置 Pod。

Q3:StatefulSet 為什麼需要 serviceName 欄位?

  • A) 用於負載平衡
  • B) 需要 Headless Service 為每個 Pod 提供 DNS 記錄(pod-0.serviceName) ✓
  • C) 用於啟用自動擴展
  • D) 用於儲存佈建

解析:StatefulSet 的每個 Pod 都有穩定的 DNS 名稱(例:mysql-0.mysql-headless.namespace.svc.cluster.local)。這需要 Headless Service(clusterIP: None)。serviceName 參照這個 Headless Service。