6.1 Pod控制器介紹
Pod是kubernetes的最小管理單元,在kubernetes中,按照pod的創建方式可以將其分為兩類:
-
自主式pod:kubernetes直接創建出來的Pod,這種pod刪除后就沒有了,也不會重建
-
控制器創建的pod:kubernetes通過控制器創建的pod,這種pod刪除了之后還會自動重建
什么是Pod控制器
Pod控制器是管理pod的中間層,使用Pod控制器之后,只需要告訴Pod控制器,想要多少個什么樣的Pod就可以了,它會創建出滿足條件的Pod並確保每一個Pod資源處於用戶期望的目標狀態。如果Pod資源在運行中出現故障,它會基於指定策略重新編排Pod。
在kubernetes中,有很多類型的pod控制器,每種都有自己的適合的場景,常見的有下面這些:
-
ReplicationController:比較原始的pod控制器,已經被廢棄,由ReplicaSet替代
-
ReplicaSet:保證副本數量一直維持在期望值,並支持pod數量擴縮容,鏡像版本升級
-
Deployment:通過控制ReplicaSet來控制Pod,並支持滾動升級、回退版本
-
Horizontal Pod Autoscaler:可以根據集群負載自動水平調整Pod的數量,實現削峰填谷
-
DaemonSet:在集群中的指定Node上運行且僅運行一個副本,一般用於守護進程類的任務
-
Job:它創建出來的pod只要完成任務就立即退出,不需要重啟或重建,用於執行一次性任務
-
Cronjob:它創建的Pod負責周期性任務控制,不需要持續后台運行
-
StatefulSet:管理有狀態應用
6.2 ReplicaSet(RS)
ReplicaSet的主要作用是保證一定數量的pod正常運行,它會持續監聽這些Pod的運行狀態,一旦Pod發生故障,就會重啟或重建。同時它還支持對pod數量的擴縮容和鏡像版本的升降級。
ReplicaSet的資源清單文件:
apiVersion
在這里面,需要新了解的配置項就是spec
下面幾個選項:
-
replicas:指定副本數量,其實就是當前rs創建出來的pod的數量,默認為1
-
selector:選擇器,它的作用是建立pod控制器和pod之間的關聯關系,采用的Label Selector機制
-
template:模板,就是當前控制器創建pod所使用的模板板,里面其實就是前一章學過的pod的定義
創建ReplicaSet
創建pc-replicaset.yaml文件,內容如下:
apiVersion
# 創建rs
[root@k8s-master01 ~]# kubectl create -f pc-replicaset.yaml
replicaset.apps/pc-replicaset created
# 查看rs
# DESIRED:期望副本數量
# CURRENT:當前副本數量
# READY:已經准備好提供服務的副本數量
[root@k8s-master01 ~]# kubectl get rs pc-replicaset -n dev -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
pc-replicaset 3 3 3 22s nginx nginx:1.17.1 app=nginx-pod
# 查看當前控制器創建出來的pod
# 這里發現控制器創建出來的pod的名稱是在控制器名稱后面拼接了-xxxxx隨機碼
[root@k8s-master01 ~]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
pc-replicaset-6vmvt 1/1 Running 0 54s
pc-replicaset-fmb8f 1/1 Running 0 54s
pc-replicaset-snrk2 1/1 Running 0 54s
擴縮容
# 編輯rs的副本數量,修改spec:replicas: 6即可
[root@k8s-master01 ~]# kubectl edit rs pc-replicaset -n dev
replicaset.apps/pc-replicaset edited
# 查看pod
[root@k8s-master01 ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-replicaset-6vmvt 1/1 Running 0 114m
pc-replicaset-cftnp 1/1 Running 0 10s
pc-replicaset-fjlm6 1/1 Running 0 10s
pc-replicaset-fmb8f 1/1 Running 0 114m
pc-replicaset-s2whj 1/1 Running 0 10s
pc-replicaset-snrk2 1/1 Running 0 114m
# 當然也可以直接使用命令實現
# 使用scale命令實現擴縮容, 后面--replicas=n直接指定目標數量即可
[root@k8s-master01 ~]# kubectl scale rs pc-replicaset --replicas=2 -n dev
replicaset.apps/pc-replicaset scaled
# 命令運行完畢,立即查看,發現已經有4個開始准備退出了
[root@k8s-master01 ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-replicaset-6vmvt 0/1 Terminating 0 118m
pc-replicaset-cftnp 0/1 Terminating 0 4m17s
pc-replicaset-fjlm6 0/1 Terminating 0 4m17s
pc-replicaset-fmb8f 1/1 Running 0 118m
pc-replicaset-s2whj 0/1 Terminating 0 4m17s
pc-replicaset-snrk2 1/1 Running 0 118m
#稍等片刻,就只剩下2個了
[root@k8s-master01 ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-replicaset-fmb8f 1/1 Running 0 119m
pc-replicaset-snrk2 1/1 Running 0 119m
鏡像升級
# 編輯rs的容器鏡像 - image: nginx:1.17.2
[root@k8s-master01 ~]# kubectl edit rs pc-replicaset -n dev
replicaset.apps/pc-replicaset edited
# 再次查看,發現鏡像版本已經變更了
[root@k8s-master01 ~]# kubectl get rs -n dev -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES ...
pc-replicaset 2 2 2 140m nginx nginx:1.17.2 ...
# 同樣的道理,也可以使用命令完成這個工作
# kubectl set image rs rs名稱 容器=鏡像版本 -n namespace
[root@k8s-master01 ~]# kubectl set image rs pc-replicaset nginx=nginx:1.17.1 -n dev
replicaset.apps/pc-replicaset image updated
# 再次查看,發現鏡像版本已經變更了
[root@k8s-master01 ~]# kubectl get rs -n dev -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES ...
pc-replicaset 2 2 2 145m nginx nginx:1.17.1 ...
刪除ReplicaSet
# 使用kubectl delete命令會刪除此RS以及它管理的Pod
# 在kubernetes刪除RS前,會將RS的replicasclear調整為0,等待所有的Pod被刪除后,在執行RS對象的刪除
[root@k8s-master01 ~]# kubectl delete rs pc-replicaset -n dev
replicaset.apps "pc-replicaset" deleted
[root@k8s-master01 ~]# kubectl get pod -n dev -o wide
No resources found in dev namespace.
# 如果希望僅僅刪除RS對象(保留Pod),可以使用kubectl delete命令時添加--cascade=false選項(不推薦)。
[root@k8s-master01 ~]# kubectl delete rs pc-replicaset -n dev --cascade=false
replicaset.apps "pc-replicaset" deleted
[root@k8s-master01 ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-replicaset-cl82j 1/1 Running 0 75s
pc-replicaset-dslhb 1/1 Running 0 75s
# 也可以使用yaml直接刪除(推薦)
[root@k8s-master01 ~]# kubectl delete -f pc-replicaset.yaml
replicaset.apps "pc-replicaset" deleted
6.3 Deployment(Deploy)
為了更好的解決服務編排的問題,kubernetes在V1.2版本開始,引入了Deployment控制器。值得一提的是,這種控制器並不直接管理pod,而是通過管理ReplicaSet來簡介管理Pod,即:Deployment管理ReplicaSet,ReplicaSet管理Pod。所以Deployment比ReplicaSet功能更加強大。
Deployment主要功能有下面幾個:
-
支持ReplicaSet的所有功能
-
支持發布的停止、繼續
-
支持滾動升級和回滾版本
Deployment的資源清單文件:
apiVersion
創建deployment
創建pc-deployment.yaml,內容如下:
apiVersion
# 創建deployment
[root@k8s-master01 ~]# kubectl create -f pc-deployment.yaml --record=true
deployment.apps/pc-deployment created
# 查看deployment
# UP-TO-DATE 最新版本的pod的數量
# AVAILABLE 當前可用的pod的數量
[root@k8s-master01 ~]# kubectl get deploy pc-deployment -n dev
NAME READY UP-TO-DATE AVAILABLE AGE
pc-deployment 3/3 3 3 15s
# 查看rs
# 發現rs的名稱是在原來deployment的名字后面添加了一個10位數的隨機串
[root@k8s-master01 ~]# kubectl get rs -n dev
NAME DESIRED CURRENT READY AGE
pc-deployment-6696798b78 3 3 3 23s
# 查看pod
[root@k8s-master01 ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-deployment-6696798b78-d2c8n 1/1 Running 0 107s
pc-deployment-6696798b78-smpvp 1/1 Running 0 107s
pc-deployment-6696798b78-wvjd8 1/1 Running 0 107s
擴縮容
# 變更副本數量為5個
[root@k8s-master01 ~]# kubectl scale deploy pc-deployment --replicas=5 -n dev
deployment.apps/pc-deployment scaled
# 查看deployment
[root@k8s-master01 ~]# kubectl get deploy pc-deployment -n dev
NAME READY UP-TO-DATE AVAILABLE AGE
pc-deployment 5/5 5 5 2m
# 查看pod
[root@k8s-master01 ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-deployment-6696798b78-d2c8n 1/1 Running 0 4m19s
pc-deployment-6696798b78-jxmdq 1/1 Running 0 94s
pc-deployment-6696798b78-mktqv 1/1 Running 0 93s
pc-deployment-6696798b78-smpvp 1/1 Running 0 4m19s
pc-deployment-6696798b78-wvjd8 1/1 Running 0 4m19s
# 編輯deployment的副本數量,修改spec:replicas: 4即可
[root@k8s-master01 ~]# kubectl edit deploy pc-deployment -n dev
deployment.apps/pc-deployment edited
# 查看pod
[root@k8s-master01 ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-deployment-6696798b78-d2c8n 1/1 Running 0 5m23s
pc-deployment-6696798b78-jxmdq 1/1 Running 0 2m38s
pc-deployment-6696798b78-smpvp 1/1 Running 0 5m23s
pc-deployment-6696798b78-wvjd8 1/1 Running 0 5m23s
鏡像更新
deployment支持兩種更新策略:重建更新
和滾動更新
,可以通過strategy
指定策略類型,支持兩個屬性:
strategy:指定新的Pod替換舊的Pod的策略, 支持兩個屬性:
type:指定策略類型,支持兩種策略
Recreate:在創建出新的Pod之前會先殺掉所有已存在的Pod
RollingUpdate:滾動更新,就是殺死一部分,就啟動一部分,在更新過程中,存在兩個版本Pod
rollingUpdate:當type為RollingUpdate時生效,用於為RollingUpdate設置參數,支持兩個屬性:
maxUnavailable:用來指定在升級過程中不可用Pod的最大數量,默認為25%。
maxSurge: 用來指定在升級過程中可以超過期望的Pod的最大數量,默認為25%。
重建更新
1) 編輯pc-deployment.yaml,在spec節點下添加更新策略
spec
2) 創建deploy進行驗證
# 變更鏡像
[root@k8s-master01 ~]# kubectl set image deployment pc-deployment nginx=nginx:1.17.2 -n dev
deployment.apps/pc-deployment image updated
# 觀察升級過程
[root@k8s-master01 ~]# kubectl get pods -n dev -w
NAME READY STATUS RESTARTS AGE
pc-deployment-5d89bdfbf9-65qcw 1/1 Running 0 31s
pc-deployment-5d89bdfbf9-w5nzv 1/1 Running 0 31s
pc-deployment-5d89bdfbf9-xpt7w 1/1 Running 0 31s
pc-deployment-5d89bdfbf9-xpt7w 1/1 Terminating 0 41s
pc-deployment-5d89bdfbf9-65qcw 1/1 Terminating 0 41s
pc-deployment-5d89bdfbf9-w5nzv 1/1 Terminating 0 41s
pc-deployment-675d469f8b-grn8z 0/1 Pending 0 0s
pc-deployment-675d469f8b-hbl4v 0/1 Pending 0 0s
pc-deployment-675d469f8b-67nz2 0/1 Pending 0 0s
pc-deployment-675d469f8b-grn8z 0/1 ContainerCreating 0 0s
pc-deployment-675d469f8b-hbl4v 0/1 ContainerCreating 0 0s
pc-deployment-675d469f8b-67nz2 0/1 ContainerCreating 0 0s
pc-deployment-675d469f8b-grn8z 1/1 Running 0 1s
pc-deployment-675d469f8b-67nz2 1/1 Running 0 1s
pc-deployment-675d469f8b-hbl4v 1/1 Running 0 2s
滾動更新
1) 編輯pc-deployment.yaml,在spec節點下添加更新策略
spec
2) 創建deploy進行驗證
# 變更鏡像
[root@k8s-master01 ~]# kubectl set image deployment pc-deployment nginx=nginx:1.17.3 -n dev
deployment.apps/pc-deployment image updated
# 觀察升級過程
[root@k8s-master01 ~]# kubectl get pods -n dev -w
NAME READY STATUS RESTARTS AGE
pc-deployment-c848d767-8rbzt 1/1 Running 0 31m
pc-deployment-c848d767-h4p68 1/1 Running 0 31m
pc-deployment-c848d767-hlmz4 1/1 Running 0 31m
pc-deployment-c848d767-rrqcn 1/1 Running 0 31m
pc-deployment-966bf7f44-226rx 0/1 Pending 0 0s
pc-deployment-966bf7f44-226rx 0/1 ContainerCreating 0 0s
pc-deployment-966bf7f44-226rx 1/1 Running 0 1s
pc-deployment-c848d767-h4p68 0/1 Terminating 0 34m
pc-deployment-966bf7f44-cnd44 0/1 Pending 0 0s
pc-deployment-966bf7f44-cnd44 0/1 ContainerCreating 0 0s
pc-deployment-966bf7f44-cnd44 1/1 Running 0 2s
pc-deployment-c848d767-hlmz4 0/1 Terminating 0 34m
pc-deployment-966bf7f44-px48p 0/1 Pending 0 0s
pc-deployment-966bf7f44-px48p 0/1 ContainerCreating 0 0s
pc-deployment-966bf7f44-px48p 1/1 Running 0 0s
pc-deployment-c848d767-8rbzt 0/1 Terminating 0 34m
pc-deployment-966bf7f44-dkmqp 0/1 Pending 0 0s
pc-deployment-966bf7f44-dkmqp 0/1 ContainerCreating 0 0s
pc-deployment-966bf7f44-dkmqp 1/1 Running 0 2s
pc-deployment-c848d767-rrqcn 0/1 Terminating 0 34m
# 至此,新版本的pod創建完畢,就版本的pod銷毀完畢
# 中間過程是滾動進行的,也就是邊銷毀邊創建
滾動更新的過程:
鏡像更新中rs的變化:
# 查看rs,發現原來的rs的依舊存在,只是pod數量變為了0,而后又新產生了一個rs,pod數量為4
# 其實這就是deployment能夠進行版本回退的奧妙所在,后面會詳細解釋
[root@k8s-master01 ~]# kubectl get rs -n dev
NAME DESIRED CURRENT READY AGE
pc-deployment-6696798b78 0 0 0 7m37s
pc-deployment-6696798b11 0 0 0 5m37s
pc-deployment-c848d76789 4 4 4 72s
版本回退
deployment支持版本升級過程中的暫停、繼續功能以及版本回退等諸多功能,下面具體來看.
kubectl rollout: 版本升級相關功能,支持下面的選項:
-
status 顯示當前升級狀態
-
history 顯示 升級歷史記錄
-
pause 暫停版本升級過程
-
resume 繼續已經暫停的版本升級過程
-
restart 重啟版本升級過程
-
undo 回滾到上一級版本(可以使用--to-revision回滾到指定版本)
# 查看當前升級版本的狀態
[root@k8s-master01 ~]# kubectl rollout status deploy pc-deployment -n dev
deployment "pc-deployment" successfully rolled out
# 查看升級歷史記錄
[root@k8s-master01 ~]# kubectl rollout history deploy pc-deployment -n dev
deployment.apps/pc-deployment
REVISION CHANGE-CAUSE
1 kubectl create --filename=pc-deployment.yaml --record=true
2 kubectl create --filename=pc-deployment.yaml --record=true
3 kubectl create --filename=pc-deployment.yaml --record=true
# 可以發現有三次版本記錄,說明完成過兩次升級
# 版本回滾
# 這里直接使用--to-revision=1回滾到了1版本, 如果省略這個選項,就是回退到上個版本,就是2版本
[root@k8s-master01 ~]# kubectl rollout undo deployment pc-deployment --to-revision=1 -n dev
deployment.apps/pc-deployment rolled back
# 查看發現,通過nginx鏡像版本可以發現到了第一版
[root@k8s-master01 ~]# kubectl get deploy -n dev -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES
pc-deployment 4/4 4 4 74m nginx nginx:1.17.1
# 查看rs,發現第一個rs中有4個pod運行,后面兩個版本的rs中pod為運行
# 其實deployment之所以可是實現版本的回滾,就是通過記錄下歷史rs來實現的,
# 一旦想回滾到哪個版本,只需要將當前版本pod數量降為0,然后將回滾版本的pod提升為目標數量就可以了
[root@k8s-master01 ~]# kubectl get rs -n dev
NAME DESIRED CURRENT READY AGE
pc-deployment-6696798b78 4 4 4 78m
pc-deployment-966bf7f44 0 0 0 37m
pc-deployment-c848d767 0 0 0 71m
金絲雀發布
Deployment控制器支持控制更新過程中的控制,如“暫停(pause)”或“繼續(resume)”更新操作。
比如有一批新的Pod資源創建完成后立即暫停更新過程,此時,僅存在一部分新版本的應用,主體部分還是舊的版本。然后,再篩選一小部分的用戶請求路由到新版本的Pod應用,繼續觀察能否穩定地按期望的方式運行。確定沒問題之后再繼續完成余下的Pod資源滾動更新,否則立即回滾更新操作。這就是所謂的金絲雀發布。
# 更新deployment的版本,並配置暫停deployment
[root@k8s-master01 ~]# kubectl set image deploy pc-deployment nginx=nginx:1.17.4 -n dev && kubectl rollout pause deployment pc-deployment -n dev
deployment.apps/pc-deployment image updated
deployment.apps/pc-deployment paused
#觀察更新狀態
[root@k8s-master01 ~]# kubectl rollout status deploy pc-deployment -n dev
Waiting for deployment "pc-deployment" rollout to finish: 2 out of 4 new replicas have been updated...
# 監控更新的過程,可以看到已經新增了一個資源,但是並未按照預期的狀態去刪除一個舊的資源,就是因為使用了pause暫停命令
[root@k8s-master01 ~]# kubectl get rs -n dev -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES
pc-deployment-5d89bdfbf9 3 3 3 19m nginx nginx:1.17.1
pc-deployment-675d469f8b 0 0 0 14m nginx nginx:1.17.2
pc-deployment-6c9f56fcfb 2 2 2 3m16s nginx nginx:1.17.4
[root@k8s-master01 ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-deployment-5d89bdfbf9-rj8sq 1/1 Running 0 7m33s
pc-deployment-5d89bdfbf9-ttwgg 1/1 Running 0 7m35s
pc-deployment-5d89bdfbf9-v4wvc 1/1 Running 0 7m34s
pc-deployment-6c9f56fcfb-996rt 1/1 Running 0 3m31s
pc-deployment-6c9f56fcfb-j2gtj 1/1 Running 0 3m31s
# 確保更新的pod沒問題了,繼續更新
[root@k8s-master01 ~]# kubectl rollout resume deploy pc-deployment -n dev
deployment.apps/pc-deployment resumed
# 查看最后的更新情況
[root@k8s-master01 ~]# kubectl get rs -n dev -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES
pc-deployment-5d89bdfbf9 0 0 0 21m nginx nginx:1.17.1
pc-deployment-675d469f8b 0 0 0 16m nginx nginx:1.17.2
pc-deployment-6c9f56fcfb 4 4 4 5m11s nginx nginx:1.17.4
[root@k8s-master01 ~]# kubectl get pods -n dev
NAME