背景: 使用k8s过程中由于服务存在bug导致业务中断,所以需要增加健康检查,主要参考k8s的文档
docker提供的健康检查能力
在容器化场景下,对于容器的健康检查可能通过在制作docker镜像时的dockerfile中增加HEALTHCHECK指令(仅能有一条)的方式进行,HEALTHCHECK指令主要有两种形式:
- HEALTHCHECK [OPTIONS] CMD command : 通过在容器中运行命令来进行健康检查
- HEALTHCHECK NONE : 禁止任何健康检查
当容器指定了健康检查指令后,容器的状态将多出一种健康状态,健康状态初始化为starting,当健康检查指令执行通过后,状态转为healthy,如果容器健康检查失败了,将转为unhealthy 对于OPTIONS可以指定以下的参数
- --interval=DURATION (默认值: 30s)
- --timeout=DURATION (默认值: 30s)
- --start-period=DURATION (默认值: 0s)
- --retries=N (默认值: 3) 健康检查将在容器启动后interval时间后第一次执行,并在上一次执行完后间隔interval时间执行,如果健康检查命令执行的时间超过了timeout参数值,则会判定执行失败,retries参数表示连续执行retries次健康检查均失败后才会判断容器为unhealthy,start-period表示容器启动后的初始化时间,在这期间内的健康检查失败将不会计数
对于CMD命令,命令的返回值表示了容器的健康检查状态,一共有三种
- 0: success - the container is healthy and ready for use
- 1: unhealthy - the container is not working correctly
- 2: reserved - do not use this exit code 示例:
HEALTHCHECK --interval=5m --timeout=3s \
CMD curl -f http://localhost/ || exit 1
k8s提供的健康检查能力
k8s不支持通过docker的HEALTHCHECK来进行容器的健康检查(Docker Swarm可以-但是我没用过),但是k8s自身提供了两种类似于健康检查的能力
- livenessProbe 检查是否需要重启pod,检查不重启就无法恢复的异常
- readnessProbe 检查容器是否就绪,如果未就绪,loadbalancer不会分发流量到这个pod的endpoint
使用方法
在pod的containers中定义livenessProbe或readnessProbe
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-exec
spec:
containers:
- name: liveness
image: k8s.gcr.io/busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
支持的健康检查方式
命令(脚本)健康检查
通过在容器中执行命令(脚本)的方式来获取容器的状态,脚本或命令返回0时表示成功,否则表示失败(如果容器指定了用户,则会以对应用户去执行,所以注意使用脚本时需要相应的权限)
livenessProbe:
exec:
command:
- /bin/bash
- /home/test/healthcheck.sh
initialDelaySeconds: 5
periodSeconds: 5
HTTP健康检查
通过发送HTTP GET请求的方式获取容器状态,返回状态码>=200且<400时表示状态正常,否则表示失败,支持自定义HTTP Header(在1.13版本前如果容器内定义了http_proxy环境变量,则在发送请求时会使用proxy,1.13及以后版本中不会再受此影响)
livenessProbe:
httpGet:
path: /healthcheck
port: 1888
httpHeaders:
- name: Custom-Header
value: Test
initialDelaySeconds: 3
periodSeconds: 3
http检查的一些字段
port: 端口
path: uri
httpHeaders: 请求头
host: 主机名,默认值时pod自身的ip地址(没用过,也许多网络平面场景下需要使用)
scheme: HTTP/HTTPS 默认HTTP
TCP健康检查
通过tcp socket建立连接的方式去判断容器状态,如果能够建连成功,则判断状态正常,否则异常
livenessProbe:
tcpSocket:
port: 1888
initialDelaySeconds: 15
periodSeconds: 20
健康检查的配置
除了健康检查方式外,还有一些参数用于控制健康检查的的行为
- initialDelaySeconds: 容器启动后多长时间开始进行健康检查
- periodSeconds: 健康检查的周期(默认10 最小1)
- timeoutSeconds: 检查的超时时间(默认1 最小1)
- successThreshold: 健康检查失败后多少次成功才判断容器状态为成功,默认为1,对于livenessProbe必须为1(对于livenessProbe没有必要配置这个参数)
- failureThreshold: 多少次健康检查失败后判断容器状态为failed(默认3 最小1)
参考
https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/