系列目录

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

要详细探讨的参数描述:

  • livenessProbe:存活性探测。判断pod是否已经停止
  • readinessProbe:就绪性探测。判断pod是否能够提供正常服务
  • maxSurge:在滚动更新过程中最多可以存在的pod数
  • maxUnavailable:在滚动更新过程中最多不可用的pod数

准备镜像和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

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

yaml文件:

root@k8s-master:~# 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上述的配置文件

root@k8s-master:~# kubectl apply -f roll_update.yaml
deployment.extensions "update-deployment" created
service "nginx-service" created
root@k8s-master:~# 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
root@k8s-master:~# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-service ClusterIP 10.254.254.199 <none> 10080/TCP 1m

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

root@k8s-master:~# 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已经是存在的状态,但是并没有真正提供服务

root@k8s-master:~# 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

root@k8s-master:~# kubectl apply -f roll_update.yaml
deployment.extensions "update-deployment" created
service "nginx-service" created
root@k8s-master:~# 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
root@k8s-master:~# 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,没有出现报错的状况

root@k8s-master:~# 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,那就没法更新了,因为又不让删除,也不让添加,这种条件是无法满足的

详谈kubernetes更新-2的更多相关文章

  1. 详谈kubernetes滚动更新-1

    系列目录 这个系列分为两个小节,第一个小节介绍deployment滚动更新时,deployment.replicaset.pod的细节以及创建过程以及deployment版本管理的方式 第二个小节将介 ...

  2. 附025.kubeadm部署Kubernetes更新证书

    一 查看证书 1.1 查看过期时间-方式一 1 [root@master01 ~]# tree /etc/kubernetes/pki/ 2 [root@master01 ~]# for tls in ...

  3. 基于jenkins,tekton等工具打造kubernetes devops平台

    本贴为目录贴,将不断更新 目录 1.Docker在centos下安装以及常见错误解决 2.使用kubernetes 官网工具kubeadm部署kubernetes(使用阿里云镜像) 3.无法访问gcr ...

  4. 利用VSTS跟Kubernetes进行CI/CD

    准备VSTS管理环境 首先我们需要到www.visualstudio.com下申请好的VSTS账号,然后在账号下创建一个用Git作为代码管理的项目 创建好项目后我们就可以利用git clone将代码库 ...

  5. 部署安装kubernetes client-python,执行pip install setup.py时报错

    之前在本地安装过kubernetes的python库,安装下来一切正常,但今天换到测试机器上去部署,确保错了,具体步骤如下. 第一步,克隆代码,执行以下命令:    # git clone --rec ...

  6. VSTS跟Kubernetes整合进行CI/CD

    利用VSTS跟Kubernetes整合进行CI/CD   为什么VSTS要搭配Kubernetes? 通常我们在开发管理软件项目的时候都会碰到一个很头痛的问题,就是开发.测试.生产环境不一致,导致开发 ...

  7. Kubernetes TensorFlow 默认 特定 集群管理器 虚拟化技术

    Our goal is to foster an ecosystem of components and tools that relieve the burden of running applic ...

  8. 入门 - k8s滚动更新部署中的镜像版本 (七)

    目标 使用 kubectl 执行 Rolling Update(滚动更新) 更新应用程序 用户期望应用程序始终可用,为此开发者/运维者在更新应用程序时要分多次完成.在 Kubernetes 中,这是通 ...

  9. 使用 kubectl 执行 Rolling Update(滚动更新)

    Rolling Update滚动更新 通过使用新版本的 Pod 逐步替代旧版本的 Pod 来实现 Deployment 的更新,从而实现零停机.新的 Pod 将在具有可用资源的 Node(节点)上进行 ...

随机推荐

  1. 模拟select框

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. Github管理 第一步:在Eclipse中导入既存Github Java Project

    1.前提 从官网下载的最新版本的Eclipse已经集成了Github插件,所以忽略了配置说明. 如果在下面的步骤中你找不到Git的设定目录,可能你的Eclipse中还没有Github,请自行解决. 2 ...

  3. no main manifest attribute, in demo-1.0.jar

    今天想打包一个jar到Linux上运行,发现使用java -jar demo-1.0.jar 运行报错: no main manifest attribute, in demo-1.0.jar 解决方 ...

  4. 你能说出SQL聚集索引和非聚集索引的区别吗?

    最近突然想起前一阵和一朋友的聊天,当时他问我的问题是一个非常普通的问题:说说SQL聚集索引和非聚集索引的区别. AD:WOT2015 互联网运维与开发者大会 热销抢票 其实对于非专业的数据库操作人员来 ...

  5. 如何用github展示前端页面

    如何在github上展示你的前端页面 参考:https://luozhihao.github.io/demo/ 感谢作者 1.New reposipory 2.进入你本机目录 我是在d:vuedemo ...

  6. Atcoder CODE FESTIVAL 2017 qual B E - Popping Balls 组合计数

    题目链接 题意 \(A+B\)个球排成一行,左边\(A\)个为红球,右边\(B\)个为蓝球. 最开始可以选择两个数\(s,t\),每次操作可以取左起第\(1\)或\(s\)或\(t\)个球.问有多少种 ...

  7. WebRTC源码架构浅析(转)

    Google 在2010年花了6千8百万美元收购了大名鼎鼎的 Global IP Sound/Solutions (GIPS) 公司, 得到了它的 VoIP 相关技术的专利和软件. 第二年, Goog ...

  8. php接口开发时,数据解析失败问题,字符转义,编码问题

    php接口开发时,数据解析失败问题,字符转义,编码问题 情景: A平台--->向接口请求数据---->接口向B平台请求数据---->B平台返回数据给接口---->接口返回数据给 ...

  9. 大文件LOG持续输出

    作了两个版本,一是websocket输出,一是直接显示指定行数. class WebSocketHandler(tornado.websocket.WebSocketHandler): file_co ...

  10. C#知识点总结:Monitor和Lock以及区别

    Monitor对象 1.Monitor.Enter(object)方法是获取锁,Monitor.Exit(object)方法是释放锁,这就是Monitor最常用的两个方法,当然在使用过程中为了避免获取 ...