← 返回上一頁
Kubernetes

Kubernetes Deployment 完整攻略:滾動更新、擴縮容與回滾一次搞懂

本頁目錄
Kubernetes Deployment 滾動更新策略總覽

前言

在實際的生產環境中,我們幾乎不太可能只跑一個 Pod 來承載線上服務。當流量變大、需要版本更新時,如何做到多副本部署、水平擴縮容、不停機滾動更新?這些需求正好就是 Kubernetes 中 Deployment 這個資源物件存在的意義。

我個人在剛接觸 K8s 的時候,對 Deployment 的認識僅止於「幫我把 Pod 跑起來」,但深入之後才發現它背後的設計遠比想像中精巧。這篇文章就來跟大家聊聊我對 Deployment 的理解,從基本結構到滾動更新、擴縮容、回滾機制,一次講清楚。

Deployment 在 K8s 中的角色

Deployment 是 Kubernetes 裡用來管理無狀態應用的核心資源。你可以把它想像成一個牧場管理員——它底下管理的 Pod 就像一頭頭牲畜,如果哪一頭出了問題,管理員會自動補上新的,維持數量穩定。

不過 Deployment 並不是直接操控 Pod 的,中間其實還有一層叫做 ReplicaSet。Deployment 透過 ReplicaSet 來達成水平擴容與滾動更新等功能,而我們平時不太需要直接碰 ReplicaSet,它比較像是幫 Deployment 跑腿的角色。

以下用表格整理它們的關係:

資源 角色 說明
Deployment 管理者 定義應用的期望狀態(副本數、映像檔版本、更新策略等)
ReplicaSet 執行者 根據 Deployment 的指示,維持指定數量的 Pod 副本
Pod 工作單元 實際跑容器的最小單位

Deployment YAML 範例解析

下面是一份我常用的 Deployment YAML 範本,涵蓋了滾動更新策略、初始化容器、健康探針等常見配置:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-web-deployment
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  selector:
    matchLabels:
      app: my-web
  template:
    metadata:
      labels:
        app: my-web
    spec:
      initContainers:
      - name: init-setup
        image: ********/init-setup:latest
      containers:
      - name: my-web
        image: ********/my-web:latest
        ports:
        - containerPort: 80
        imagePullPolicy: Always
        livenessProbe:
          httpGet:
            path: /healthz
            port: 80
          initialDelaySeconds: 3
          periodSeconds: 5
        readinessProbe:
          httpGet:
            path: /readiness
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 5

幾個重點欄位說明:

欄位 用途
replicas 指定要維持多少個 Pod 副本
strategy.rollingUpdate.maxSurge 滾動更新時,最多可以額外多建幾個 Pod
strategy.rollingUpdate.maxUnavailable 滾動更新時,最多允許幾個 Pod 不可用
imagePullPolicy: Always 每次啟動都拉最新映像檔(也可設為 IfNotPresent 或 Never)
livenessProbe 存活探針,偵測容器是否還在正常運作
readinessProbe 就緒探針,偵測容器是否準備好接收流量

寫好 YAML 後,執行以下指令就能部署:

kubectl apply -f my-web-deployment.yaml

滾動更新(Rolling Update)

這是我覺得 Deployment 最優雅的設計之一。當我們更新了 Pod 模板(例如換了映像檔版本),Deployment 不會粗暴地把所有 Pod 一次砍掉重建,而是採用逐步替換的方式。

具體流程大致如下:

  1. Deployment 偵測到 Pod 模板有變更
  2. 建立一個新的 ReplicaSet(對應新版映像檔)
  3. 新 ReplicaSet 啟動一個新 Pod,確認就緒後,舊 ReplicaSet 刪除一個舊 Pod
  4. 重複步驟 3,直到所有 Pod 都替換成新版本
  5. 舊的 ReplicaSet 保留(不管理任何 Pod),以便後續回滾

Kubernetes Rolling Update 滾動更新流程圖

Kubernetes 滾動更新流程示意(圖片來源:spacelift.io)

這種方式確保了在整個更新過程中,始終有足夠數量的 Pod 在服務,使用者幾乎不會感受到中斷——這就是所謂的零停機部署

Kubernetes Deployment 滾動更新策略總覽

Deployment 滾動更新策略總覽(圖片來源:spacelift.io)

水平擴縮容(Horizontal Scaling)

水平擴縮容的概念很直覺:就是增減 Pod 的數量。假設線上流量突然暴增,我們想把副本數從 3 擴到 5,有兩種方式:

方式一:修改 YAML 後重新 apply

# 將 replicas 改為 5 後執行
kubectl apply -f my-web-deployment.yaml

方式二:直接用指令調整

kubectl scale deployment my-web-deployment --replicas=5 -n my-namespace

執行後,Deployment 對應的 ReplicaSet 就會自動補上 2 個新的 Pod,非常方便。反之,要縮容的話就把數字調小即可。

回滾(Rollback)

生產環境最怕的就是更新出包。還好 Deployment 內建了回滾機制,因為每次滾動更新時,舊的 ReplicaSet 都還在,裡面保存了完整的配置資訊。

常用的回滾指令如下:

# 查看部署歷史版本
kubectl rollout history deployment my-web-deployment -n my-namespace

# 查看某個版本的詳細資訊
kubectl rollout history deployment my-web-deployment --revision=2 -n my-namespace

# 回滾到指定版本
kubectl rollout undo deployment my-web-deployment --to-revision=2 -n my-namespace

這讓我們在出問題時能快速回到上一個穩定版本,大幅降低了線上事故的風險。

初始化容器與健康探針

在 Pod 的定義中,除了主要的應用容器,還可以配置初始化容器(initContainers)健康探針(Probes)

初始化容器

initContainers 會在主容器啟動之前執行。如果有多個初始化容器,它們會按順序逐一執行,全部成功退出後主容器才會啟動。常見用途包括:等待相依服務就緒、資料庫 migration、下載設定檔等。

Liveness 與 Readiness 探針

這兩個探針是 K8s 確保服務穩定性的關鍵機制:

探針類型 偵測目的 失敗後果
Liveness Probe 容器是否還活著 K8s 會重啟該容器
Readiness Probe 容器是否準備好接收流量 該 Pod 會被從 Service 的負載均衡中移除,不再接收流量

兩者搭配使用,可以有效避免流量打到還沒準備好或已經異常的容器上,是維運穩定性的好幫手。

小結

雖然 Deployment 是 Kubernetes 裡相對基礎的資源,但它涵蓋的功能——多副本管理、滾動更新、水平擴縮容、版本回滾——每一個都是日常維運的必備技能。我自己的經驗是,把 Deployment 搞透了,後面再去理解 StatefulSet、DaemonSet 等進階資源會輕鬆很多。

希望這篇整理對你有幫助,有任何問題歡迎留言交流!

參考資料:

分享這篇
X LinkedIn Facebook Hacker News Reddit

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料