這個系列分為兩個小節,第一個小節介紹deployment滾動更新時,deployment、replicaset、pod的細節以及創建過程以及deployment版本管理的方式
第二個小節將介紹滾動更新過程中最大可用、liveness以及readiness等
我們在阿里雲上有兩個不同版本的鏡像用於測試,使用docker pull
把它拉取到本地
docker pull registry.cn-beijing.aliyuncs.com/mrvolleyball/nginx:v1
docker pull registry.cn-beijing.aliyuncs.com/mrvolleyball/nginx:v2
截至目前,我們並沒有詳細介紹過docker的操作,但是目前市面上已經有很多書籍和博客介紹docker的基本操作,沒有docker操作經驗的可以關注一些入門教程.
root@k8s-master:~# docker run -d -p 10080:80 nginx:v1
e88097841c5feef92e4285a2448b943934ade5d86412946bc8d86e262f80a050
root@k8s-master:~# curl http://127.0.0.1:10080
----------
version: v1
hostname: f5189a5d3ad3
注在linux里如果是以root用戶登陸,則命令行前一個
#
標識,這里並不是注釋的意思,還請注意
deployment、replicaset、pod之間的關系
+------------+
| deployment |
+-----+------+
|
|
|
|
+--------------------------------------------------+
| | |
| | |
| | |
| | |
| | |
| | |
+------v------+ +------v------+ +------v------+
|replicaset:v1| |replicaset:v2| |replicaset:v3|
+-------------+ +------+------+ +-------------+
|
|
+--------+---------+
| |
| |
+---v---+ +---v---+
|pod:v2 | |pod:v2 |
+-------+ +-------+
- deployment調度replicaset,pod由replicaset調度
- deployment管理多個replicaset版本,可用於回滾
- replicaset控制pod的行為,包括新增pod、刪除pod
我們首先准備一個yaml文件用於測試:
root@k8s-master:~# more roll_update.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: image-deployment
spec:
replicas: 1
template:
metadata:
labels:
app: image-update
spec:
containers:
- name: nginx
image: registry.cn-beijing.aliyuncs.com/mrvolleyball/nginx:v1
imagePullPolicy: Always
簡單驗證一下:
root@k8s-master:~# kubectl apply -f roll_update.yaml
deployment.extensions "update-deployment" created
root@k8s-master:~# kubectl get deploy
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
update-deployment 3 3 3 3 54s
root@k8s-master:~# kubectl get rs
NAME DESIRED CURRENT READY AGE
update-deployment-7db77f7cc6 3 3 3 56s
root@k8s-master:~# kubectl get pod
NAME READY STATUS RESTARTS AGE
update-deployment-7db77f7cc6-7j49g 1/1 Running 0 1m
update-deployment-7db77f7cc6-b75wn 1/1 Running 0 1m
update-deployment-7db77f7cc6-cfnt5 1/1 Running 0 1m
deployment、replicaset、pod都已經正常啟動,下面分析一下他們的行為:
deployment
root@k8s-master:~# kubectl describe deploy update-deployment
Name: update-deployment
Namespace: default
...
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 1 max unavailable, 1 max surge
...
NewReplicaSet: update-deployment-7db77f7cc6 (3/3 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 1m deployment-controller Scaled up replica set update-deployment-7db77f7cc6 to 3
- deployment創建了一個replicaset,叫做update-deployment-7db77f7cc6(7db77f7cc6是replicaset的template hash值)
- 根據配置文件的要求,replicaset的副本數為3
replicaset
root@k8s-master:~# kubectl describe rs update-deployment-7db77f7cc6
Name: update-deployment-7db77f7cc6
Namespace: default
...
Controlled By: Deployment/update-deployment
Replicas: 3 current / 3 desired
Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 3m replicaset-controller Created pod: update-deployment-7db77f7cc6-7j49g
Normal SuccessfulCreate 3m replicaset-controller Created pod: update-deployment-7db77f7cc6-b75wn
Normal SuccessfulCreate 3m replicaset-controller Created pod: update-deployment-7db77f7cc6-cfnt5
replicaset創建了3個pod
pod
root@k8s-master:~# kubectl describe pod update-deployment-7db77f7cc6-7j49g
Name: update-deployment-7db77f7cc6-7j49g
Namespace: default
...
Status: Running
IP: 10.10.169.140
Controlled By: ReplicaSet/update-deployment-7db77f7cc6
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 9m default-scheduler Successfully assigned update-deployment-7db77f7cc6-7j49g to k8s-node2
Normal SuccessfulMountVolume 9m kubelet, k8s-node2 MountVolume.SetUp succeeded for volume "default-token-v9nkm"
Normal Pulling 9m kubelet, k8s-node2 pulling image "registry.cn-beijing.aliyuncs.com/mrvolleyball/nginx:v1"
Normal Pulled 9m kubelet, k8s-node2 Successfully pulled image "registry.cn-beijing.aliyuncs.com/mrvolleyball/nginx:v1"
Normal Created 9m kubelet, k8s-node2 Created container
Normal Started 9m kubelet, k8s-node2 Started container
- pod被replicaset創建之后,開始分配到worker節點、拉取鏡像、啟動容器等一系列操作
- 所以pod的命名方式是:update-deployment-7db77f7cc6-7j49g(deployment名字-replicaset模板hash名字-pod模板hash名字)
大家可能不禁會有疑問,為什么搞這么復雜,啟動一個pod需要動用這么多組件呢?下面用一個場景說明為啥需要這么多組件:
鏡像版本更新
鏡像版本更新
-
當鏡像版本有更新時(三種方法都可以實現,參考前一篇文章:更新k8s鏡像版本的三種方式),既要保證服務可用,又要保證在線更新,流程應該是:
- 先增加一個pod,鏡像版本為新版本
- pod可用之后,刪除一個老版本pod
- 循環第1、2步,直到老版本pod全部刪除,新版本的pod全部可用
-
上述的這個過程就是replicaset的作用,它根據需求,自動的增加新版本pod,然后刪除老版本pod,直到老版本pod全部刪除,新版本的pod全部可用
-
如果此時版本需要回退,那replicaset需要把剛才的步驟逆向更新一遍,實現版本回退
-
deployment的作用就是管理replicaset。deployment會保存各個版本的replicaset,一旦需要進行版本回滾,deployment會立即回滾replicaset的版本,從而控制pod狀態
下面測試一下:
使用patch命令更新鏡像版本,並且使用pause命令來觀察:
root@k8s-master:~# kubectl patch deployment update-deployment \
--patch '{"spec": {"template": {"spec": {"containers": [{"name": "nginx","image":"registry.cn-beijing.aliyuncs.com/mrvolleyball/nginx:v2"}]}}}}' \
&& kubectl rollout pause deployment update-deployment
deployment.extensions "update-deployment" patched
deployment.apps "update-deployment" paused
此時pod狀態:
root@k8s-master:~# kubectl get pod -owide
NAME READY STATUS RESTARTS AGE IP NODE
update-deployment-7db77f7cc6-7j49g 1/1 Running 0 1h 10.10.169.140 k8s-node2
update-deployment-7db77f7cc6-b75wn 1/1 Running 0 1h 10.10.235.211 k8s-master
update-deployment-7db77f7cc6-cfnt5 1/1 Terminating 0 1h 10.10.36.126 k8s-node1
update-deployment-7fb7b4b557-6987x 1/1 Running 0 7s 10.10.36.127 k8s-node1
update-deployment-7fb7b4b557-dxdqb 1/1 Running 0 10s 10.10.169.139 k8s-node2
新增了2個pod,而刪除了1個老版本的pod
此時replicaset狀態:
root@k8s-master:~# kubectl get rs -owide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
update-deployment-7db77f7cc6 2 2 2 1h nginx registry.cn-beijing.aliyuncs.com/mrvolleyball/nginx:v1 app=roll-update,pod-template-hash=3863393772
update-deployment-7fb7b4b557 2 2 2 4m nginx registry.cn-beijing.aliyuncs.com/mrvolleyball/nginx:v2 app=roll-update,pod-template-hash=3963606113
有一個新版本的replicaset創建了出來,並且需求的pod數量為2,而原來的replicaset需求的pod數量從3降為2
查看replicaset版本:
root@k8s-master:~# kubectl rollout history deploy update-deployment
deployments "update-deployment"
REVISION CHANGE-CAUSE
1 <none>
2 update version to v2
新增了一個版本2
由於使用pause命令,更新過程到此會卡主,我們讓更新的過程繼續下去:
root@k8s-master:~# kubectl rollout resume deployment update-deployment
deployment.apps "update-deployment" resumed
查看狀態:
root@k8s-master:~# kubectl get pod
NAME READY STATUS RESTARTS AGE
update-deployment-7fb7b4b557-6987x 1/1 Running 0 15m
update-deployment-7fb7b4b557-dxdqb 1/1 Running 0 15m
update-deployment-7fb7b4b557-wg5c8 1/1 Running 0 1m
root@k8s-master:~# kubectl get rs -owide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
update-deployment-7db77f7cc6 0 0 0 1h nginx registry.cn-beijing.aliyuncs.com/mrvolleyball/nginx:v1 app=roll-update,pod-template-hash=3863393772
update-deployment-7fb7b4b557 3 3 3 14m nginx registry.cn-beijing.aliyuncs.com/mrvolleyball/nginx:v2 app=roll-update,pod-template-hash=3963606113
v1版本的replicaset已經沒有pod,但是歷史記錄還是保留的,可以通過deployment調度快速回滾