K8S探针讲解(K8S探针讲解)
K8S探针讲解(K8S探针讲解)容器启动时都会执行一个主进程,如果进程退出返回码不是0,则认为容器异常,即pod异常,k8s 会根据restartPolicy策略选择是否杀掉 pod,再重新启动一个。如果没有引入探针,k8s 会对pod 的crash状态(具体可以查看官网:https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/pod-lifecycle/)进行判断。在开始详细的介绍k8s的探针之前,先看下pod 的生命周期。Kubernetes pod遵循已定义的生命周期。常见的状态:Pod生命周期示意图
K8s 的pod健康检查在没有引入健康检查机制的时候,kubelet 根据容器运行的状态作为健康依据,不能监控容器中应用程序运行的状态,这就会导致在变更,服务假死等情况下的时候,导致流量丢失等问题。因此这个时候就需要引入健康检查机制。
健康检查健康检查(Health Check)用于检测您的应用实例是否正常工作,是保障业务可用性的一种传统机制,一般用于负载均衡下的业务,如果实例的状态不符合预期,将会把该实例“摘除”,不承担业务流量。
k8s健康检测主要分为以下三种:(官方介绍:https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/)存活性探测(Liveness probes),就绪性探测(Readiness probes),启动探测(Startup Probes)
目前支持的探测方式:
- HTTP
- TCP
- Exec命令
在开始详细的介绍k8s的探针之前,先看下pod 的生命周期。
Kubernetes pod遵循已定义的生命周期。常见的状态:
- 挂起(Pending):Pod 已被 Kubernetes 系统接受,但有一个或者多个容器镜像尚未创建。等待时间包括调度 Pod 的时间和通过网络下载镜像的时间,这可能需要花点时间。
- 运行中(Running):该 Pod 已经绑定到了一个节点上,Pod 中所有的容器都已被创建。至少有一个容器正在运行,或者正处于启动或重启状态。
- 成功(Succeeded):Pod 中的所有容器都被成功终止,并且不会再重启。
- 失败(Failed):Pod 中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止。
- 未知(Unknown):因为某些原因无法取得 Pod 的状态,通常是因为与 Pod 所在主机通信失败。
Pod生命周期示意图
如果没有引入探针,k8s 会对pod 的crash状态(具体可以查看官网:https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/pod-lifecycle/)进行判断。
容器启动时都会执行一个主进程,如果进程退出返回码不是0,则认为容器异常,即pod异常,k8s 会根据restartPolicy策略选择是否杀掉 pod,再重新启动一个。
restartPolicy分为三种:
- Always:当容器终止退出后,总是重启容器,默认策略。
- Onfailure:当容器异常退出(退出码非0)时,才重启容器。
- Never:当容器终止退出时,才不重启容器。
主要是探测应用是否还活着。如果检测到应用没有存活就杀掉当前pod并重启。例如,存活探针可以探测到应用死锁(应用程序在运行,但是无法继续执行后面的步骤)情况。重启这种状态下的容器有助于提高应用的可用性,即使其中存在缺陷。
对应k8s中的配置
livenessProbe:
enabled: true
httpGet:
port: 8080
scheme: HTTP
initialDelaySeconds: 60#表示延迟60S开始第一次探测,默认值是0,最小值是0
timeoutSeconds: 35 #表示每次探测的超时时间,35S后如果没返回结果就认为超时失败,默认值是1,最小值是1
periodSeconds: 30 # 表示多久进行一次探测,默认是10S,最小值是1
successThreshold: 1#表示在探测失败后,最小的连续成功被认为是成功的,默认值是1,最小值是1
failureThreshold: 3#表示当探测失败时,Kubernetes将在认为失败前尝试failureThreshold次数。默认值是3,最小值是1;Liveness认为失败的操作是重启pod
就绪性探测(Readiness probes)
只要是探测应用是否准备好接受请求访问,当一个 Pod 内的所有容器都就绪时,才能认为该 Pod 就绪。这种信号的一个用途就是控制哪个 Pod 作为 Service 的后端。若 Pod 尚未就绪,会被从 Service 的负载均衡器中剔除。
readinessProbe:
enabled: true
httpGet:
port: 8080
scheme: HTTP
initialDelaySeconds: 30 #表示延迟30S开始第一次探测,默认值是0,最小值是0
timeoutSeconds: 35 #表示每次探测的超时时间,35S后如果没返回结果就认为超时失败,默认值是1,最小值是1
periodSeconds: 30 # 表示多久进行一次探测,默认是10S,最小值是1
successThreshold: 1#表示在探测失败后,最小的连续成功被认为是成功的,默认值是1,最小值是1
failureThreshold: 3#表示当探测失败时,Kubernetes将在认为失败前尝试failureThreshold次数。默认值是3,最小值是1;readiness认为失败的操作是把pod标记为 Unready
启动探测(Startup Probes)
kubelet 使用启动探针来了解应用容器何时启动。如果配置了这类探针,你就可以控制容器在启动成功后再进行存活性和就绪态检查, 确保这些存活、就绪探针不会影响应用的启动。启动探针可以用于对慢启动容器进行存活性检测,避免它们在启动运行之前就被杀掉。
对于 HTTP 和 TCP 存活检测可以使用命名的port,可以把上面的配置抽象出来
比如:
ports:
- name: liveness-port
containerPort: 8080
hostPort: 8080
livenessProbe:
httpGet:
path:
port: liveness-port
使用启动探针的配置实例
ports:
- name: liveness-port
containerPort: 8080
hostPort: 8080
livenessProbe:
httpGet:
path: /healthz
port: liveness-port
failureThreshold: 1
periodSeconds: 10
startupProbe:
httpGet:
path: /healthz
port: liveness-port
failureThreshold: 30
periodSeconds: 10
这样对于启动时间比较久的pod,应用程序将会有最多 5 分钟(30 * 10 = 300s)的时间来完成其启动过程。一旦启动探测成功一次,存活探测任务就会接管对容器的探测,对容器死锁作出快速响应。如果启动探测一直没有成功,容器会在 300 秒后被杀死,并且根据 restartPolicy 来执行进一步处置。
探针执行方式HTTPkubelet 将 HTTP GET 请求发送到 endpoint,并检查 2xx 或 3xx 响应。即使您的应用程序不是HTTP服务,我们也可以在应用程序内创建轻量级HTTP服务以响应Liveness探针。Kubernetes去访问一个路径,如果它得到的是200或300范围内的HTTP响应,它会将应用程序标记为健康。否则它被标记为不健康。
httpGet配置项:
- host:连接的主机名,默认连接到pod的IP。你可能想在http header中设置”Host”而不是使用IP。
- scheme:连接使用的schema,默认HTTP。
- path: 访问的HTTP server的path。
- httpHeaders:自定义请求的header。HTTP运行重复的header。
- port:访问的容器的端口名字或者端口号。端口号必须介于1和65535之间。
livenessProbe:
httpGet:
path: /healthz
port: 8080
httpHeaders:
- name: Accept
value: application/json
initialDelaySeconds: 3
periodSeconds: 3
TCP
对于 TCP 探测而言,kubelet 在节点上(不是在 Pod 里面)发起探测连接, 这意味着你不能在 host 参数上配置服务名称,因为 kubelet 不能解析服务名称。Kubernetes尝试在指定端口上建立TCP连接。如果它可以建立连接,则容器被认为是健康的;否则被认为是不健康的。
TCP 的配置项(tcpSocket):
- host:探测的主机,默认为本pod ip
- port:端口,1到65535
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 35
periodSeconds: 10
Exec
Exec探针是在容器内运行指定的命令,如果命令退出代码为0,则标记容器状态为健康,如果不为0,则容器会被标记为不健康。
Exec 的配置项(exec):
- command:需要执行的命令,需要符合命令的格式
livenessProbe:
exec:
command:
- cat
- /etc/hosts
initialDelaySeconds: 5
periodSeconds: 5
在实际的工作中需要根据业务的场景使用对应的探针组合,建议默认都开启存活性探针(liveness probes)和就绪性探针(readiness probes)。
k8s基于存活性探针(liveness probes)和就绪性探针(readiness probes)可以实现下面的一些需求
- 异常实例自动剔除,并重启新实例
- 多种类型探针检测,保证异常pod不接入流量
- 不停机部署,更安全的滚动升级
对于慢启动的容器,可以引入启动探测(Startup Probes)来优化健康检查。k8s 1.16 才开始支持startup Probe这个特性。