markdown-it
demo
Delete
Submit
clear
permalink
下面我把 **Kubernetes Deployment** 的概念、常用欄位、範例 YAML、常見操作指令、進階設定(滾動更新、probe、HPA、PDB、回滾)和最佳實務整理成一個實用手冊,帶註解與範例,方便你直接複製貼上、實作與調整。 # 1) Deployment 簡介(一句話) Deployment 是 Kubernetes 用來 **管理一組 Pod(通常是無狀態應用)與其 ReplicaSet** 的控制器,讓你以「聲明式(declarative)」方式指定期望狀態,且支援受控更新(rolling updates)、回滾等功能。([Kubernetes][1]) --- # 2) 最重要的欄位(高階說明) * `apiVersion: apps/v1` / `kind: Deployment` / `metadata`:基本識別。 * `spec.replicas`:期望的 Pod 數量。 * `spec.selector`:**必填**且(在 apps/v1)**建立後不可變**,必須和 `spec.template.metadata.labels` 相符(否則 API 會拒絕)。這個 selector 決定哪些 Pod 屬於這個 Deployment。([Kubernetes][2]) * `spec.template`:描述 Pod 模板(容器、ports、env、probes、resources…)。 * `spec.strategy`:部署策略,常見有 `RollingUpdate`(預設)與 `Recreate`;`RollingUpdate` 有 `maxSurge`、`maxUnavailable` 用來調整更新時的速度/可用性。從 Kubernetes 1.16 起,`maxSurge` / `maxUnavailable` 的預設值已改為 `25%`(可用整數或百分比)。([Kubernetes][3]) --- # 3) Annotated 範例 YAML(最常見的 minimal + production-oriented fields) ```yaml apiVersion: apps/v1 # Deployment 所屬的 API 版本(固定為 apps/v1) kind: Deployment # 資源種類:Deployment(控制器,用於管理 Pod 與 ReplicaSet) metadata: name: myapp-deployment # Deployment 的名稱(唯一識別) labels: # 自定義標籤,可用於篩選或分類 app: myapp # 標籤名稱與值(與 selector 及 Pod labels 對應) spec: # Deployment 的規格(宣告期望狀態) replicas: 3 # 期望同時執行的 Pod 副本數(副本控制) selector: # Deployment 如何挑選它要管理的 Pod(非常重要!) matchLabels: # matchLabels 必須與下方 template.metadata.labels 一致 app: myapp # 若不一致,K8s 會拒絕建立 Deployment strategy: # 定義更新策略(Deployment 如何滾動更新 Pod) type: RollingUpdate # 預設為 RollingUpdate(逐步替換舊 Pod) rollingUpdate: # 滾動更新的參數設定 maxSurge: 25% # 允許暫時多出最多 25% 的 Pod(相對於 replicas 數) maxUnavailable: 25% # 更新期間最多可有 25% 的 Pod 不可用 minReadySeconds: 5 # Pod 成功啟動並通過 ReadinessProbe 後,必須維持 Ready 狀態至少 5 秒才算穩定 revisionHistoryLimit: 10 # 保留最多 10 個舊版 ReplicaSet,以支援回滾(預設 10) template: # 定義 Pod 的模板(Pod 會依這裡建立) metadata: labels: app: myapp # Pod 的標籤(必須與 selector.matchLabels 對應) spec: # Pod 的詳細規格(與單獨的 Pod manifest 類似) containers: # 定義容器列表(Pod 內可有多個容器) - name: myapp-container # 容器名稱(在同一 Pod 內唯一) image: myregistry/myapp:1.2.3 # 使用的映像檔(建議用固定版本號,不用 latest) imagePullPolicy: IfNotPresent # (可選)若本地無映像才拉取,可改成 Always 強制更新 ports: - containerPort: 8080 # 容器內部服務的 port(對應程式監聽的埠) env: # (可選)環境變數設定 - name: ENVIRONMENT value: production resources: # 設定 CPU / Memory 資源限制(非常建議) requests: # Scheduler 會依 requests 判斷要放在哪個節點 cpu: "100m" # 要求最少 0.1 顆 CPU memory: "128Mi" # 要求最少 128MB 記憶體 limits: # 容器最大可用資源(超過會被限制或 OOMKilled) cpu: "500m" # 最多 0.5 顆 CPU memory: "512Mi" # 最多 512MB 記憶體 readinessProbe: # 檢查應用程式是否「已準備好」接收流量 httpGet: # 以 HTTP GET 方式檢查 path: /healthz # 檢查的路徑 port: 8080 # 檢查的埠號(對應 containerPort) initialDelaySeconds: 5 # 容器啟動後等待幾秒才開始檢查 periodSeconds: 10 # 每 10 秒檢查一次 timeoutSeconds: 2 # (可選)每次檢查的逾時時間(預設 1 秒) failureThreshold: 3 # (可選)連續失敗幾次才算不 Ready successThreshold: 1 # (可選)成功一次即恢復 Ready 狀態 livenessProbe: # 檢查容器是否「活著」(避免程式卡死) httpGet: path: /live # 用另一個健康檢查端點 port: 8080 initialDelaySeconds: 30 # 延遲 30 秒才開始檢查(確保應用啟動完成) periodSeconds: 10 # 每 10 秒檢查一次 timeoutSeconds: 2 failureThreshold: 3 # 若連續 3 次檢查失敗則重啟容器 startupProbe: # (可選)應用啟動很慢時使用(先用 startupProbe,成功後才啟動其他 probe) httpGet: path: /startup port: 8080 failureThreshold: 30 # 最多允許 30 次失敗 periodSeconds: 10 # 每 10 秒檢查一次 → 最多容忍 5 分鐘啟動時間 volumeMounts: # (可選)掛載外部 volume 到容器內 - name: app-config mountPath: /etc/myapp volumes: # 定義可被 Pod 內容器共用的 volume - name: app-config configMap: # 來源是 ConfigMap name: myapp-config # ConfigMap 名稱(需事先建立) imagePullSecrets: # 若要拉 private registry 的映像 - name: my-registry-secret # 指向已建立的 Secret(type=kubernetes.io/dockerconfigjson) securityContext: # Pod 層級的安全性設定 runAsNonRoot: true # 強制容器以非 root 身份執行 fsGroup: 2000 # 設定檔案系統群組 ID(有助於卷權限) restartPolicy: Always # Pod 的重啟策略(Deployment 一定是 Always) ``` (上面是常見組合,可以依照你的應用調整 probes、resources、image tag 等) --- # 4) 常用 kubectl 工作流(快速 Cheat-sheet) * 建立/套用:`kubectl apply -f deployment.yaml` * 看資源:`kubectl get deployments` / `kubectl describe deployment myapp-deployment` * 檢查 rollout 狀態:`kubectl rollout status deployment/myapp-deployment`。`kubectl rollout` 可管理 rollout(查看歷史、回滾等)。([Kubernetes][4]) * 查看 rollout 歷史:`kubectl rollout history deployment/myapp-deployment` * 回滾(到上一版):`kubectl rollout undo deployment/myapp-deployment` * 更新容器映像(無 downtime 的方式):`kubectl set image deployment/myapp-deployment myapp-container=myregistry/myapp:1.2.4`(會觸發 rolling update) * 強制重啟(讓 Pod 逐一重建):`kubectl rollout restart deployment/myapp-deployment`(等同觸發一個新的 rollout)。([Kubernetes][5]) * 縮放:`kubectl scale deployment/myapp-deployment --replicas=5` * 快速自動縮放(建立 HPA):`kubectl autoscale deployment myapp-deployment --min=2 --max=10 --cpu-percent=60`(會建立 HorizontalPodAutoscaler)([Kubernetes][6]) --- # 5) 健康檢查 (liveness vs readiness vs startup) * **Liveness probe**:決定 container 是否「死掉」需要重啟(避免 hung)。([Kubernetes][7]) * **Readiness probe**:決定 Pod 是否「已就緒」能接受流量(影響 Service 的 endpoint)。 * **Startup probe**:app 啟動很慢時先用 startupProbe 延後 liveness 判斷,避免啟動期間被重啟。 > 設定正確的 readinessProbe 很重要,因為 rolling update 會等到 new Pod 被標示為 Ready 才會把舊 Pod 刪掉(依 `maxSurge`/`maxUnavailable` 規則)。([Kubernetes][8]) --- # 6) Rolling update 與策略要點 * `RollingUpdate`(預設):用 `maxSurge`(可臨時多出的 Pod 數)與 `maxUnavailable`(更新期間最多不可用的 Pod)平衡速度與可用性。預設常為 `25%`(詳細行為與版本有差異,請留意 Kubernetes 版本)— 若想零 downtime,可考慮 `maxUnavailable: 0` 並把 `maxSurge` 設為 `1`(或更高)。([Kubernetes][3]) * `Recreate`:先把舊 Pod 全下線再建立新 Pod(會有 downtime),適用於無法同時跑舊/新版的場景。 * 注意:`spec.selector` 一旦建立後不可變(如果要改 selector,通常要刪掉再重建 Deployment)。因此建立時 selector 與 template labels 要小心規劃。([Kubernetes][2]) --- # 7) 進階:自動擴縮、流量分流與無停機部署 * **HPA(Horizontal Pod Autoscaler)**:根據 CPU/memory 或自訂 metrics 自動調整 Deployment replicas(需要 metrics server / API 支援)。用 `kubectl autoscale` 快速建立,或以 HPA 資源 manifest 管理。([Kubernetes][6]) * **Canary / Blue-Green**:Deployment 本身支援基本滾動更新;更進階的 canary/blue-green 通常需搭配 Service/Ingress 修改流量、或使用更專門的 delivery 工具(Argo Rollouts、Flagger、Istio/Service Mesh 等)。([Codefresh][9]) * **PodDisruptionBudget (PDB)**:控制自願性中斷(例如 node drain、cluster upgrade)期間最少要保留多少 Pod,以避免在維護時造成過大影響。([Kubernetes][10]) --- # 8) 常見問題與陷阱(小心會踩雷) * **selector 不匹配 template labels → 會被 API 拒絕或造成控制器行為不正確**(建立時特別小心)。([Kubernetes][11]) * **用 `:latest` 標籤在 production 不安全**:因為 image tag 不可辨識版本,建議在 CI/CD 中使用 immutable tags(如 git hash、semver)。 * **忘了 readiness probe**:會導致 Service 把尚未可用的 Pod 當作可用而分流流量,造成錯誤或 502。([Kubernetes][7]) * **resource requests/limits 未設定**:scheduler 無法正確放置 Pod,或在節點壓力下遭到 OOMKill。 * **認知 `maxSurge` / `maxUnavailable` 為百分比時會向上取整**(1 個 replica 時 25% 會向上成為 1),可能導致你看到超過預期的 Pod 數量。([Kubernetes][3]) --- # 9) 範例操作流程(CI/CD 常見) 1. CI 建出新的 image 並打上版本號(例如 `v2025-10-09-abc123`)。 2. CI 更新 `image:` 字段或 patch deployment(`kubectl set image` 或 更新 manifest 並 `kubectl apply`)。 3. 觀察 rollout:`kubectl rollout status deployment/myapp-deployment`。若有問題,`kubectl rollout undo` 回滾。([Kubernetes][4]) --- # 10) 推薦閱讀(官方 / 深入) * Deployment 概念與用法(官方 docs)。([Kubernetes][1]) * kubectl rollout / restart 文件(命令與用法)。([Kubernetes][4]) * Liveness / Readiness / Startup probes(設定細節與範例)。([Kubernetes][8]) * Horizontal Pod Autoscaler(HPA):自動擴縮說明與 walkthrough。([Kubernetes][6]) --- [1]: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/?utm_source=chatgpt.com "Deployments" [2]: https://kubernetes.io/docs/reference/using-api/deprecation-guide/?utm_source=chatgpt.com "Deprecated API Migration Guide" [3]: https://kubernetes.io/blog/2018/04/30/zero-downtime-deployment-kubernetes-jenkins/?utm_source=chatgpt.com "Zero-downtime Deployment in Kubernetes with Jenkins" [4]: https://kubernetes.io/docs/reference/kubectl/generated/kubectl_rollout/?utm_source=chatgpt.com "kubectl rollout" [5]: https://kubernetes.io/docs/reference/kubectl/generated/kubectl_rollout/kubectl_rollout_restart/?utm_source=chatgpt.com "kubectl rollout restart" [6]: https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/?utm_source=chatgpt.com "Horizontal Pod Autoscaling" [7]: https://kubernetes.io/docs/concepts/configuration/liveness-readiness-startup-probes/?utm_source=chatgpt.com "Liveness, Readiness, and Startup Probes" [8]: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/?utm_source=chatgpt.com "Configure Liveness, Readiness and Startup Probes" [9]: https://codefresh.io/learn/kubernetes-deployment/?utm_source=chatgpt.com "Kubernetes Deployment Strategies: The Definitive Guide" [10]: https://kubernetes.io/docs/tasks/run-application/configure-pdb/?utm_source=chatgpt.com "Specifying a Disruption Budget for your Application" [11]: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/?utm_source=chatgpt.com "ReplicaSet"
html
source
debug
Fork me on GitHub