1. 簡介
一個 Deployment 為 Pods
和 ReplicaSets
提供宣告式的更新能力。
使用者負責描述 Deployment 中的 目標狀態,而 Deployment 控制器(Controller)以受控速率更改實際狀態, 使其變為期望狀態。你可以定義 Deployment 以建立新的 ReplicaSet,或刪除現有 Deployment, 並通過新的 Deployment 收養其資源。
ReplicaSet 的目的是維護一組在任何時候都處於執行狀態的 Pod 副本的穩定集合。 因此,它通常用來保證給定數量的、完全相同的 Pod 的可用性。
也就是 Deployment 通過管理 ReplicaSet 來確保任何時間都有指定數量的 Pod 副本在執行。
2. quick start
2.1 建立deploy
如果沒有現成的模板,可以使用 --dry-run 快速生成一個deploy資源模板
$ kubectl create deploy nginx-test --image=nginx --dry-run=client --replicas=3 -oyaml -n test1
# 輸出內容如下
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: nginx-test
name: nginx-test
namespace: test1
spec:
replicas: 3
selector:
matchLabels:
app: nginx-test
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: nginx-test
spec:
containers:
- image: nginx
name: nginx
resources: {}
status: {}
新建一個deploy模板 deploy-nginx.yaml
,內容如下:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
# 自定義標籤
app: nginx-deploy-test
# 資源名稱
name: nginx-test-1
namespace: test1
spec:
# pod 副本數量
replicas: 3
# 模板選擇器
selector:
matchLabels:
# 選擇下方宣告的 template
app: nginx-test
template:
metadata:
labels:
app: nginx-test
spec:
containers:
- image: nginx
name: nginx
建立deploy
$ kubectl create -f deploy-nginx.yaml
在該例中:
- 建立名為
nginx-test-1
(由.metadata.name
欄位標明)的 deployment - 該deployment建立三個(由
replicas
欄位標明)Pod副本 selector
欄位定義 Deployment 如何查詢要管理的 Pods。 在這裡,選擇在 Pod 模板中定義的標籤(app: nginx-test
)。 不過,更復雜的選擇規則是也可能的,只要 Pod 模板本身滿足所給規則即可。
template
欄位包含以下子欄位:- Pod 被使用
labels
欄位打上app: nginx-test
標籤。 - Pod 模板約定(即
.template.spec
欄位) Podsnginx
容器。 - 建立一個容器並使用
name
欄位將其命名為nginx
。
- Pod 被使用
說明:
spec.selector.matchLabels
欄位是 {key,value}
鍵值對對映。 在 matchLabels
對映中的每個 {key,value}
對映等效於 matchExpressions
中的一個元素, 即其 key
欄位是 “key”,operator
為 “In”,values
陣列僅包含 “value”。 在 matchLabels
和 matchExpressions
中給出的所有條件都必須滿足才能匹配。
2.2 檢視deploy
檢視deploy 基本資訊
# kubectl get -f deploy-nginx.yaml
$ kubectl get deploy -n test1
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-test-1 3/3 3 3 4m20s
檢視deploy 詳細資訊
# kubectl get -f deploy-nginx.yaml -o wide
$ kubectl get deploy -n test1 -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx-test-1 3/3 3 3 4m54s nginx nginx app=nginx-test
檢視deploy 詳情資訊
# kubectl describe deploy/nginx-test-1 -n test1
$ kubectl describe -f deploy-nginx.yaml
Name: nginx-test-1
Namespace: test1
CreationTimestamp: Sun, 12 Dec 2021 22:38:12 +0800
Labels: app=nginx-deploy-test
Annotations: deployment.kubernetes.io/revision: 1
Selector: app=nginx-test
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-test
Containers:
nginx:
Image: nginx
Port: <none>
Host Port: <none>
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: nginx-test-1-795d659f45 (3/3 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 6m58s deployment-controller Scaled up replica set nginx-test-1-795d659f45 to 3
檢視pod情況
$ kubectl get po -n test1
NAME READY STATUS RESTARTS AGE
nginx-test-1-795d659f45-7rlq7 1/1 Running 0 15m
nginx-test-1-795d659f45-dfjfb 1/1 Running 0 15m
nginx-test-1-795d659f45-m45qn 1/1 Running 0 15m
檢視deploy上線狀態
$ kubectl rollout status deploy/nginx-test-1 -n test1
deployment "nginx-test-1" successfully rolled out
2.3 修改deploy
說明: 僅當 Deployment Pod 模板(即
.spec.template
)發生改變時,例如模板的標籤或容器映象被更新, 才會觸發 Deployment 上線。 其他更新(如對 Deployment 執行擴縮容的操作)不會觸發上線動作。
-
直接修改資源模板,修改完直接apply即可
$ kubectl apply -f deploy-nginx.yaml
-
使用命令修改,修改完儲存即可
$ kubectl edit deploy/nginx-test-1 -n test1
-
修改映象版本
- --record=true 記錄當前操作,後續會用到
$ kubectl set image deploy/nginx-test-1 nginx=nginx:1.16.1 -n test1 --record=true
2.4 刪除deploy
-
使用命令刪除
$ kubectl delete deploy/nginx-test-1 -n test1
-
使用資原始檔
$ kubectl delete -f deploy-nginx.yaml
3. 更新服務版本
3.1 建立deploy
deploy-nginx.yaml
deploy 模板資訊如下:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-deploy-test
name: nginx-test-1
namespace: test1
spec:
replicas: 3
selector:
matchLabels:
app: nginx-test
template:
metadata:
labels:
app: nginx-test
spec:
containers:
- image: nginx:1.16.1
name: nginx
3.2 修改deploy檔案更新
# 修改模板檔案中的映象版本號
$ sed -i 's/nginx:1.16.1/nginx:latest/g' deploy-nginx.yaml
# 應用修改後的模板檔案
# --record的作用是將當前命令記錄到 revision 記錄中,這樣就可以知道每個 revison 對應的是哪個配置檔案。
$ kubectl apply -f deploy-nginx.yaml --record
我們從圖中可以看到pod執行過程是等待新的pod啟動完成,在進行銷燬舊的pod,這樣就完成了叢集的滾動更新工作
更新完成後我們也可以檢視一下迭代資訊和修訂歷史詳細資訊
3.2 使用edit命令更新
$ kubectl edit deploy/nginx-test-1 -n test1
deployment.apps/nginx-test-1 edited
一般臨時修改一下部署資訊會使用一下edit。
一般不太推薦使用edit進行編輯,推出即儲存。雖然版本更新成功了,history也有保留,但是最終的修改記錄沒有持久化到模板檔案中。
3.3 使用set image 命令更新
# nginx=nginx:1.16.1 <container-name>=<image-name>:<version>
$ kubectl set image deploy/nginx-test-1 -n test1 nginx=nginx:1.16.1 --record
能比edit更新強點,至少可以很清楚的在history中檢視版本更新的情況
4. 回滾服務版本
我們使用上面的更新應用時k8s都會記錄一個revision(版本),這樣我們就可以通過這個版本記錄回滾到特定的版本中
-
回滾到上一個版本
$ kubectl rollout undo deploy/nginx-test-1 -n test1
-
回滾到指定版本
$ kubectl rollout undo deploy/nginx-test-1 --to-revision=3 -n test1
rollout命令引數如下
$ kubectl rollout -h
Manage the rollout of a resource.
Valid resource types include:
* deployments
* daemonsets
* statefulsets
Examples:
# Rollback to the previous deployment
kubectl rollout undo deployment/abc
# Check the rollout status of a daemonset
kubectl rollout status daemonset/foo
Available Commands:
history 顯示 rollout 歷史
pause 標記提供的 resource 為中止狀態
restart Restart a resource
resume 繼續一個停止的 resource
status 顯示 rollout 的狀態
undo 撤銷上一次的 rollout
Usage:
kubectl rollout SUBCOMMAND [options]
預設配置下,k8s 只會保留最近的幾個 revision,可以在 Deployment 配置檔案中通過 revisionHistoryLimit
屬性增加 revision
數量。(同時rs和我們rollout中記錄的版本號相同,可以理解為rollout中顯示的REVISION
版本號實際上就是rs中的版本)
revisionHistoryLimit(歷史版本記錄):Deployment revision history儲存在它控制的ReplicaSets中。預設儲存記錄10個 .spec.revisionHistoryLimit 是一個可選配置項,用來指定可以保留的舊的ReplicaSet數量。
該理想值取決於心Deployment的頻率和穩定性。如果該值沒有設定的話,預設所有舊的Replicaset或會被保留,將資源儲存在etcd中,是用kubectl get rs檢視輸出。
每個Deployment的該配置都儲存在ReplicaSet中,然而,一旦刪除的舊的RepelicaSet,Deployment就無法再回退到那個revison了。
如果將該值設定為0,所有具有0個replica的ReplicaSet都會被刪除。在這種情況下,新的Deployment rollout無法撤銷,因為revision history都被清理掉了。 PS:為了儲存版本升級的歷史,需要再建立Deployment物件時,在命令中使用"record"選項
一般配合revisionHistoryLimit使用的strategy (更新策略)
strategy(更新策略):
.spec.strategy 指定新的Pod替換舊的Pod的策略。 .spec.strategy.type 可以是"Recreate"或者是 "RollingUpdate"。"RollingUpdate"是預設值。
Recreate: 重建式更新,就是刪一個建一個。類似於ReplicaSet的更新方式,即首先刪除現有的Pod物件,然後由控制器基於新模板重新建立新版本資源物件。
rollingUpdate:滾動更新,簡單定義 更新期間pod最多有幾個等。可以指定maxUnavailable 和 maxSurge 來控制 rolling update 程式。
maxSurge:.spec.strategy.rollingUpdate.maxSurge 是可選配置項,用來指定可以超過期望的Pod數量的最大個數。該值可以是一個絕對值(例如5)或者是期望的Pod數量的百分比(例如10%)。當MaxUnavailable為0時該值不可以為0。通過百分比計算的絕對值向上取整。預設值是1。
例如,該值設定成30%,啟動rolling update後新的ReplicatSet將會立即擴容,新老Pod的總數不能超過期望的Pod數量的130%。舊的Pod被殺掉後,新的ReplicaSet將繼續擴容,舊的ReplicaSet會進一步縮容,確保在升級的所有時刻所有的Pod數量和不會超過期望Pod數量的130%。
maxUnavailable:.spec.strategy.rollingUpdate.maxUnavailable 是可選配置項,用來指定在升級過程中不可用Pod的最大數量。該值可以是一個絕對值(例如5),也可以是期望Pod數量的百分比(例如10%)。通過計算百分比的絕對值向下取整。 如果.spec.strategy.rollingUpdate.maxSurge 為0時,這個值不可以為0。預設值是1。
例如,該值設定成30%,啟動rolling update後舊的ReplicatSet將會立即縮容到期望的Pod數量的70%。新的Pod ready後,隨著新的ReplicaSet的擴容,舊的ReplicaSet會進一步縮容確保在升級的所有時刻可以用的Pod數量至少是期望Pod數量的70%。 PS:maxSurge和maxUnavailable的屬性值不可同時為0,否則Pod物件的副本數量在符合使用者期望的數量後無法做出合理變動以進行更新操作。
在配置時,使用者還可以使用Deployment控制器的spec.minReadySeconds屬性來控制應用升級的速度。新舊更替過程中,新建立的Pod物件一旦成功響應就緒探測即被認為是可用狀態,然後進行下一輪的替換。而spec.minReadySeconds能夠定義在新的Pod物件建立後至少需要等待多長的時間才能會被認為其就緒,在該段時間內,更新操作會被阻塞。
完整的revisionHistoryLimit
配置如下:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-deploy-test
name: nginx-test-1
namespace: test1
spec:
replicas: 3
selector:
matchLabels:
app: nginx-test
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: nginx-test
spec:
containers:
- image: nginx:latest
name: nginx
4. 服務副本縮放
-
使用
scale
命令修改$ kubectl scale deploy/nginx-test-1 --replicas=2 -n test1
-
使用edit命令修改
直接使用edit命令修改 .spec.replicas 屬性值即可
$ kubectl edit deploy/nginx-test-1 -n test1
-
直接修改模板中的
.spec.replicas
屬性值即可
當然我們也可以設定自動縮放功能,這裡先簡單提及一下,完了專門寫一篇說這個事情。
基於現有 Pods 的 CPU 利用率選擇 要執行的 Pods 個數下限和上限。
$ kubectl autoscale deploy/nginx-test-1 --min=10 --max=15 --cpu-percent=80