赞
踩
Kubernetes中的健康检查主要使用 就绪性探针(
readinessProbes
)和 存活性探针(livenessProbes
) 来实现,service即为负载均衡,k8s保证 service 后面的 pod 都可用,是k8s中自愈能力的主要手段,主要基于这两种探测机制,可以实现如下需求:
官方文档:https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
Kubernetes(k8s)环境部署可以参考我这篇文章:Kubernetes(k8s)最新版最完整版环境部署+master高可用实现(k8sV1.24.1+dashboard+harbor)
readiness probes
准备就绪检查,通过readiness是否准备接受流量,准备完毕加入到Endpoint
,否则剔除。如果容器不提供就绪探针,则默认状态为 Success。
liveness probes
在线检查机制,检查应用是否可用,如死锁,无法响应,异常时将根据restartPolicy
来设置 Pod 状态会自动重启容器,如果容器不提供存活探针,则默认状态为 Success。
restartPolicy
有三个可选值:
Always
:当容器终止退出后,总是重启容器,默认策略。
OnFailure
:当容器异常退出(退出状态码非0)时,才重启容器。
Never
:当容器终止退出,从不重启容器。
startupProbes
启动检查机制,应用一些启动缓慢的业务,避免业务长时间启动而被前面的探针kill掉。startupProbes
探测,则在 startupProbes
状态为 Success 之前,其他所有探针都处于无效状态,直到它成功后其他探针才起作用。startupProbe
失败,kubelet 将杀死容器,容器将根据 restartPolicy
来重启。如果容器没有配置 startupProbe
,则默认状态为 Success。其实一般主要是设置上面两种即可。就绪、存活两种探针的区别:
readinessProbe 和 livenessProbe 可以使用相同探测方式,只是对 Pod 的处置方式不同。
EndPoint
列表中删除。每种探测机制支持三种健康检查方法,分别是命令行exec,httpGet和tcpSocket,其中exec通用性最强,适用与大部分场景,tcpSocket适用于TCP业务,httpGet适用于web业务。
exec
(自定义健康检查):在容器中执行指定的命令,如果执行成功,退出码为 0 则探测成功。httpGet
:通过容器的IP地址、端口号及路径调用 HTTP Get方法,如果响应的状态码大于等于200且小于400,则认为容器 健康。tcpSocket
:通过容器的 IP 地址和端口号执行 TCP 检 查,如果能够建立 TCP 连接,则表明容器健康。探针探测结果有以下值:
Success
:表示通过检测。Failure
:表示未通过检测。Unknown
:表示检测没有正常进行。readiness probe
配置进行探测,无问题后结果为成功即状态为 Success
;READY
状态为 true,从0/1变为1/1。如果失败继续为0/1,状态为 false;Success
。对于此pod、此pod关联的Service
资源、EndPoint
的关系也将基于 Pod 的 Ready
状态进行设置;Service
资源 关联的 EndPoint
列表中去除此pod,届时service资源接收到GET请求后,kube-proxy
将一定不会把流量引入此pod中,通过这种机制就能防止将流量转发到不可用的 Pod 上。Endpoint
列表。kube-proxy
也将有概率通过负载机制会引入流量到此pod中。restartPolicy
(重启策略)来判断,Pod 是否要进行重启操作;Success
。即Success后pod状态是RUNING
。常用的探针可选参数:
参数名称 | 默认值 | 最小值 | 描述 |
---|---|---|---|
initialDelaySeconds | 0秒 | 0秒 | 探测延迟时长,容器启动后多久开始进行第一次探测工作。 |
periodSeconds | 10秒 | 1秒 | 探测频度,频率过高会对pod带来较大的额外开销,频率过低则无法及时反映容器产生的错误。 |
timeoutSeconds | 1秒 | 1秒 | 探测的超时时长。 |
failureThreshold | 3 | 1 | 处于成功状态时,探测连续失败几次可被认为失败。 |
successThreshold | 1 | 1 | 处于失败状态时,探测连续成功几次,被认为成功。 |
cat >exec-liveness.yaml<<EOF
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-exec
spec:
# 为了测试方便,指定调度机器
nodeName: local-168-182-110
containers:
- name: liveness
image: registry.aliyuncs.com/google_containers/busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
EOF
解释:
initialDelaySeconds
字段告诉 kubelet 在执行第一次探测前应该等待 5 秒。
periodSeconds
字段指定了 kubelet 应该每 5 秒执行一次存活探测。
kubelet 在容器内执行命令 cat /tmp/healthy 来进行探测。
如果命令执行成功并且返回值为 0,kubelet 就会认为这个容器是健康存活的。
如果这个命令返回非 0 值,kubelet 会杀死这个容器并重新启动它。
当容器启动时,执行如下的命令:
/bin/sh -c "touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600"
创建 Pod:
# 最好先拉取镜像,如果是使用docker,就换成docker就行
crictl pull registry.aliyuncs.com/google_containers/busybox
kubectl apply -f exec-liveness.yaml
【问题】ERRO[0000] unable to determine image API version: rpc error: code = Unavailable desc = connection error: desc = “transport: Error while dialing dial unix /var/run/dockershim.sock: connect: no such file or directory”
【解决】原因:未配置endpoints
crictl config runtime-endpoint unix:///run/containerd/containerd.sock
crictl config image-endpoint unix:///run/containerd/containerd.sock
查看
kubectl describe pod liveness-exec
【现象】30s之后检查失败后就重启pod了,又正常了。
cat >http-liveness.yaml<<EOF
apiVersion: v1
kind: Pod
metadata:
name: liveness-httpget
namespace: default
spec:
# 为了测试方便,指定调度机器
nodeName: local-168-182-110
containers:
- name: liveness-httpget-container
image: nginx
imagePullPolicy: IfNotPresent
ports:
- name: nginx
containerPort: 80
livenessProbe:
httpGet:
port: nginx
path: /index.html
initialDelaySeconds: 1
periodSeconds: 3
timeoutSeconds: 10
EOF
解释:
initialDelaySeconds
字段告诉 kubelet 在执行第一次探测前应该等待 1 秒。periodSeconds
字段指定了 kubelet 每隔 3 秒执行一次存活探测。/index.html
路径下的处理程序返回成功代码,则 kubelet 认为容器是健康存活的。200
并且小于 400
的任何代码都标示成功,其它返回代码都标示失败。执行并查看
crictl pull nginx
kubectl apply -f http-liveness.yaml
kubectl describe pod liveness-httpget
删除 Pod 的 index.html 文件
kubectl exec -it liveness-httpget -- rm -rf /usr/share/nginx/html/index.html
# 再查看
kubectl describe pod liveness-httpget
kubectl get pod liveness-httpget
Liveness probe failed: HTTP probe failed with statuscode: 404
。HTTP Probes 允许针对 httpGet 配置额外的字段:
host
:连接使用的主机名,默认是 Pod 的 IP。也可以在 HTTP 头中设置 “Host” 来代替。scheme
:用于设置连接主机的方式(HTTP 还是 HTTPS)。默认是 “HTTP”。path
:访问 HTTP 服务的路径。默认值为 “/”。httpHeaders
:请求中自定义的 HTTP 头。HTTP 头字段允许重复。port
:访问容器的端口号或者端口名。如果数字必须在 1~65535 之间。你可以通过为探测设置 .httpHeaders 来重载默认的头部字段值;例如:
livenessProbe:
httpGet:
httpHeaders:
- name: Accept
value: application/json
startupProbe:
httpGet:
httpHeaders:
- name: User-Agent
value: MyUserAgent
cat >tcp-liveness-readiness.yaml<<EOF
apiVersion: v1
kind: Pod
metadata:
name: liveness-readiness-tcpsocket
labels:
app: liveness-readiness-tcpsocket
spec:
# 为了测试方便,指定调度机器
nodeName: local-168-182-110
containers:
- name: liveness-readiness-tcpsocket
image: nginx
ports:
- containerPort: 80
readinessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 15
periodSeconds: 20
EOF
解释:
kubectl apply -f tcp-liveness-readiness.yaml
kubectl get pod liveness-readiness-tcpsocket
kubectl describe pod liveness-readiness-tcpsocket
对于 HTTP 或者 TCP 存活检测可以使用命名的 port。
ports:
- name: nginx
containerPort: 80
hostPort: 80
livenessProbe:
httpGet:
path: /index.html
port: nginx
完整版配置
ports:
- name: nginx
containerPort: 80
hostPort: 80
# readinessProbe,就绪探针
livenessProbe:
httpGet:
path: /index.html
port: nginx
# 延迟多久后开始探测
initialDelaySeconds: 10
# 执行探测频率(秒) 【 每隔秒执行一次 】
periodSeconds: 10
# 超时时间
timeoutSeconds: 1
# 处于成功状态时,探测连续失败几次可被认为失败。
failureThreshold: 3
# 处于失败状态时,探测连续成功几次,被认为成功。
successThreshold: 1
# livenessProbe,存活探针
livenessProbe:
httpGet:
path: /index.html
port: nginx
# 延迟多久后开始探测
initialDelaySeconds: 10
# 执行探测频率(秒) 【 每隔秒执行一次 】
periodSeconds: 10
# 超时时间
timeoutSeconds: 1
# 处于成功状态时,探测连续失败几次可被认为失败。
failureThreshold: 3
# 处于失败状态时,探测连续成功几次,被认为成功。
successThreshold: 1
# startupProbe,启动探针
startupProbe:
httpGet:
path: /index.html
port: nginx
# 延迟多久后开始探测
initialDelaySeconds: 10
# 执行探测频率(秒) 【 每隔秒执行一次 】
periodSeconds: 10
# 超时时间
timeoutSeconds: 1
# 处于成功状态时,探测连续失败几次可被认为失败。
failureThreshold: 3
# 处于失败状态时,探测连续成功几次,被认为成功。
successThreshold: 1
一般使用控制器去创建管理pod,对k8s 控制器不清晰的小伙伴,可以参考我之前的文章:Kubernetes(k8s)Deployment、StatefulSet、DaemonSet、Job、CronJob五种控制器详解
下面是一个完整版的示例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-probe
spec:
replicas: 3
selector:
matchLabels:
app: deployment-probe
template:
metadata:
labels:
app: deployment-probe
spec:
containers:
- name: nginx
image: nginx:1.17.1
# readinessProbe,就绪探针
readinessProbe:
httpGet:
path: /index.html
port: nginx
# 延迟多久后开始探测
initialDelaySeconds: 10
# 执行探测频率(秒) 【 每隔秒执行一次 】
periodSeconds: 10
# 超时时间
timeoutSeconds: 1
# 处于成功状态时,探测连续失败几次可被认为失败。
failureThreshold: 3
# 处于失败状态时,探测连续成功几次,被认为成功。
successThreshold: 1
# livenessProbe,存活探针
livenessProbe:
httpGet:
path: /index.html
port: nginx
# 延迟多久后开始探测
initialDelaySeconds: 10
# 执行探测频率(秒) 【 每隔秒执行一次 】
periodSeconds: 10
# 超时时间
timeoutSeconds: 1
# 处于成功状态时,探测连续失败几次可被认为失败。
failureThreshold: 3
# 处于失败状态时,探测连续成功几次,被认为成功。
successThreshold: 1
# startupProbe,启动探针
startupProbe:
httpGet:
path: /index.html
port: nginx
# 延迟多久后开始探测
initialDelaySeconds: 10
# 执行探测频率(秒) 【 每隔秒执行一次 】
periodSeconds: 10
# 超时时间
timeoutSeconds: 1
# 处于成功状态时,探测连续失败几次可被认为失败。
failureThreshold: 3
# 处于失败状态时,探测连续成功几次,被认为成功。
successThreshold: 1
执行查看
crictl pull nginx:1.17.1
kubectl apply -f deployment-probe.yaml
kubectl get pod,deploy
Kubernetes(k8s)健康检查详解与实战演示就先到这里了,健康检查会伴随所有k8s编排任务,所以非常重要,其实也不难,小伙伴有什么疑问,欢迎给我留言哦~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。