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. 速查表
| 任務 | 指令 |
|---|---|
| 建立 Deployment | kubectl create deploy NAME --image=IMG --replicas=N |
| 更新映像檔 | kubectl set image deploy/NAME CONTAINER=IMAGE:TAG |
| 回滾 | kubectl rollout undo deploy/NAME |
| 檢查 DaemonSet | kubectl get daemonset -A |
| 檢查 StatefulSet | kubectl 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。