Concepts - Workload Management - deployments
Deployment 是用來幫助執行 stateless 的 pod
stateless:
- 在 pod 的 replica 之間 不存在任何關聯
- pod 在 start/restart/stop 後也不存在前後關聯
簡單來說 每個 pod 都是個獨立運作的個體
舉例來說 web-server 就適合使用 deployment
Creating a Deployment
在前面我們使用 範例去新增一個 deployment
|
|
為了方便說明
我直接使用註解做講解
有一些功能尚未介紹到 就請大家邊看邊學 後面會再做深入介紹
|
|
實際操作可以使用官方提供的 manifest 新增一個 deployment
|
|
然後觀察狀態
|
|
deployment 就是其中一種 workload resource or 又稱 kind
nginx-deployment 稱之為 object
記得前面有提到, 我們不直接建立 pod 而是透過 workload resources
這個 yaml 是宣告建立一個 kind 是 deployment 的 object
.spec.template
則是建立 ReplicaSet, 另一個 workload resources
ReplicaSet 則會建立 pod
基本上我們不會直接使用 ReplicaSet
關係如下
flowchart TD A[Deployment] -- 控制與管理 --> B(ReplicaSet) B -- 建立並維持副本數量 --> C((Pod 1...n))
關於 label
k8s 的 label 是很重要的觀念
label 用於建立 k8s 不同 object 之間的關係
藉由指定 label 就可以到找對應的 object (一或多個)
這邊來說明這裡所用到的 label
.metadata.labels
是提供給要使用 deplyment 的人使用
舉例 只讓 kubectl 顯示符合 label 的 deplyment object
$ k get deplyment --selector=app=nginx
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 13m
.spec.selector.matchLabels
告訴 ReplicaSet 如何找到 pod 去納管
.spec.template.metadata.labels
指定建立 pod 時該有的 label
READY: 目標要三個 replica 並都已正常啟動 UP-TO-DATE: 顯示如果有任何 pod 已更新完成(如有進行 rolling update 可以觀察此項目)
如要觀察詳細資訊 就使用 describe
$ k describe deploy nginx-deployment
Name: nginx-deployment
Namespace: default
CreationTimestamp: Sat, 21 Jun 2025 00:53:33 +0000
Labels: app=nginx
Annotations: deployment.kubernetes.io/revision: 2
Selector: app=nginx
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=nginx
Annotations: kubectl.kubernetes.io/restartedAt: 2025-06-21T00:58:03Z
Containers:
nginx:
Image: nginx:1.14.2
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Node-Selectors: <none>
Tolerations: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: nginx-deployment-647677fc66 (0/0 replicas created)
NewReplicaSet: nginx-deployment-756d74bd9 (3/3 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 5m59s deployment-controller Scaled up replica set nginx-deployment-647677fc66 from 0 to 3
Normal ScalingReplicaSet 89s deployment-controller Scaled up replica set nginx-deployment-756d74bd9 from 0 to 1
Normal ScalingReplicaSet 88s deployment-controller Scaled down replica set nginx-deployment-647677fc66 from 3 to 2
Normal ScalingReplicaSet 88s deployment-controller Scaled up replica set nginx-deployment-756d74bd9 from 1 to 2
Normal ScalingReplicaSet 87s deployment-controller Scaled down replica set nginx-deployment-647677fc66 from 2 to 1
Normal ScalingReplicaSet 87s deployment-controller Scaled up replica set nginx-deployment-756d74bd9 from 2 to 3
Normal ScalingReplicaSet 86s deployment-controller Scaled down replica set nginx-deployment-647677fc66 from 1 to 0
Updating a Deployment
這邊操作有印象即可
實務來說 我們不會這樣使用
通常會使用 IaC 來進行操作
修改 image tag
|
|
這時 deployment 會幫我們進行 rolling update
非常的簡單
那如果我設定有問題的 image 呢?
|
|
你還是會看到 deployment 顯示 image updated
但是去看 pod 的狀態
|
|
因為這 tag 並不存在
因此 pod STATUS 為 ErrImagePull
deployment 會因為 pod 起不來 因此沒有繼續更新
在新的 pod 尚未能運作前, deployment 並不會把舊的 pod 停掉
因此一個簡易的 canary deploy 就出現了
但也要注意一件事當我們對 deplyment set image 時
並不會拿到一個 fail 的狀態
因為會需要不斷的使用 get pod 觀察 update 狀態
這個問題可以透過 argoCD 解決
另外從 flow 來看
deployment 會先建立另一個 ReplicaSet
並逐步調整兩個 ReplicaSet 的 pod 數量
藉此來 rolling upgrade
graph TD A[Deployment] -- 控制與管理 --> B1(ReplicaSet) A[Deployment] -- 控制與管理 --> B2(ReplicaSet) B1 -- 建立並維持副本數量 --> C1(("tag 1.16.1 Pod 1...n-x")) B2 -- 建立並維持副本數量 --> C2(("tag 1.16.2 Pod 1...x"))
這樣也能夠理解 為什麼中間還要再過一層 ReplicaSet 了
Rolling Back a Deployment update
這邊操作有印象即可
實務來說 我們不會這樣使用
通常會使用 IaC 來進行操作
k8s 會紀錄你的變更紀錄 (預設 10 份)
你可以使用
|
|
Scaling a Deployment
如何修改範例的 replica 數量
可以使用
|
|
但平常我們都會採用 auto scale
因此人工 scale 只有在特殊狀況使用
比如說我想暫時把 deploymnet 停了
就可以使用 --replicas=0
而不必 delete replica
|
|
Failed Deployment
前面有故意將 images tag 改為 1.16.123
並看到 pod 出現 ErrImagePull
如果你使用 k describe pod
可以看到更多細節
這邊就不贅述所有狀態了
基本上養成善用 describe
來進行 debug 就是了
update Strategy
預設情況下 k8s 採用 RollingUpdate
也就是逐步更新
可以使用 Recreate
來一次行更新所有 pod
Rolling Update Deployment strategy
RollingUpdate 可以修改他的行為
default 情況下是
maxUnavailable: default 25%
允許 pod stop 的量
可以用絕對值 or 百分比
當開始 rolling upgrade 時
舊的 replica 會馬上停掉 25%
maxSurge: default 25%
允許 pod start 的量
可以用絕對值 or 百分比
當開始 rolling upgrade 時
新增的 replica 會先啟動 25%
因此只要控制 maxUnavailable, maxSurge 即可控制 rolling upgrade 的流程