容器探针和生命周期回调学习
- [1. 容器探针](#1. 容器探针)
-
- [1.1. 探针类型](#1.1. 探针类型)
- [1.2. 检查机制](#1.2. 检查机制)
- [1.3. 探测结果](#1.3. 探测结果)
- [1.4. 实验](#1.4. 实验)
- 2.容器生命周期回调
-
- [2.1. 什么是容器生命周期回调](#2.1. 什么是容器生命周期回调)
- [2.2. PostStart和PreStop回调介绍](#2.2. PostStart和PreStop回调介绍)
- [2.3. 如何实现回调](#2.3. 如何实现回调)
- [2.4. 通过实验来完成](#2.4. 通过实验来完成)
1. 容器探针
官网文档介绍:https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/pod-lifecycle/#container-probes
1.1. 探针类型
探针名称 | 作用 | 使用场景 |
---|---|---|
livenessProbe | 存活探针,当存活探针检测失败,kubelet会杀死容器,并根据重启策略决定是否重启容器,不设置重启探针默认为Success | 适用于容器内进程在,但是服务已经出现问题了,比如访问时报500无法正常处理请求的进程。 |
readinessProbe | 就绪探针,当就绪探针检测失败, EndpointSlice 控制器将把包含这个Pod的Service中的EndpointSlice 中删除该 Pod 的 IP 地址,如果设置了延时探测,在延时这段时间状态为Failure,不设置就绪探针默认是Success | 适用于,将已经完全准备接收请求的容器加入到service的EndpointSlice |
startupProbe | 启动探针,如果使用了启动探针,其他探针会暂时被禁用,直到启动探针成功后,如果探针失败,kubelet会根据启动策略决定是否重启容器,没有设置探针,默认是Success | 使用与容器内的服务,启动时需要等待一段时间 |
1.2. 检查机制
k8s提供四种探针来检查容器的运行状态:
探针名称 | 如何使用 |
---|---|
exec | 在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功。 |
grpc | 使用 gRPC 执行一个远程过程调用。 目标应该实现 gRPC 健康检查。 如果响应的状态是 "SERVING",则认为诊断成功。 |
httpGet | 对容器的 IP 地址上指定端口和路径执行 HTTP GET 请求。如果响应的状态码大于等于 200 且小于 400,则诊断被认为是成功的。 |
tcpSocket | 对容器的 IP 地址上的指定端口执行 TCP 检查。如果端口打开,则诊断被认为是成功的。 如果远程系统(容器)在打开连接后立即将其关闭,这算作是健康的。 |
使用exec 容器时需要注意:
和其他机制不同,exec 探针的实现涉及每次执行时创建/复制多个进程。 因此,在集群中具有较高 pod 密度、较低的 initialDelaySeconds 和 periodSeconds 时长的时候, 配置任何使用 exec 机制的探针可能会增加节点的 CPU 负载。 这种场景下,请考虑使用其他探针机制以避免额外的开销。
探针探测核心参数:
- initialDelaySeconds :首次进行探测的延时时间,设置多久后进行第一次探测(单位/s)
- periodSeconds:设置探测间隔时间,第一次探测完,第二次探测间隔时间(单位/s)
- failureThreshold: 连续探测失败多少次,将触发重启策略(默认3次)
1.3. 探测结果
探测值 | 含义 |
---|---|
Success | 容器通过了诊断,探测成功 |
Failure | 容器未通过诊断,探测失败 |
Unknown | 诊断失败,因此不会采取任何行动。 |
1.4. 实验
nginx-po.yaml
:
clike
apiVersion: v1
kind: Pod
metadata:
name: nginx-probe
labels:
app: nginx-probe
spec:
containers:
- name: nginx
image: nginx:latest
imagePullPolicy: IfNotPresent
restartPolicy: Always
ports:
- name: web
containerPort: 80
protocol: TCP
# 配置启动探针
startupProbe:
tcpSocket:
port: 80
# 等待5秒后进行探测
initialDelaySeconds: 5
failureThreshold: 3
periodSeconds: 3
# 配置存活探针
livenessProbe:
exec:
command: ["curl", "-s", "-f", "http://127.0.0.1"]
failureThreshold: 3
periodSeconds: 3
# 配置就绪探针
readinessProbe:
httpGet:
path: /
port: 80
scheme: HTTP
periodSeconds: 3
periodSeconds: 3
通过kubectl describe pod nginx-probe
查看探针配置情况
clike
Liveness: exec [curl -s -f http://127.0.0.1] delay=0s timeout=1s period=3s #success=1 #failure=3
Readiness: http-get http://:80/ delay=0s timeout=1s period=3s #success=1 #failure=3
Startup: tcp-socket :80 delay=5s timeout=1s period=3s #success=1 #failure=3
2.容器生命周期回调
官网文档:https://kubernetes.io/zh-cn/docs/concepts/containers/container-lifecycle-hooks/
2.1. 什么是容器生命周期回调
就是可以在容器启动后或者结束前来完成一些事情
2.2. PostStart和PreStop回调介绍
回调类型 | 触发时机 |
---|---|
postStart | 在容器创建完后立即触发, 但是不能保证回调会在容器入口点(ENTRYPOINT)之前执行,可能是同时启动, 如果 PostStart 回调程序执行时间过长或挂起,它可能会阻止容器进入 running 状态。 |
PreStop | 在容器因 API 请求或者管理事件(诸如存活态探针、启动探针失败、资源抢占、资源竞争等) 而被终止之前,此回调会被调用。 如果容器已经处于已终止或者已完成状态,则对 preStop 回调的调用将失败。当 Pod 被标记为删除时,会先容器发送 SIGTERM 信号,然后执行PreStop 回调,当SIGTERM信号发送给容器后,就进入到了宽限期,回调需要在这个宽限期内完成工作,否则宽限期一到容器就会被立刻终止。 |
2.3. 如何实现回调
容器通过三种方式实现回调:
回调类型 | 实现方式 | 使用场景 |
---|---|---|
Exec | 在容器的 cgroups 和名字空间中执行特定的命令(例如 pre-stop.sh)。 命令所消耗的资源计入容器的资源消耗。 | 在容器内部执行命令或者脚本 |
HTTP | 对容器上的特定端点执行 HTTP 请求。 | 向容器内部的某个 HTTP/HTTPS 端点发送请求(如 GET、POST),通过应用自身的接口触发回调逻辑。 |
Sleep | 将容器暂停一段指定的时间。 | 通过执行 sleep 命令让容器暂停指定时间,本质是 Exec 回调的特例(仅执行 sleep <秒数>)。 |
2.4. 通过实验来完成
官网有一个实验:https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/attach-handler-lifecycle-event,使用这个实验来完成 PostStart和PreStop
lifecycle使用参考: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#lifecycle-v1-core
lifecycle-demo.yaml
:
clike
apiVersion: v1
kind: Pod
metadata:
name: lifecycle-demo
spec:
containers:
- name: lifecycle-demo-container
image: nginx
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"]
preStop:
exec:
command: ["/bin/sh","-c","nginx -s quit; while killall -0 nginx; do sleep 1; done"]
kubectl create -f lifecycle-demo.yaml
查看容器lifecycle-demo-container
是否创建了/usr/share/message文件
kubectl exec pods/lifecycle-demo -- cat /usr/share/message
clike
Hello from the postStart handler
当删除Pod时,preStop会立即执行,上面定义的preStop是安全的退出nginx。