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

一、知识准备

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

● 相关的参数介绍:

??livenessProbe:存活性探测。判断pod是否已经停止

??readinessProbe:就绪性探测。判断pod是否能够提供正常服务

??maxSurge:在滚动更新过程中最多可以存在的pod数

??maxUnavailable:在滚动更新过程中最多不可用的pod数

二、环境准备

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

三、准备镜像、yaml文件

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

docker pull registry.cn-beijing.aliyuncs.com/mrvolleyball/nginx:v1
docker pull registry.cn-beijing.aliyuncs.com/mrvolleyball/nginx:delay_v1

2个镜像都提供相同的服务,只不过nginx:delay_v1会延迟启动20才启动nginx

[email protected]:~# docker run -d --rm -p 10080:80 nginx:v1
e88097841c5feef92e4285a2448b943934ade5d86412946bc8d86e262f80a050
[email protected]:~# curl http://127.0.0.1:10080
----------
version: v1
hostname: f5189a5d3ad3

yaml文件:

[email protected]:~# more roll_update.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: update-deployment
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: roll-update
    spec:
      containers:
      - name: nginx
        image: registry.cn-beijing.aliyuncs.com/mrvolleyball/nginx:v1
        imagePullPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
    selector:
      app: roll-update
    ports:
    - protocol: TCP
      port: 10080
      targetPort: 80

四、livenessProbe与readinessProbe

livenessProbe:存活性探测,最主要是用来探测pod是否需要重启

readinessProbe:就绪性探测,用来探测pod是否已经能够提供服务

● 在滚动更新的过程中,pod会动态的被delete,然后又被create出来。存活性探测保证了始终有足够的pod存活提供服务,一旦出现pod数量不足,k8s会立即拉起新的pod

● 但是在pod启动的过程中,服务正在打开,并不可用,这时候如果有流量打过来,就会造成报错

下面来模拟一下这个场景:

首先apply上述的配置文件

[email protected]:~# kubectl apply -f roll_update.yaml
deployment.extensions "update-deployment" created
service "nginx-service" created
[email protected]:~# kubectl get pod -owide
NAME                                 READY     STATUS    RESTARTS   AGE       IP              NODE
update-deployment-7db77f7cc6-c4s2v   1/1       Running   0          28s       10.10.235.232   k8s-master
update-deployment-7db77f7cc6-nfgtd   1/1       Running   0          28s       10.10.36.82     k8s-node1
update-deployment-7db77f7cc6-tflfl   1/1       Running   0          28s       10.10.169.158   k8s-node2
[email protected]:~# kubectl get svc
NAME            TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)     AGE
nginx-service   ClusterIP   10.254.254.199   <none>        10080/TCP   1m

重新打开终端,测试当前服务的可用性(每秒做一次循环去获取nginx的服务内容):

[email protected]:~# while :; do curl http://10.254.254.199:10080; sleep 1; done
----------
version: v1
hostname: update-deployment-7db77f7cc6-nfgtd
----------
version: v1
hostname: update-deployment-7db77f7cc6-c4s2v
----------
version: v1
hostname: update-deployment-7db77f7cc6-tflfl
----------
version: v1
hostname: update-deployment-7db77f7cc6-nfgtd
...

这时候把镜像版本更新到nginx:delay_v1,这个镜像会延迟启动nginx,也就是说,会先sleep 20s,然后才去启动nginx服务。这就模拟了在服务启动过程中,虽然pod已经是存在的状态,但是并没有真正提供服务

[email protected]:~# kubectl patch deployment update-deployment --patch ‘{"metadata":{"annotations":{"kubernetes.io/change-cause":"update version to v2"}} ,"spec": {"template": {"spec": {"containers": [{"name": "nginx","image":"registry.cn-beijing.aliyuncs.com/mrvolleyball/nginx:delay_v1"}]}}}}‘
deployment.extensions "update-deployment" patched
...
----------
version: v1
hostname: update-deployment-7db77f7cc6-h6hvt
curl: (7) Failed to connect to 10.254.254.199 port 10080: Connection refused
curl: (7) Failed to connect to 10.254.254.199 port 10080: Connection refused
curl: (7) Failed to connect to 10.254.254.199 port 10080: Connection refused
curl: (7) Failed to connect to 10.254.254.199 port 10080: Connection refused
curl: (7) Failed to connect to 10.254.254.199 port 10080: Connection refused
curl: (7) Failed to connect to 10.254.254.199 port 10080: Connection refused
curl: (7) Failed to connect to 10.254.254.199 port 10080: Connection refused
curl: (7) Failed to connect to 10.254.254.199 port 10080: Connection refused
curl: (7) Failed to connect to 10.254.254.199 port 10080: Connection refused
curl: (7) Failed to connect to 10.254.254.199 port 10080: Connection refused
curl: (7) Failed to connect to 10.254.254.199 port 10080: Connection refused
curl: (7) Failed to connect to 10.254.254.199 port 10080: Connection refused
----------
version: delay_v1
hostname: update-deployment-d788c7dc6-6th87
----------
version: delay_v1
hostname: update-deployment-d788c7dc6-n22vz
----------
version: delay_v1
hostname: update-deployment-d788c7dc6-njmpz
----------
version: delay_v1
hostname: update-deployment-d788c7dc6-6th87

