摘要
K8S上的服务项目要做健康检测,liveness和readiness很重要。它们能保证服务项目的稳定和可靠,让我们的业务流程更顺畅。K8s真是太棒了!
正文
Kubernetes服务项目pod的健康检测liveness和readiness详细说明
Kubernetes服务项目pod的健康检测liveness和readiness详细说明
下面给大伙儿解读下到K8S上,大家假如对大家的业务流程服务项目开展健康检测。
Health Check、restartPolicy
这儿大家再进一步,来聊一聊K8s上边服务项目的健康检测特点。在K8s上,强劲的自愈能力是这一器皿编辑模块的十分关键的一个特点,治愈的默认设置完成方法是根据自动关机产生常见故障的器皿,使之恢复过来。此外,大家还能够运用Liveness 和 Readiness检验体制来设定更加细致的健康检测指标值,进而完成以下的要求:
- 零关机布署
- 防止布署失效的服务项目镜像系统
- 更为安全性地翻转升級
下边大家先来实践活动学习培训下K8s的Healthz Check作用,大家先来学习培训下K8s默认设置的健康检测体制:
每一个器皿运作时都是会实行一个过程,此过程是由Dockerfile的CMD 或 ENTRYPOINT来特定,当器皿内过程撤出时回到状态码为非零,则会觉得器皿发生了常见故障,K8s便会依据restartPolicy来重新启动这一器皿,以做到治愈的实际效果。
下边大家来动手能力实践活动下,仿真模拟一个器皿产生常见故障时的情景 :
# 先来转化成一个pod的yaml环境变量,并对其开展相对应改动
# kubectl run busybox --image=busybox --dry-run=client -o yaml > testHealthz.yaml
# vim testHealthz.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: busybox
name: busybox
spec:
containers:
- image: busybox
name: busybox
resources: {}
args:
- /bin/sh
- -c
- sleep 10; exit 1 # 并加上pod运作特定脚本制作指令,仿真模拟器皿运行10秒后产生常见故障,撤出状态码为1
dnsPolicy: ClusterFirst
restartPolicy: OnFailure # 将默认设置的Always改动为OnFailure
status: {}
重新启动对策 | 表明 |
---|---|
Always | 当器皿无效时,由kubelet自动关机该器皿 |
OnFailure | 当器皿停止运作且撤出码不以0时,由kubelet自动关机该器皿 |
Never | 无论器皿运作情况怎样,kubelet都不容易重新启动该器皿 |
实行配备建立pod
# kubectl apply -f testHealthz.yaml
pod/busybox created
# 观查数分钟,运用-w 主要参数来不断监视pod的情况转变
# kubectl get pod -w
NAME READY STATUS RESTARTS AGE
busybox 0/1 ContainerCreating 0 4s
busybox 1/1 Running 0 6s
busybox 0/1 Error 0 16s
busybox 1/1 Running 1 22s
busybox 0/1 Error 1 34s
busybox 0/1 CrashLoopBackOff 1 47s
busybox 1/1 Running 2 63s
busybox 0/1 Error 2 73s
busybox 0/1 CrashLoopBackOff 2 86s
busybox 1/1 Running 3 109s
busybox 0/1 Error 3 1m
busybox 0/1 CrashLoopBackOff 3 1m15s
busybox 1/1 Running 4 3M2s
busybox 0/1 Error 4 3M12s
busybox 0/1 CrashLoopBackOff 4 3M23s
busybox 1/1 Running 5 2m52s
busybox 0/1 Error 5 5m2s
busybox 0/1 CrashLoopBackOff 5 5m14s
上边能够见到这一检测pod被重新启动了5次,殊不知服务项目自始至终一切正常不上,便会维持在CrashLoopBackOff了,等候运维管理工作人员来开展下一步不正确清查
注:kubelet会以指数级的战不胜延迟时间(10s,20s,40s等)重启他们,限制为五分钟
这儿我们都是人为因素仿真模拟服务项目常见故障来开展的检测,在具体生产制造工作上,针对业务流程服务项目,大家怎样运用这类重新启动器皿来修复的体制来配备业务流程服务项目呢,回答是`liveness`检验
Liveness
Liveness检验使我们能够自定标准来分辨器皿是不是身心健康,假如检验不成功,则K8s会重新启动器皿,大家再来一个事例实践活动下,提前准备以下yaml配备并储存为liveness.yaml:
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness
spec:
restartPolicy: OnFailure
containers:
- name: liveness
image: busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 10 # 器皿运行 10 秒以后逐渐检验
periodSeconds: 5 # 每过 5 秒再检验一次
运行过程最先创建文件 /tmp/healthy,30 秒后删掉,在大家的设置中,假如 /tmp/healthy 文档存有,则觉得器皿处在一切正常情况,总之则产生常见故障。
livenessProbe 一部分界定怎样实行 Liveness 检验:
检验的方式 是:根据 cat 指令查验 /tmp/healthy 文档是不是存有。假如指令实行取得成功,传参为零,K8s 则觉得此次 Liveness 检验取得成功;假如指令传参非零,此次 Liveness 检验不成功。
initialDelaySeconds: 10 特定器皿运行 10 以后逐渐实行 Liveness 检验,大家一般会依据运用运行的提前准备時间来设定。例如某一运用一切正常运行要花 30 秒,那麼 initialDelaySeconds 的值就应当超过 30。
periodSeconds: 5 特定每 5 秒实行一次 Liveness 检验。K8s 假如持续实行 3 次 Liveness 检验均不成功,则会干掉并重新启动器皿。
然后来建立这一Pod:
# kubectl apply -f liveness.yaml
pod/liveness created
从环境变量得知,最初的 30 秒,/tmp/healthy 存有,cat 指令回到 0,Liveness 检验取得成功,这段时间 kubectl describe pod liveness 的 Events一部分会表明一切正常的日志
# kubectl describe pod liveness
......
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 53s default-scheduler Successfully assigned default/liveness to 10.0.1.203
Normal Pulling 52s kubelet Pulling image "busybox"
Normal Pulled 43s kubelet Successfully pulled image "busybox"
Normal Created 43s kubelet Created container liveness
Normal Started 42s kubelet Started container liveness
35 秒以后,日志会表明 /tmp/healthy 早已不会有,Liveness 检验不成功。再过几十秒,几回检验都不成功后,器皿会被重新启动。
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 3M53s default-scheduler Successfully assigned default/liveness to 10.0.1.203
Normal Pulling 73s (x3 over 3M52s) kubelet Pulling image "busybox"
Normal Pulled 62s (x3 over 3M43s) kubelet Successfully pulled image "busybox"
Normal Created 62s (x3 over 3M43s) kubelet Created container liveness
Normal Started 62s (x3 over 3M42s) kubelet Started container liveness
Warning Unhealthy 18s (x9 over 3M8s) kubelet Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
Normal Killing 18s (x3 over 1m58s) kubelet Container liveness failed liveness probe, will be restarted
除开 Liveness 检验,Kubernetes Health Check 体制还包含 Readiness 检验。
Readiness
我们可以根据Readiness检验来告知K8s何时能够将pod添加到服务项目Service的web服务池里,对外开放给予服务项目,这一在生产制造情景服务项目公布最新版本时十分关键,在我们发布的最新版本产生程序流程不正确时,Readiness会根据检验公布,进而不导进总流量到pod内,将服务项目的常见故障操纵在內部,在生产制造情景中,提议这个是必加的,Liveness不用都能够,由于有时大家必须保存服务项目打错的当场来查看日志,精准定位,告知开发设计来修补程序流程。
Readiness 检验的配备英语的语法与 Liveness 检验彻底一样,下边是个事例:
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness
spec:
restartPolicy: OnFailure
containers:
- name: liveness
image: busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600
readinessProbe: # 这儿将livenessProbe换为readinessProbe就可以,其他配备都一样
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 10 # 器皿运行 10 秒以后逐渐检验
periodSeconds: 5 # 每过 5 秒再检验一次
储存上边这一配备为readiness.yaml,并实行它转化成pod:
# kubectl apply -f readiness.yaml
pod/liveness created
# 观查,在一开始建立时,文档并沒有被删掉,因此检验一切正常
# kubectl get pod
NAME READY STATUS RESTARTS AGE
liveness 1/1 Running 0 50s
# 随后35秒后,文档被删掉,这个时候READY情况便会产生变化,K8s会断掉Service到pod的总流量
# kubectl describe pod liveness
......
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 56s default-scheduler Successfully assigned default/liveness to 10.0.1.203
Normal Pulling 56s kubelet Pulling image "busybox"
Normal Pulled 40s kubelet Successfully pulled image "busybox"
Normal Created 40s kubelet Created container liveness
Normal Started 40s kubelet Started container liveness
Warning Unhealthy 5s (x2 over 10s) kubelet Readiness probe failed: cat: can't open '/tmp/healthy': No such file or directory
# 能够见到pod的总流量被断掉,此刻即便 服务项目打错,对外部而言也是认知不上的,此刻大家运维管理工作人员就可以开展常见故障清查了
# kubectl get pod
NAME READY STATUS RESTARTS AGE
liveness 0/1 Running 0 61s
下边对 Liveness 检验和 Readiness 检验做一个较为:
Liveness 检验和 Readiness 检验是二种 Health Check 体制,如果不刻意配备,Kubernetes 将对二种检验采用同样的默认设置个人行为,即根据分辨器皿运行过程的传参是不是为零来分辨检验是不是取得成功。
二种检验的配备方式 彻底一样,适用的配备主要参数也一样。不同点取决于检验不成功后的个人行为:Liveness 检验是重新启动器皿;Readiness 检验则是将器皿设定为不能用,不接受 Service 分享的要求。
Liveness 检验和 Readiness 检验是单独实行的,二者之间沒有依靠,因此能够独立应用,还可以另外应用。用 Liveness 检验分辨器皿是不是必须重新启动以完成治愈;用 Readiness 检验分辨器皿是不是早已准备好对外开放给予服务项目。
Health Check 在 业务流程生产制造中翻转升级(rolling update)的应用领域
针对运维管理工作人员而言,将服务项目的最新项目编码升级发布,保证其平稳运作是一项很重要,且可重复性很高的每日任务,在模式下,大家一般是用saltsatck或是ansible等大批量可视化工具来消息推送编码到各台服务器上进行升级,那麼在K8s上,这一升级步骤就被简单化了,在后面高级章节目录我能讲到CI/CD自动化技术步骤,大概便是开发者开发设计好编码提交代码仓库即会开启CI/CD步骤,这中间基本上不用运维管理工作人员的参加。那麼在那么高宽比自动化技术的步骤中,大家运维管理工作人员如何保证服务项目能平稳发布呢?Health Check里边的Readiness 能充分发挥很重要的功效,这一实际上在上面也有讲过,这儿大家再以案例而言一遍,加重印像:
大家提前准备一个deployment資源的yaml文档
# cat myapp-v1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mytest
spec:
replicas: 10 # 这儿提前准备10个总数的pod
selector:
matchLabels:
app: mytest
template:
metadata:
labels:
app: mytest
spec:
containers:
- name: mytest
image: busybox
args:
- /bin/sh
- -c
- sleep 10; touch /tmp/healthy; sleep 30000
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 10
periodSeconds: 5
运作这一配备
# kubectl apply -f myapp-v1.yaml --record
deployment.apps/mytest created
# 等候一会,能够见到全部pod已一切正常运作
# kubectl get pod
NAME READY STATUS RESTARTS AGE
mytest-d9f48585b-2lmh2 1/1 Running 0 3M22s
mytest-d9f48585b-5lh9l 1/1 Running 0 3M22s
mytest-d9f48585b-cwb8l 1/1 Running 0 3M22s
mytest-d9f48585b-f6tzc 1/1 Running 0 3M22s
mytest-d9f48585b-hb665 1/1 Running 0 3M22s
mytest-d9f48585b-hmqrw 1/1 Running 0 3M22s
mytest-d9f48585b-jm8bm 1/1 Running 0 3M22s
mytest-d9f48585b-kxm1m 1/1 Running 0 3M22s
mytest-d9f48585b-lqpr9 1/1 Running 0 3M22s
mytest-d9f48585b-pk75z 1/1 Running 0 3M22s
然后大家来提前准备升级这一服务项目,而且人为因素仿真模拟版本号常见故障来开展观查,新提前准备一个配备myapp-v2.yaml
# cat myapp-v2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mytest
spec:
strategy:
rollingUpdate:
maxSurge: 35% # 翻转升级的团本数量最高值(以10的数量为例子):10 10 * 35% = 13.5 --> 14
maxUnavailable: 35% # 可以用团本数最高值(初始值2个全是25%): 10 - 10 * 35% = 6.5 --> 7
replicas: 10
selector:
matchLabels:
app: mytest
template:
metadata:
labels:
app: mytest
spec:
containers:
- name: mytest
image: busybox
args:
- /bin/sh
- -c
- sleep 30000 # 由此可见这儿并沒有转化成/tmp/healthy这一文档,因此下边的检验必定不成功
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 10
periodSeconds: 5
很显著这儿由于大家升级的这一v2版本号里边不容易转化成/tmp/healthy文档,那麼全自动是没法根据Readiness 检验的,详细信息以下:
# kubectl apply -f myapp-v2.yaml --record
deployment.apps/mytest configured
# kubectl get deployment mytest
NAME READY UP-TO-DATE AVAILABLE AGE
mytest 7/10 7 7 2m58s
# READY 如今已经运作的仅有七个pod
# UP-TO-DATE 表明当今早已进行升级的团本数:即 7 个新团本
# AVAILABLE 表明当今处在 READY 情况的团本数
# kubectl get pod
NAME READY STATUS RESTARTS AGE
mytest-7657789bc7-5hfkc 0/1 Running 0 3M2s
mytest-7657789bc7-7c5lg 0/1 Running 0 3M2s
mytest-7657789bc7-c96t6 0/1 Running 0 3M2s
mytest-7657789bc7-nbz2q 0/1 Running 0 3M2s
mytest-7657789bc7-pt86c 0/1 Running 0 3M2s
mytest-7657789bc7-q57gb 0/1 Running 0 3M2s
mytest-7657789bc7-x77cg 0/1 Running 0 3M2s
mytest-d9f48585b-6bnph 1/1 Running 0 5m4s
mytest-d9f48585b-965t4 1/1 Running 0 5m4s
mytest-d9f48585b-cvq7l 1/1 Running 0 5m4s
mytest-d9f48585b-hvpnq 1/1 Running 0 5m4s
mytest-d9f48585b-k89zs 1/1 Running 0 5m4s
mytest-d9f48585b-wkb4b 1/1 Running 0 5m4s
mytest-d9f48585b-wrkzf 1/1 Running 0 5m4s
# 上边能够见到,因为 Readiness 检验一直没根据,因此最新版本的pod全是Not ready情况的,那样就确保了不正确的业务流程编码不容易被外部要求到
# kubectl describe deployment mytest
# 下边提取一些这儿必须的重要信息内容
......
Replicas: 10 desired | 7 updated | 14 total | 7 available | 7 unavailable
......
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 5m55s deployment-controller Scaled up replica set mytest-d9f48585b to 10
Normal ScalingReplicaSet 3M53s deployment-controller Scaled up replica set mytest-7657789bc7 to 4 # 运行4个最新版本的pod
Normal ScalingReplicaSet 3M53s deployment-controller Scaled down replica set mytest-d9f48585b to 7 # 将旧版pod总数降到7
Normal ScalingReplicaSet 3M53s deployment-controller Scaled up replica set mytest-7657789bc7 to 7 # 增加3个运行至七个最新版本
综合性上边的剖析,大家很真正的仿真模拟一次K8s之前不正确的编码发布步骤,所幸的是这里有Health Check的Readiness检验帮大家屏蔽掉有不正确的团本,不会被外边的总流量要求到,另外保存了绝大多数旧版的pod,因而全部服务项目的业务流程并沒有因这此更新失败而遭受危害。
下面大家深入分析下翻转升级的基本原理,为何上边服务项目最新版本建立的pod总数是七个,另外只消毁了3个旧版的pod呢?
缘故就取决于这一段配备:
我们不显式配备这一段得话,初始值均是25%
strategy:
rollingUpdate:
maxSurge: 35%
maxUnavailable: 35%
翻转升级根据主要参数maxSurge和maxUnavailable来操纵pod团本总数的升级更换。
maxSurge
这一主要参数操纵翻转更新过程中pod团本数量超出设置总团本总数的限制。maxSurge 能够是实际的整数金额(例如 3),还可以是百分数,向上取整。maxSurge 初始值为 25%
在上面检测的事例里边,pod的总团本总数是10,那麼在更新过程中,总团本总数的限制大最值方案公式计算为:
10 10 * 35% = 13.5 –> 14
大家查询下升级deployment的叙述信息内容:
Replicas: 10 desired | 7 updated | 14 total | 7 available | 7 unavailable
旧版available 的总数七个 最新版本unavailable`的总数七个 = 总总数 14 total
maxUnavailable
这一主要参数操纵翻转更新过程中不能用的pod团本总总数的值,一样,maxUnavailable 能够是实际的整数金额(例如 3),还可以是百分之百,向下取整。maxUnavailable 初始值为 25%。
在上面检测的事例里边,pod的总团本总数是10,那麼要确保一切正常可以用的pod团本总数为:
10 – 10 * 35% = 6.5 –> 7
因此大家在上面查询的叙述信息内容里,7 available 一切正常可以用的pod总数值就为7
maxSurge 值越大,原始建立的新团本总数就越大;maxUnavailable 值越大,原始消毁的旧团本总数就越大。
一切正常升级理想化状况下,大家此次版本号公布实例翻转升级的全过程是:
- 最先建立4个最新版本的pod,使团本总总数做到14个
- 随后再消毁3个旧版的pod,使可以用的团本总数降为七个
- 当这3个旧版的pod被 取得成功消毁后,可再建立3个最新版本的pod,使总的团本总数维持为14个
- 当最新版本的pod根据Readiness 检验后,会使可以用的pod团本总数提升超出七个
- 随后能够再次消毁大量的旧版的pod,使总体可以用的pod总数返回七个
- 伴随着旧版的pod消毁,使pod团本总总数小于14个,那样就可以再次建立大量的最新版本的pod
- 这一增加消毁步骤会不断地开展,最后全部旧版的pod会被最新版本的pod慢慢更换,全部翻转升级进行
而大家这儿的具体情况是在第4步就卡住了,最新版本的pod总数没法能过Readiness 检验。上边的叙述信息内容最终面的事情一部分的日志也详细描述了这一切:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 5m55s deployment-controller Scaled up replica set mytest-d9f48585b to 10
Normal ScalingReplicaSet 3M53s deployment-controller Scaled up replica set mytest-7657789bc7 to 4 # 运行4个最新版本的pod
Normal ScalingReplicaSet 3M53s deployment-controller Scaled down replica set mytest-d9f48585b to 7 # 将旧版pod总数降到7
Normal ScalingReplicaSet 3M53s deployment-controller Scaled up replica set mytest-7657789bc7 to 7 # 增加3个运行至七个最新版本
这儿按一切正常的生产制造解决步骤,在获得充足的最新版本错误报告递交给开发设计剖析后,我们可以根据kubectl rollout undo 往返滚到上一个一切正常的服务项目版本号:
# 先查询下需要回退版本信息前边的数据,这儿为1
# kubectl rollout history deployment mytest
deployment.apps/mytest
REVISION CHANGE-CAUSE
1 kubectl apply --filename=myapp-v1.yaml --record=true
2 kubectl apply --filename=myapp-v2.yaml --record=true
# kubectl rollout undo deployment mytest --to-revision=1
deployment.apps/mytest rolled back
# kubectl get deployment mytest
NAME READY UP-TO-DATE AVAILABLE AGE
mytest 10/10 10 10 96m
# kubectl get pod
NAME READY STATUS RESTARTS AGE
mytest-d9f48585b-6bnph 1/1 Running 0 96m
mytest-d9f48585b-8nvhd 1/1 Running 0 1m13s
mytest-d9f48585b-965t4 1/1 Running 0 96m
mytest-d9f48585b-cvq7l 1/1 Running 0 96m
mytest-d9f48585b-hvpnq 1/1 Running 0 96m
mytest-d9f48585b-k89zs 1/1 Running 0 96m
mytest-d9f48585b-qs5c6 1/1 Running 0 1m13s
mytest-d9f48585b-wkb4b 1/1 Running 0 96m
mytest-d9f48585b-wprlz 1/1 Running 0 1m13s
mytest-d9f48585b-wrkzf 1/1 Running 0 96m
OK,到这儿截止,大家真正的仿真模拟了一次有什么问题的版本号公布及回退,而且能够见到,在这里全部全过程中,尽管发生了难题,但大家的业务流程仍然是沒有遭受一切危害的,这就是K8s的风采所属。
pod怪物作战(工作)
# 把上边全部升级及回退的实例,自身再检测一遍,留意观查在其中的pod转变,加重了解
关注不迷路
扫码下方二维码,关注宇凡盒子公众号,免费获取最新技术内幕!
评论0