k8s进阶-容器探测
容器探测用于检测容器中的应用实例是否正常工作,通过向目前容器周期性发出不同方式的探针,以检测目标实例的健康状态,k8s环境下微服务应用的健康监控是必不可少的环节,本章节也将结合springboot健康检查插件来整合支持k8s的容器探测1、存活探针不会等待就绪性探针成功2、如果就绪态探针实现不正确,可能会导致容器中进程的数量不断上升3、如果要在执行存活探针之前等待,可以使用或4、针对 HTTP 或
前言
容器探测用于检测容器中的应用实例是否正常工作,通过向目前容器周期性发出不同方式的探针,以检测目标实例的健康状态,k8s环境下微服务应用的健康监控是必不可少的环节,本章节也将结合springboot健康检查插件来整合支持k8s的容器探测
探针类型
存活探针- LivenessProbe
kubelet 使用存活探针来检测应用实例当前是否处于正常运行状态,确定什么时候需要重启容器。 例如,存活探针可以探测到应用死锁(应用程序在运行,但是无法继续执行后面的步骤)情况。重启探测失败状态的容器有助于提高应用的可用性
就绪探针- ReadinessProbe
kubelet 使用就绪探针可以知道容器何时准备好接受请求流量,当一个 Pod 内的所有容器都就绪时,才能认为该 Pod 就绪。这种信号的一个用途就是控制哪个 Pod 作为 Service 的后端,若 Pod 就绪探测失败,会被从 Service 的负载均衡列表中剔除
启动探针- StartupProbe
kubelet 使用启动探针来了解应用容器何时启动。 如果配置了这类探针,就可以控制容器在启动成功后再进行存活性[liveness]和就绪态[readiness]的检查, 确保存活、就绪探针不会影响应用的启动。 启动探针可以用于对慢启动容器进行存活性检测,避免它们在启动运行之前就被杀掉
探针参数
探针有很多配置参数,可以使用这些参数精确地控制启动、存活和就绪检测的行为
initialDelaySeconds
:容器启动后要等待多少秒后才启动存活、就绪和启动探针, 默认是 0 秒,最小值是 0periodSeconds
:执行探测的时间间隔(单位是秒),默认是 10 秒,最小值是 1timeoutSeconds
:探测的超时后等待多少秒,默认值是 1 秒,最小值是 1successThreshold
:连续探测成功多少次才被认定为执行成功,默认值是 1,存活和启动探测的这个值必须是 1,最小值是 1failureThreshold
:连续探测失败多少次才被认定为执行失败。 对于存活探测而言,失败就意味着重新启动容器。 对就绪探测而言,失败意味着 Pod 会被打上未就绪的标签,默认值是 3,最小值是 1
探测方式
Exec命令 - 以存活探针为例
创建文件exec-liveness.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
app: liveness
name: liveness-exec
namespace: probe
spec:
containers:
- name: nginx
image: nginx:latest
args:
- /bin/sh
- -c
- touch /tmp/liveness; sleep 30; rm -f /tmp/liveness; sleep 100
livenessProbe:
exec:
command:
- cat
- /tmp/liveness
initialDelaySeconds: 5
periodSeconds: 5
在配置文件中,periodSeconds
字段指定了 kubelet 每 5 秒执行一次存活探测。initialDelaySeconds
指定 kubelet 在执行第一次探测前应该等待 5 秒。 kubelet 在容器内执行命令 cat /tmp/liveness
来进行探测, 如果命令执行成功并且返回值为 0,kubelet 就会认为这个容器是健康存活的,如果这个命令返回非0值,kubelet 会杀死这个容器并重新启动它
在容器启动时,将执行如下命令:
/bin/sh -c "touch /tmp/liveness; sleep 30; rm -f /tmp/liveness; sleep 300"
容器生命的前 30 秒,/tmp/liveness 文件是存在的,即在容器启动后的 30 秒内,执行命令 cat /tmp/liveness
会返回成功,30 秒之后文件被删除,再次执行命令 cat /tmp/liveness
时就会返回失败,kubectl则会对容器进行重启操作
创建Pod
$ kubectl apply -f ./exec-liveness.yaml
30秒内查看pod的状态
$ kubectl describe pod liveness-exec -n probe
输出结果显示pod创建成功
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 38s default-scheduler Successfully assigned probe/liveness-exec to k8s-node1
Normal Pulling 37s kubelet Pulling image "nginx:latest"
Normal Pulled 22s kubelet Successfully pulled image "nginx:latest" in 15.416721868s
Normal Created 22s kubelet Created container nginx
Normal Started 22s kubelet Started container nginx
等到35秒再次查看pod的状态,显示liveness探测失败,Container nginx failed liveness probe, will be restarted\n Container nginx failed liveness probe, will be restarted
,容器被重启
$ kubectl describe pod liveness-exec -n probe
----------------------------------------------
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 3m26s default-scheduler Successfully assigned probe/liveness-exec to k8s-node1
Normal Pulled 3m11s kubelet Successfully pulled image "nginx:latest" in 15.416721868s
Normal Pulled 104s kubelet Successfully pulled image "nginx:latest" in 15.370383805s
Warning Unhealthy 60s (x6 over 2m40s) kubelet Liveness probe failed: cat: /tmp/healthy: No such file or directory
Normal Killing 60s (x2 over 2m30s) kubelet Container nginx failed liveness probe, will be restarted
Normal Pulling 30s (x3 over 3m26s) kubelet Pulling image "nginx:latest"
Normal Created 14s (x3 over 3m11s) kubelet Created container nginx
Normal Started 14s (x3 over 3m11s) kubelet Started container nginx
Normal Pulled 14s kubelet Successfully pulled image "nginx:latest" in 15.368988721s
此时查看pod状态,显示容器重启次数增加了1
$ kubectl get pod liveness-exec -n probe
--------------------------------------------------------
NAME READY STATUS RESTARTS AGE
liveness-exec 0/1 CrashLoopBackOff 1 1m
HttpGet - 以存活探针为例
创建文件http-liveness.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
app: liveness
name: liveness-http
namespace: probe
spec:
containers:
- name: nginx
image: nginx:latest
livenessProbe:
httpGet:
path: /
port: 80
scheme: HTTP
httpHeaders:
- name: Accept
value: application/json
initialDelaySeconds: 5
periodSeconds: 5
在配置文件中,periodSeconds
指定了 kubelet 应该每 5 秒执行一次存活探测,initialDelaySeconds
指定 kubelet 在容器启动后等待 5 秒再开始探测。kubelet 会向容器内运行的服务(host-默认为pod的ip,port为80)发送一个HTTP GET 请求来执行探测, 如果服务器上 "/"
路径下的处理程序返回成功,则 kubelet 认为容器是健康存活的,如果处理程序返回失败,则 kubelet 会杀死这个容器并将其重启
判断标准:返回大于或等于 200 并且小于 400 的任何代码都标示成功,其它返回代码都标示失败
创建pod
$ kubectl apply -f ./http-liveness.yaml
容器启动后,控测的地址http://podid:80/
为nginx服务的首页,即能正常返回200状态码,pod状态显示创建成功
$ kubectl describe pod -n probe
----------------------------------------------------------------------
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 42s default-scheduler Successfully assigned probe/liveness-http to k8s-node1
Normal Pulling 42s kubelet Pulling image "nginx:latest"
Normal Pulled 26s kubelet Successfully pulled image "nginx:latest" in 16.461481089s
Normal Created 26s kubelet Created container nginx
Normal Started 26s kubelet Started container nginx
----------------------------------------------------------------------
$ kubectl get pod -n probe
NAME READY STATUS RESTARTS AGE
liveness-http 1/1 Running 0 1m
接着修改yaml文件,指定path路径为 "/abc"
,脚本片断如下:
containers:
- name: nginx
image: nginx:latest
livenessProbe:
httpGet:
#修改路径为/abc
path: /abc
port: 80
scheme: HTTP
此时,kubelet访问的探测地址为http://podid:80/abc
,因容器内nginx服务不存在该路径地址,则会返回404状态码,查看pod状态显示健康检查失败,Liveness probe failed: HTTP probe failed with statuscode: 404
,kubelet 会杀死容器并再次重新启动容器
$ kubectl describe pod liveness-http -n probe
------------------------------------------------------------------
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 34s default-scheduler Successfully assigned probe/liveness-http to k8s-node1
Normal Pulled 19s kubelet Successfully pulled image "nginx:latest" in 15.467613921s
Normal Created 19s kubelet Created container nginx
Normal Started 18s kubelet Started container nginx
Normal Pulling 3s (x2 over 34s) kubelet Pulling image "nginx:latest"
Warning Unhealthy 3s (x3 over 13s) kubelet Liveness probe failed: HTTP probe failed with statuscode: 404
Normal Killing 3s kubelet Container nginx failed liveness probe, will be restarted
TcpSocket - 以就绪探针和存活探针为例
TCP 检测的配置和 HTTP 检测方式相近,只需要配置端口即可。如果能建立连接,这个容器就被看作是健康的,脚本片断如下:
containers:
- name: nginx
image: nginx:latest
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 15
periodSeconds: 20
gRPC - 以存活探针为例
在 Kubernetes 1.23 之前,gRPC 健康探测通常使用 grpc-health-probe 来实现。v1.24版本以后就可以使用内置gRPC探针,但必须先启用 GRPCContainerProbe 特性门控才能配置依赖于 gRPC 的检查机制。因gRPC探测容器存活的方式比较少见,这里暂不做详细描述,参考博客地址:https://kubernetes.io/blog/2018/10/01/health-checking-grpc-servers-on-kubernetes/
脚本片断如下:
containers:
- name: nginx
image: nginx:latest
livenessProbe:
grpc:
port: 2379
initialDelaySeconds: 10
集成SpringBoot Actuator
一、配置pom.xml,引入actuator模块
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
二、配置application.properties,定义liveness和readiness分组
management.endpoint.health.probes.enabled=true
management.endpoint.health.group.liveness.include=livenessState,ping
management.endpoint.health.group.readiness.include=readinessState
#配置health Endpoints暴露在web环境下(即可通过url访问)
management.endpoints.web.exposure.include=health,info
#默认为/actuator
management.endpoints.web.basePath=/actuator
样例中liveness分组会执行LivenessStateHealthIndicator和PingHealthIndicator两个检查器,当两个检查器状态同时为UP时,liveness分组状态为UP,访问路径http://localhost:8080/actuator/health/liveness
响应:{"status":"UP","components":{"livenessState":{"status":"UP"},"ping":{"status":"UP"}}}
样例中readiness分组只执行ReadinessStateHealthIndicator检查器,访问路径http://localhost:8080/actuator/health/readiness
响应:{"status":"UP","components":{"readinessState":{"status":"UP"}}}
三、配置K8S容器检测 - 存活探针和就绪探针,yaml文件片断如下:
livenessProbe:
failureThreshold: 3
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 6
httpGet:
path: /actuator/health/liveness
port: 8080
scheme: HTTP
readinessProbe:
failureThreshold: 3
periodSeconds: 15
successThreshold: 3
timeoutSeconds: 3
httpGet:
path: /actuator/health/readiness
port: 8080
scheme: HTTP
总结
1、存活探针
不会等待就绪性探
成功后再开始探测
2、如果就绪态探
针实现不正确,可能会导致容器中进程的数量不断上升
3、如果要在执行存活探针
之前等待,可以使用 initialDelaySeconds
参数 或 startupProbe
探针
4、针对 HTTP 或 TCP 探测,通过将启动探针
failureThreshold * periodSeconds 参数设置为足够长的时间来保护慢启动容器
(完)
更多推荐
所有评论(0)