Health Check
健康检查,直白点说就是防微杜渐,k8s是一个编排引擎我们通过k8s部署容器集群,如果说集群容器没有健康检查这个过程,我们无法预知我们生产环境会不会部署上错误的容器导致服务崩溃。好在k8s 帮我们考虑到了这个问题,健康检查是k8s重要特性之一,默认有健康检查,还可以主动设置一些健康检查。
接下来我们一步步深入了解下k8s的健康检查。
1. 默认的健康检查
dockerfile制作镜像的时候,我们CMD,ENTRYPOINT会指定运行命令,容器完成指令之后退出时返回码非零,则判定发生故障,然后根据 restartPolicy 策略重启容器。默认的重启策略是Always 。
healthcheck.yml
apiVersion: v1
kind: Pod
metadata:
labels:
test: healthcheck
name: healthcheck
spec:
restartPolicy: OnFailure
containers:
- name: healthcheck
image: busybox
args:
- /bin/sh
- -c
- sleep 10; exit 1
参数解析
restartPolicy: OnFailure 重启的策略是失败便重启
args 是容器启动后运行的命令
资源管理
创建资源
kubectl apply -f healthy.yml
查看pod状态
kubectl get pod healthcheck
可以发现RESTARTS已经重启多次。
优缺点
优点:可以通过restartPolicy 的策略,解决一下重启就能解决的问题
缺点:必须等到进程退出后的返回值是非零才会触发重启策略,不能直接监测容器是否是健康
2. liveness 探测的健康检查
liveness 的功能就是我们可以自己定义判断容器健康的条件,然后去监测容器是否满足健康条件,不健康执行重启自愈。
liveness.yml
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 -rf /tmp/healthy; sleep 600
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 10
periodSeconds: 5
参数解析
livenessProbe 定义判断容器健康的条件
exec 交互输入界面
command 命令行命令
initialDelaySeconds 设置容器启动后多久执行liveness
periodSeconds 指定每隔多久执行一次liveness
如果三次liveness 探测都失败了,容器就会重启
资源管理
kubectl apply -f liveness.yml
kubectl get pod liveness
3. readiness 探测的健康检查
判断容器何时可以进入service 负载均衡池中,例如在滚动更新过程中,判断更新的容器是否满足条件能够完成业务,不符合的暂停更新,保证有足够多的业务容器能正常工作。
readiness.yml
apiVersion: v1
kind: Pod
metadata:
labels:
test: readiness
name: readiness
spec:
restartPolicy: OnFailure
containers:
- name: readiness
image: busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 10
periodSeconds: 5
readinessProbe 定义判断容器健康的条件
这里会经历三个过程:
过程一:刚被创建时,pod不可用
过程二:15秒后第一次探测成功,pod设置可用
过程三:30秒后监测文件被删除,连续三次的探测失败之后,pod设置不可用
资源管理
kubectl apply -f readiness.yml
kubectl get pod readiness
4. Scale up中的运用Health Check
scaleupcheck.yml
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
template:
metadata:
labels:
run: web
spec:
containers:
- name: web
image: httpd
ports:
- containerPort: 80
readinessProbe:
httpGet:
scheme: HTTP
port: 80
initialDelaySeconds: 10
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: web-svc
spec:
selector:
run: web
ports:
- protocol: TCP
port: 8080
targetPort: 80
参数说明
readinessProbe 定义判断容器健康的条件
httpGet 一种探测方式,需要返回的代码在200~400之间
scheme 指定协议,支持http和https
port 指定端口
path 指定路径
由yml文件可知,我们设置pod容器端口80和服务端口8080绑定,实际监测的是容器的端口
资源管理
kubectl apply -f scaleupcheck.yml
kubectl get deployment
kubectl get pod web -o wide
kubectl get service
5. 滚动更新中运用Healthy Check
解决了副本正常运行需要准备时间,配置错误副本无法完成准备工作。
说白了就是更新的时候,默认的Healthy Check认为副本已经准备好了,逐步用新的副本替换旧的副本,直至完成所有的更新。配置错误的副本替换了旧副本这样会导致生产环境中服务无法正常访问。
rollingupdatecheckv1.yml
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: app
spec:
replicas: 10
template:
metadata:
labels:
run: app
spec:
containers:
- name: app
image: busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 3000
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 10
periodSeconds: 5
rollingupdatecheckv2.yml
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: app
spec:
replicas: 10
template:
metadata:
labels:
run: app
spec:
containers:
- name: app
image: busybox
args:
- /bin/sh
- -c
- sleep 3000
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 10
periodSeconds: 5
资源管理
kubectl apply -f rollingupdatecheckv1.yml --record
等待几分钟,待资源创建成功后,我们执行更新
kubectl apply -f rollingupdatecheckv2.yml --record
我们查看资源会发现
kubectl get deployment app
DESIRED 期望状态是10个READY的副本
CURRENT 表示当前的副本总数是13
UP-TO-DATE 已完成的更新数是5个
AVAILABLE 表示当前处于READY状态的副本数是8个
为什么会这样呢?13个副本是怎么产生的?为什么更新了5个副本,旧副本还要8个?
滚动更新时 maxSurge和 maxUnavailable 负责副本数替换
maxSurge
控制副本数的上限
roundUp向上取整
目标副本是10的话,默认情况下,maxSurge=roundUp(10+10*25%)=13
maxUnavailable
控制不可用副本数的上限
roundDown向下取整
目标副本是10的话,默认情况下,10 - roundDown(10*25)=8
所以滚动升级的过程是
过程一: 创建三个新副本,副本总是达到13
过程二: 销毁两个旧副本,可用的旧副本剩下8
过程三: 创建两个新副本,总副本数为13,旧副本为8,新副本为5
过程四: readiness 探测成功之后,继续替换副本,失败便停止
过程五: 重复上述过程,直至所有旧副本被新副本替换
我们测试过程中,v2版本readiness是无法监测通过的,所有副本数保持13个,5个新副本,8个可以使用的旧副本。8个旧副本将继续提供服务,确保生产环境的稳定。
閱讀更多 崔格拉斯 的文章