我们在K8s环境上面有个deployment,包括xx-service和telegraf两个container,xx-service提供8080端口的/metrics path给telegraf提供metrics,以及/healthcheck path给livenessP在增加了telegraf之后,查看pod的状态,一直是pod在重启, 就像这样
检查两个container各自的log
telegraf:
E! [inputs.prometheus] Error in plugin: error making HTTP request to http://localhost:8080/metrics: Get "http://localhost:8080/metrics": dial tcp 127.0.0.1:8080: connect: connection refused
xx-service
INFO: 127.0.0.1:32848 - "GET /metrics HTTP/1.1" 200 OK
INFO: 127.0.0.1:32869 - "GET /healthcheck HTTP/1.1" 200 OK
初看之下是telegraf连metrics被拒的错误,但是xx-service里面/metrics 明明是正确的返回,telegraf在本地测试是通过的,conf没有问题,不应该有链接的问题.继续看xx-service, describe一下pod
Warning Unhealthy 26m (x28 over 40m) kubelet Liveness probe failed:
Warning BackOff 73s (x153 over 38m) kubelet Back-off restarting failed container
好家伙,是livenessProbe一直失败导致k8s认为pod并不处于健康中,强行restart了这个pod, describe中有143(SIGTERM)的return code, 但是liveness probe failed: 后面没有任何信息
livenessProbe我们配的是python scripts, 难道是python script执行的问题,进入pod container,执行python scripts,检查返回值0,奇了怪了
后来我们尝试:
livenessProbe加上 initialDelaySeconds和failureThreshold的值(以为xx-service container来不及启动成功,livenessProbe就已经执行了)
pyhon3 用绝对路径
/bin/sh -c
当然这些都是不能奏效的
最终的罪魁祸首是 timeoutSeconds 探测超时时间。默认 1 秒,最小 1 秒。
因为我们提供的healthcheck不光是check xx-service本身,还有其它的依赖组件的连接检查,像db, vCenter等, 这就导致service在1秒内无法返回,livenessProbe healthcheck超时退出, 最终导致telegraf无法连接到一直处于restart中的xx-service的/metrics
containers:
- name: xxx
image: xxx
# 存活检查
livenessProbe:
httpGet:
scheme: HTTP # 协议
path: /actuator/health # 路径
port: 8080 # 端口
initialDelaySeconds: 30 # 延迟探测时间(秒) 【 在k8s第一次探测前等待秒 】
periodSeconds: 10 # 执行探测频率(秒) 【 每隔秒执行一次 】
timeoutSeconds: 1 # 超时时间
successThreshold: 1 # 健康阀值
failureThreshold: 3 # 不健康阀值
- timeoutSeconds:探测超时的秒数。默认为1秒。最小值为1。
- initialDelaySeconds:启动活动或准备就绪探测之前容器启动后的秒数。
- periodSeconds:执行探测的频率(以秒为单位)。默认为10秒。最小值为1。
- failureThreshold:当Pod启动并且探测失败时,Kubernetes会failureThreshold在放弃之前尝试一次。在活动探测的情况下放弃意味着重新启动Pod。如果准备好探测,Pod将被标记为未准备好。默认为3.最小值为1。
- successThreshold:失败后探测成功的最小连续成功次数。默认为1.活跃度必须为1。最小值为1。