详细聊聊k8s deployment的滚动更新(一)

一、知识准备

● 本文详细探索deployment在滚动更新时候的行为


二、环境准备

组件 版本
OS Ubuntu 18.04.1 LTS
docker 18.06.0-ce


三、准备镜像

首先准备2个不同版本的镜像,用于测试(已经在阿里云上创建好2个不同版本的nginx镜像)

docker pull registry.cn-beijing.aliyuncs.com/mrvolleyball/nginx:v1
docker pull registry.cn-beijing.aliyuncs.com/mrvolleyball/nginx:v2
root@k8s-master:~# docker run -d --rm -p 10080:80 nginx:v1
e88097841c5feef92e4285a2448b943934ade5d86412946bc8d86e262f80a050
root@k8s-master:~# curl http://127.0.0.1:10080
----------
version: v1
hostname: f5189a5d3ad3

四、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镜像版本的三种方式),既要保证服务可用,又要保证在线更新,流程应该是:
  1、先增加一个pod,镜像版本为新版本
  2、pod可用之后,删除一个老版本pod
  3、循环第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调度快速回滚

五、小结

● 本文介绍了deployment滚动更新时,deployment、replicaset、pod的细节以及创建过程
● 介绍了deployment版本管理的方式
● 下一小节将会介绍在滚动更新过程中最大可用、liveness以及readiness等



至此,本文结束
在下才疏学浅,有撒汤漏水的,请各位不吝赐教...

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容