k8s探针
健康检查(Health Check)用于检测应用实例是否正常工作,是保障业务可用性的一种传统机制,一般用于负载均衡下的业务,如果实例的状态不符合预期,将会把该实例“摘除”,不承担业务流量。
Kubernetes中的健康检查使用存活性探针(liveness probes)和就绪性探针(readiness probes)来实现,对于慢启动容器还专门设有启动探针(startup Probe)。
探测方式
在讨论探针具体的功能和目的之前,先了解一下探针的具体探测方式。无论是存活探针、就绪探针还是启动探针的探测都是由kubelet执行的,K8S提供了三种探测容器的方式:
-
exec:在容器内执行shell命令,根据命令退出状态码是否为0判定成功失败;
exec: #探针类型为exec探针 command: - cat #表示cat /usr/share/nginx/html/index.html文件,根据命令执行 - /usr/share/nginx/html/index.html #结果返回状态是否非0来表示探针状态 -
httpGet:根据容器IP地址、端口号、路径发送http get请求,返回200-400范围内的状态码表示成功;(生产环境建议使用这种)
httpGet: #探针类型为httpGet探针 # host: 10.244.0.49 #指定主机,默认是pod的ip,一般省略不写 path: / #路径 port: 80 #端口 -
tcpSocket:与容器IP地址、端口建立TCP Socket链接,能建立则表示成功;
tcpSocket: #探针类型为tcpSocket探针 # host: 10.244.0.49 #指定主机,默认是pod的ip,一般省略不写 port: 80 #探测与80端口是否能成功建立tcp链接
探针
存活探针
在kubernetes中可以通过存活探针检查容器是否还在运行,可以为pod中的每个容器单独定义存活探针,而每个node节点上的组件kubelet将负责定期执行探针,如果探测失败,将杀死容器,并根据restartPolicy策略来决定是否重启容器。
在exec、httpGet和tcpSocket三种探测方式的基础上,存活探针还有以下几个附加属性:
initialDelaySeconds:表示在容器启动后延时多久秒才开始探测;periodSeconds:表示执行探测的频率,即间隔多少秒探测一次,默认间隔周期是10秒,最小1秒;timeoutSeconds:表示探测超时时间,默认1秒,最小1秒,表示容器必须在超时时间范围内做出响应,否则视为本次探测失败;successThreshold:表示最少连续探测成功多少次才被认定为成功,默认是1,对于liveness必须是1,最小值是1;failureThreshold:表示连续探测失败多少次才被认定为失败,默认是3,连续3次失败,k8s 将根据pod重启策略对容器做出决定;
[!NOTE]
定义存活探针时,一定要设置initialDelaySeconds属性,该属性为初始延时,如果不设置,默认容器启动时探针就开始探测了,这样可能会存在应用程序还未启动就绪,就会导致探针检测失败,kubelet就会根据pod重启策略杀掉容器然后再重新创建容器的莫名其妙的问题。
nginx应用,httpGet探活:
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: rs-nginx-http
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: nginx-rs
matchExpressions:
- {key: env, operator: In, values: [dev]}
template:
metadata:
labels:
app: nginx-rs
env: dev
spec:
containers:
- image: nginx:1.7.9
name: nginx-container
ports:
- containerPort: 80
livenessProbe: #为容器定义一个存活探针
httpGet: #探针类型为httpGet探针
# host: 10.244.0.49 #指定主机,默认是pod的ip,一般省略不写
path: / #路径
port: 80 #端口
initialDelaySeconds: 15 #初始延时时间为15s
periodSeconds: 5 #探测周期
timeoutSeconds: 2 #超时时间
failureThreshold: 9 #失败次数
就绪探针
当一个pod启动后,就会立即加入service的endpoint ip列表中,并开始接收到客户端的链接请求,假若此时pod中的容器的业务进程还没有初始化完毕,那么这些客户端链接请求就会失败,为了解决这个问题,kubernetes提供了就绪探针来解决这个问题的。
在pod中的容器定义一个就绪探针,就绪探针周期性检查容器,如果就绪探针检查失败了,说明该pod还未准备就绪,不能接受客户端链接,则该pod将从endpoint列表中移除,被剔除了service就不会把请求分发给该pod,然后就绪探针继续检查,如果随后容器就绪,则再重新把pod加回endpoint列表。
nginx应用,httpGet就绪探测:
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: rs-nginx-http
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: nginx-rs
matchExpressions:
- {key: env, operator: In, values: [dev]}
template:
metadata:
labels:
app: nginx-rs
env: dev
spec:
containers:
- image: nginx:1.7.9
name: nginx-container
ports:
- containerPort: 80
readinessProbe: #为容器定义一个存活探针
httpGet: #探针类型为httpGet探针
# host: 10.244.0.49 #指定主机,默认是pod的ip,一般省略不写
path: /reader #路径
port: 80 #端口
initialDelaySeconds: 10 # 容器启动后多久开始探测
timeoutSeconds: 2 # 表示容器必须在2s内做出相应反馈给probe,否则视为探测失败
periodSeconds: 30 # 探测周期,每30s探测一次
successThreshold: 1 # 连续探测1次成功表示成功
failureThreshold: 3 # 连续探测3次失败表示失败
启动探针
对于慢启动容器来说,存活探针和就绪探针这两种健康检查机制不太好用。
慢启动容器:指需要大量时间(一到几分钟)启动的容器。启动缓慢的原因可能有多种:
- 长时间的数据初始化:只有第一次启动会花费很多时间。
- 负载很高:每次启动都花费很多时间。
- 节点资源不足/过载:即容器启动时间取决于外部因素。
这种容器的主要问题在于,在存活探针失败之前,应该给它们足够的时间来启动它们。对于这种问题,现有的机制的处理方式为:
- 方法一:livenessProbe中把延迟初始时间 initialDelaySeconds 设置的很长,以允许容器启动(即initialDelaySeconds大于平均启动时间)。虽然这样可以确保 livenessProbe不会检测失败,但是不知道 initialDelaySeconds 应该配置为多少,因为启动时间不是一个固定值。另外,因为 livenessProbe 在启动过程还没运行,因此 Pod 得不到反馈,Events 看不到内容,如果 initialDelaySeconds 是 10 分钟,那这 10 分钟内你不知道在发生什么。
- 方法二:增加 livenessProbe 的失败次数。即 failureThreshold*periodSeconds 的乘积足够大,这样可以挺过容器启动,虽然简单粗暴,但是在容器在初次成功启动后,由于livenessProbe 的失败次数过大,就算容器死锁或以其他方式挂起,livenessProbe 也会不断探测到,这样就失去了存活检查的意义。
[!NOTE]
livenessProbe的设计是为了在 Pod 启动成功后进行健康探测,最好前提是 Pod 已经启动成功,在启动阶段的多次失败是没有意义的。
以上两种方式都可以对慢启动容器进行监控检查,但都不够优雅。因此官方提出了一种新的探针:即startupProbe,startupProbe并不是一种新的数据结构,他完全复用了livenessProbe,只是名字改了下,多了一种概念。
startupProbe:
httpGet:
path: /healthz
port: liveness-port
failureThreshold: 30
periodSeconds: 10
这个配置的含义是:
startupProbe首先检测,该应用程序最多有5分钟(30 * 10 = 300s)完成启动。一旦startupProbe成功一次,livenessProbe将接管,以对后续运行过程中容器死锁提供快速响应。如果startupProbe从未成功,则容器将在300秒后被杀死。
探针对比
如果不特意配置这三种健康检查机制,Kubernetes 将采取的默认机制,即通过判断容器启动主进程的返回值是否为零来判断探测是否成功。
startupProbe 完全复用了 livenessProbe,只是名字改了下,多了一种概念,startupProbe常用于慢启动程序,启动探针只在容器启动期间起作用,在容器成功启动后*不会*继续执行定期的监控检查。
Liveness 探测和 Readiness 探测配置方法完全一样,支持的配置参数也一样。不同之处在于探测失败后的行为:Liveness 探测是重启容器;Readiness 探测则是将容器设置为不可用,不接收 Service 转发的请求。
Liveness 探测和 Readiness 探测是独立执行的,二者之间没有依赖,所以可以单独使用,也可以同时使用。
用 Liveness 探测判断容器是否需要重启以实现自愈;用 Readiness 探测判断容器是否已经准备好对外提供服务。Readiness可用于指定容器启动后,判断容器各服务是否已正常启动(如启动脚本执行后写指定内容至特定文件)。

浙公网安备 33010602011771号