Skip to content

容器的健康检查

容器健康检查根据用户需求,检查容器的健康状况。配置后,容器内的应用程序入如果异常,容器会自动进行重启恢复。Kubernetes 提供了存活(Liveness)检查、就绪(Readiness)检查和启动(Startup)检查。

  • 存活检查(LivenessProbe) 可探测到应用死锁(应用程序在运行,但是无法继续执行后面的步骤)情况。 重启这种状态下的容器有助于提高应用的可用性,即使其中存在缺陷。

  • 就绪检查(ReadinessProbe) 可探知容器何时准备好接受请求流量,当一个 Pod 内的所有容器都就绪时,才能认为该 Pod 就绪。 这种信号的一个用途就是控制哪个 Pod 作为 Service 的后端。 若 Pod 尚未就绪,会被从 Service 的负载均衡器中剔除。

  • 启动检查(StartupProbe) 可以了解应用容器何时启动,配置后,可控制容器在启动成功后再进行存活性和就绪态检查, 确保这些存活、就绪探测器不会影响应用的启动。 启动探测可以用于对慢启动容器进行存活性检测,避免它们在启动运行之前就被杀掉。

存活和就绪检查

存活检查(LivenessProbe)的配置和就绪检查(ReadinessProbe)的配置参数相似, 唯一区别是要使用 readinessProbe 字段,而不是 livenessProbe 字段。

HTTP GET 参数说明:

参数 参数说明
路径( Path) 访问的请求路径。如: 示例中的 /healthz 路径
端口(Port) 服务监听端口。 如: 示例中的 8080 端口
协议 访问协议,Http 或者Https
延迟时间(initialDelaySeconds) 延迟检查时间,单位为秒,此设置与业务程序正常启动时间相关。例如,设置为30,表明容器启动后30秒才开始健康检查,该时间是预留给业务程序启动的时间。
超时时间(timeoutSeconds) 超时时间,单位为秒。例如,设置为10,表明执行健康检查的超时等待时间为10秒,如果超过这个时间,本次健康检查就被视为失败。若设置为0或不设置,默认超时等待时间为1秒。
超时时间(timeoutSeconds) 超时时间,单位为秒。例如,设置为10,表明执行健康检查的超时等待时间为10秒,如果超过这个时间,本次健康检查就被视为失败。若设置为0或不设置,默认超时等待时间为1秒。
成功阈值(successThreshold) 探测失败后,被视为成功的最小连续成功数。默认值是 1,最小值是 1。存活和启动探测的这个值必须是 1。
最大失败次数(failureThreshold) 当探测失败时重试的次数。存活探测情况下的放弃就意味着重新启动容器。就绪探测情况下的放弃 Pod 会被打上未就绪的标签。默认值是 3。最小值是 1。

使用 HTTP GET 请求检查

YAML 示例:

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-http
spec:
  containers:
  - name: liveness
    image: k8s.gcr.io/liveness
    args:
    - /server
    livenessProbe:
      httpGet:
        path: /healthz  # 访问的请求路径
        port: 8080  # 服务监听端口
        httpHeaders:
        - name: Custom-Header
          value: Awesome
      initialDelaySeconds: 3  # kubelet 在执行第一次探测前应该等待 3 秒
      periodSeconds: 3   # kubelet 每隔 3 秒执行一次存活探测

按照设定的规则,ubelet 向容器内运行的服务(服务在监听 8080 端口)发送一个 HTTP GET 请求来执行探测。如果服务器上 /healthz 路径下的处理程序返回成功代码,则 kubelet 认为容器是健康存活的。 如果处理程序返回失败代码,则 kubelet 会杀死这个容器并将其重启。返回大于或等于 200 并且小于 400 的任何代码都标示成功,其它返回代码都标示失败。 容器存活期间的最开始 10 秒中, /healthz 处理程序返回 200 的状态码。 之后处理程序返回 500 的状态码。

使用 TCP 端口检查

TCP 端口参数说明:

参数 参数说明
端口(Port) 服务监听端口。 如: 示例中的 8080 端口
延迟时间(initialDelaySeconds) 延迟检查时间,单位为秒,此设置与业务程序正常启动时间相关。例如,设置为30,表明容器启动后30秒才开始健康检查,该时间是预留给业务程序启动的时间。
超时时间(timeoutSeconds) 超时时间,单位为秒。例如,设置为10,表明执行健康检查的超时等待时间为10秒,如果超过这个时间,本次健康检查就被视为失败。若设置为0或不设置,默认超时等待时间为1秒。

对于提供TCP通信服务的容器,基于此配置,按照设定规则集群对该容器建立TCP连接,如果连接成功,则证明探测成功,否则探测失败。选择TCP端口探测方式,必须指定容器监听的端口。

YAML 示例:

apiVersion: v1
kind: Pod
metadata:
  name: goproxy
  labels:
    app: goproxy
spec:
  containers:
  - name: goproxy
    image: k8s.gcr.io/goproxy:0.1
    ports:
    - containerPort: 8080
    readinessProbe:
      tcpSocket:
        port: 8080
      initialDelaySeconds: 5
      periodSeconds: 10
    livenessProbe:
      tcpSocket:
        port: 8080
      initialDelaySeconds: 15
      periodSeconds: 20

此示例同时使用就绪和存活探针。kubelet 在容器启动 5 秒后发送第一个就绪探测。 尝试连接 goproxy 容器的 8080 端口, 如果探测成功,这个 Pod 会被标记为就绪状态,kubelet 将继续每隔 10 秒运行一次检测。

除了就绪探测,这个配置包括了一个存活探测。 kubelet 会在容器启动 15 秒后进行第一次存活探测。 就绪探测会尝试连接 goproxy 容器的 8080 端口。 如果存活探测失败,容器会被重新启动。

执行命令检查

YAML 示例:

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-exec
spec:
  containers:
  - name: liveness
    image: k8s.gcr.io/busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600
    livenessProbe:
      exec:
        command:
        - cat
        - /tmp/healthy
      initialDelaySeconds: 5 # kubelet 在执行第一次探测前等待 5 秒
      periodSeconds: 5  #kubelet 每 5 秒执行一次存活探测

periodSeconds 字段指定了 kubelet 每 5 秒执行一次存活探测, initialDelaySeconds 字段指定 kubelet 在执行第一次探测前等待 5 秒。按照设定规则,集群周期性的通过 kubelet 在容器内执行命令 cat /tmp/healthy 来进行探测。 如果命令执行成功并且返回值为 0,kubelet 就会认为这个容器是健康存活的。 如果这个命令返回非 0 值,kubelet 会杀死这个容器并重新启动它。

使用启动前检查保护慢启动容器

有些应用在启动时需要较长的初始化时间,需要使用相同的命令来设置启动探测,针对 HTTP 或 TCP 检测,可以通过将 failureThreshold * periodSeconds 参数设置为足够长的时间来应对启动需要较长时间的场景。

YAML 示例:

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

如上设置,应用将有最多 5 分钟(30 * 10 = 300s)的时间来完成启动过程, 一旦启动探测成功,存活探测任务就会接管对容器的探测,对容器死锁作出快速响应。 如果启动探测一直没有成功,容器会在 300 秒后被杀死,并且根据 restartPolicy 来 执行进一步处置。