可以看到,由于延迟启动,nginx并没有真正做好准备提供服务,此时流量已经发到后端,导致服务不可用的状态

所以,加入readinessProbe是非常必要的手段:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: update-deployment
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: roll-update
    spec:
      containers:
      - name: nginx
        image: registry.cn-beijing.aliyuncs.com/mrvolleyball/nginx:v1
        imagePullPolicy: Always
        readinessProbe:
          tcpSocket:
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
    selector:
      app: roll-update
    ports:
    - protocol: TCP
      port: 10080
      targetPort: 80

重复上述步骤,先创建nginx:v1,然后patch到nginx:delay_v1

[email protected]:~# kubectl apply -f roll_update.yaml
deployment.extensions "update-deployment" created
service "nginx-service" created
[email protected]:~# kubectl patch deployment update-deployment --patch ‘{"metadata":{"annotations":{"kubernetes.io/change-cause":"update version to v2"}} ,"spec": {"template": {"spec": {"containers": [{"name": "nginx","image":"registry.cn-beijing.aliyuncs.com/mrvolleyball/nginx:delay_v1"}]}}}}‘
deployment.extensions "update-deployment" patched
[email protected]:~# kubectl get pod -owide
NAME                                 READY     STATUS        RESTARTS   AGE       IP              NODE
busybox                              1/1       Running       0          45d       10.10.235.255   k8s-master
lifecycle-demo                       1/1       Running       0          32d       10.10.169.186   k8s-node2
private-reg                          1/1       Running       0          92d       10.10.235.209   k8s-master
update-deployment-54d497b7dc-4mlqc   0/1       Running       0          13s       10.10.169.178   k8s-node2
update-deployment-54d497b7dc-pk4tb   0/1       Running       0          13s       10.10.36.98     k8s-node1
update-deployment-6d5d7c9947-l7dkb   1/1       Terminating   0          1m        10.10.169.177   k8s-node2
update-deployment-6d5d7c9947-pbzmf   1/1       Running       0          1m        10.10.36.97     k8s-node1
update-deployment-6d5d7c9947-zwt4z   1/1       Running       0          1m        10.10.235.246   k8s-master

● 由于设置了readinessProbe,虽然pod已经启动起来了,但是并不会立即投入使用,所以出现了 READY: 0/1 的情况

● 并且有pod出现了一直持续Terminating状态,因为滚动更新的限制,至少要保证有pod可用

再查看curl的状态,image的版本平滑更新到了nginx:delay_v1,没有出现报错的状况

[email protected]:~# while :; do curl http://10.254.66.136:10080; sleep 1; done
...
version: v1
hostname: update-deployment-6d5d7c9947-pbzmf
----------
version: v1
hostname: update-deployment-6d5d7c9947-zwt4z
----------
version: v1
hostname: update-deployment-6d5d7c9947-pbzmf
----------
version: v1
hostname: update-deployment-6d5d7c9947-zwt4z
----------
version: delay_v1
hostname: update-deployment-54d497b7dc-pk4tb
----------
version: delay_v1
hostname: update-deployment-54d497b7dc-4mlqc
----------
version: delay_v1
hostname: update-deployment-54d497b7dc-pk4tb
----------
version: delay_v1
hostname: update-deployment-54d497b7dc-4mlqc
...

五、maxSurge与maxUnavailable

● 在滚动更新中,有几种更新方案:先删除老的pod,然后添加新的pod;先添加新的pod,然后删除老的pod。在这个过程中,服务必须是可用的(也就是livenessProbe与readiness必须检测通过)

● 在具体的实施中,由maxSurge与maxUnavailable来控制究竟是先删老的还是先加新的以及粒度

● 若指定的副本数为3:

??maxSurge=1 maxUnavailable=0:最多允许存在4个(3+1)pod,必须有3个pod(3-0)同时提供服务。先创建一个新的pod,可用之后删除老的pod,直至全部更新完毕

??maxSurge=0 maxUnavailable=1:最多允许存在3个(3+0)pod,必须有2个pod(3-1)同时提供服务。先删除一个老的pod,然后创建新的pod,直至全部更新完毕

● 归根结底,必须满足maxSurge与maxUnavailable的条件,如果maxSurge与maxUnavailable同时为0,那就没法更新了,因为又不让删除,也不让添加,这种条件是无法满足的

六、小结

● 本文介绍了deployment滚动更新过程中,maxSurge、maxUnavailable、liveness、readiness等参数的使用

● 在滚动更新过程中,还有留有一个问题。比如在一个大型的系统中,某个业务的pod数很多(100个),执行一次滚动更新时,势必会造成pod版本不一致(有些pod是老版本,有些pod是新版本),用户访问很有可能会造成多次结果不一致的现象,直至版本更新完毕。关于这个问题待之后慢慢讨论



至此,本文结束

在下才疏学浅,有撒汤漏水的,请各位不吝赐教...

原文地址:https://www.cnblogs.com/MrVolleyball/p/10360860.html

时间: 2024-10-04 11:23:38

详细聊聊k8s deployment的滚动更新(二)的相关文章

Kubernetes集群中Service的滚动更新

Kubernetes集群中Service的滚动更新 二月 9, 2017 0 条评论 在移动互联网时代,消费者的消费行为已经"全天候化",为此,商家的业务系统也要保持7×24小时不间断地提供服务以满足消费者的需求.很难想像如今还会有以"中断业务"为前提的服务系统更新升级.如果微信官方发布公告说:每周六晚23:00~次日凌晨2:00进行例行系统升级,不能提供服务,作为用户的你会怎么想.怎么做呢?因此,各个平台在最初设计时就要考虑到服务的更新升级问题,部署在Kubern

K8S使用deployment 管理Pod以及滚动更新(6)

前面有使用pod的举例,但是我们现在有一个Pod正在提供线上的服务,我们来想想一下我们可能会遇到的一些场景: 某次运营活动非常成功,网站访问量突然暴增可以使用[HPA]运行当前Pod的节点发生故障了,Pod不能正常提供服务了[高可用pod]后面是解决方法,但是如果没有或者我们不了解底层pod运行模式,需要手动去干预处理,将会非常的麻烦.第一种情况,可能比较好应对,一般活动之前我们会大概计算下会有多大的访问量,提前多启动几个Pod,活动结束后再把多余的Pod杀掉,虽然有点麻烦,但是应该还是能够应对

linux运维、架构之路-K8s滚动更新及回滚

一.滚动更新        应用程序一次只更新一小部分副本,更新成功后,再更新更多的副本,最终完成所有副本的更新. 滚动更新的优点:零停机,整个更新过程始终有副本在运行,从而保证了业务的连续性. 1.创建三个副本Httpd服务,初始镜像为httpd:2.2.31,然后滚动更新至httpd:2.2.32 ###cat httpd.yaml### apiVersion: apps/v1beta2 kind: Deployment metadata: name: httpd spec: replica

深入玩转K8S之智能化的业务弹性伸缩和滚动更新操作

在上篇我们讲到了较为傻瓜初级的弹性伸缩和滚动更新,那么接下来我们来看看较为高级的智能的滚动更新.本节的知识点呢是K8S的liveness和readiness探测,也就是说利用健康检查来做更为智能化的弹性扩容和滚动更新. 那为什么说是比较智能化呢,因为在实际生产环境中会遇到这样那样的问题,比如:容器里面应用挂了或者说新启动的容器里面应用还没有就绪等等,所以说就需要进行探测来检验容器是否满足需求. 那么一般的检测分为几种,比如:进程检测.业务检测. 进程检测呢很好理解,也就是说通过检测容器进程来验证

Kubernetes——滚动更新和数据管理

k8s——滚动更新滚动更新就是一次只更新一小部分副本,更新成功之后再更新更多的副本,最终完成所有副本的更新.滚动更新最大的好处是零停机,整个更新的过程中始终有副本运行,从而保证了业务的连续性.kubectl create deploy httpd3 --image=httpd  --dry-run -o yaml > httpd3.yaml或者手动编写yaml文件: vim httpd3.yaml apiVersion: apps/v1kind: Deploymentmetadata: labe

kubernetes 滚动更新

示例: 创建一个app:kubectl create deployment nginx --image=nginx:1.11 创建service kubectl expose deployment nginx --port=80 --type=NodePort 扩缩容:kubectl scale deployment nginx --replicas=5 修改镜像,滚动更新:kubectl set image deployment nginx nginx=nginx:1.10 或者kubectl

Kubernetes Pod应用的滚动更新(八)

一.环境准备 我们紧接上一节的环境,进行下面的操作,如果不清楚的,可以先查看上一篇博文. 滚动更新是一次只更新一小部分副本,成功后,再更新更多的副本,最终完成所有副本的更新.滚动更新的最大的好处是零停机,整个更新过程始终有副本在运行,从而保证了业务的连续性. 二.更新 我们查看一下上一节的配置文件mytest-deploy.yaml. apiVersion: extensions/v1beta1 kind: Deployment metadata: name: mytest spec: repl

kubernetes学习(一) Scale应用 &amp; 滚动更新

一.Scale应用 默认请款下应用只会运行一个副本,可通过kubectl get deployments 查看副本数. ~$ kubectl get deployments NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE blogtest 1 1 1 1 3d kubernetes-bootcamp 1 1 1 1 3d 1.使用scale增加pod数量 执行如下命令,可将副本数增加到3个. ~$ kubectl scale deployments/b

Mysql命令详细汇总[未完][不定时更新]

先从最最最基础的开始 一.登录/退出 登录:mysql -h hostname -u username -p 退出:exit; 二.导入/导出[注意:这是在shell下直接敲命令,不用也不能登录mysql] 导入:mysql -hostname -u username -p < filepath/filename.sql 导出:mysqldump -hostname -u username -p > filepath/filename.sql 同时也可以登录mysql使用source命令 导入