×

在软件系统中,组件可能会由于瞬态问题(例如临时连接丢失、配置错误或外部依赖项问题)而变得不健康。OpenShift Container Platform 应用程序有多种选项可用于检测和处理不健康的容器。

了解健康检查

健康检查会定期使用准备情况检查、存活性检查和启动检查的任意组合对正在运行的容器执行诊断。

您可以在包含要执行健康检查的容器的 Pod 的规范中包含一个或多个探针。

如果要向现有 Pod 添加或编辑健康检查,则必须编辑 Pod 的 `DeploymentConfig` 对象或使用 Web 控制台中的**开发者**视角。您不能使用 CLI 向现有 Pod 添加或编辑健康检查。

准备情况探针

准备情况探针确定容器是否已准备好接受服务请求。如果容器的准备情况探针失败,kubelet 会从可用服务端点列表中删除该 Pod。

失败后,探针将继续检查 Pod。如果 Pod 变为可用,kubelet 会将 Pod 添加到可用服务端点列表中。

存活性健康检查

存活性探针确定容器是否仍在运行。如果存活性探针由于死锁等情况而失败,kubelet 会终止该容器。然后,Pod 会根据其重启策略做出响应。

例如,具有 `restartPolicy` 为 `Always` 或 `OnFailure` 的 Pod 上的存活性探针会终止并重启容器。

启动探针

启动探针指示容器中的应用程序是否已启动。在启动成功之前,所有其他探针都处于禁用状态。如果启动探针在指定的时间段内未成功,kubelet 会终止容器,并且容器将遵循 Pod 的 `restartPolicy`。

某些应用程序在其第一次初始化时可能需要额外的启动时间。您可以将启动探针与存活性探针或准备情况探针一起使用,以使用 `failureThreshold` 和 `periodSeconds` 参数将探针延迟足够长的时间以处理冗长的启动时间。

例如,您可以向存活性探针添加一个启动探针,其 `failureThreshold` 为 30 次失败,`periodSeconds` 为 10 秒(30 * 10 秒 = 300 秒),最多 5 分钟。启动探针第一次成功后,存活性探针将接管。

您可以使用以下任何类型的测试配置存活性、准备情况和启动探针

  • HTTP `GET`:使用 HTTP `GET` 测试时,测试使用 Web 挂钩来确定容器的健康状况。如果 HTTP 响应代码介于 `200` 和 `399` 之间,则测试成功。

    您可以将 HTTP `GET` 测试与在完全初始化时返回 HTTP 状态代码的应用程序一起使用。

  • 容器命令:使用容器命令测试时,探针会在容器内执行命令。如果测试以 `0` 状态退出,则探针成功。

  • TCP 套接字:使用 TCP 套接字测试时,探针会尝试打开到容器的套接字。只有在探针能够建立连接时,容器才被认为是健康的。您可以将 TCP 套接字测试与在初始化完成之前不开始侦听的应用程序一起使用。

您可以配置多个字段来控制探针的行为

  • `initialDelaySeconds`:容器启动后探针可以被调度的秒数。默认为 0。

  • `periodSeconds`:执行探针之间延迟的秒数。默认为 `10`。此值必须大于 `timeoutSeconds`。

  • `timeoutSeconds`:探针超时且容器被假定已失败后的非活动秒数。默认为 `1`。此值必须小于 `periodSeconds`。

  • successThreshold:探针在失败后必须报告成功的次数,才能将容器状态重置为成功。对于存活性探针,该值必须为1。默认为1

  • failureThreshold:探针允许失败的次数。默认为 3。在指定尝试次数之后:

    • 对于存活性探针,容器将被重启

    • 对于就绪性探针,Pod 将被标记为Unready

    • 对于启动探针,容器将被终止,并受 Pod 的restartPolicy 策略影响

探针示例

以下是不同探针在对象规范中显示方式的示例。

Pod规范中包含容器命令就绪性探针的就绪性探针示例
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: health-check
  name: my-application
# ...
spec:
  containers:
  - name: goproxy-app (1)
    args:
    image: registry.k8s.io/goproxy:0.1 (2)
    readinessProbe: (3)
      exec: (4)
        command: (5)
        - cat
        - /tmp/healthy
# ...
1 容器名称。
2 要部署的容器镜像。
3 就绪性探针。
4 容器命令测试。
5 要在容器上执行的命令。
Pod规范中包含容器命令启动探针和存活性探针的示例
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: health-check
  name: my-application
# ...
spec:
  containers:
  - name: goproxy-app (1)
    args:
    image: registry.k8s.io/goproxy:0.1 (2)
    livenessProbe: (3)
      httpGet: (4)
        scheme: HTTPS (5)
        path: /healthz
        port: 8080 (6)
        httpHeaders:
        - name: X-Custom-Header
          value: Awesome
    startupProbe: (7)
      httpGet: (8)
        path: /healthz
        port: 8080 (9)
      failureThreshold: 30 (10)
      periodSeconds: 10 (11)
# ...
1 容器名称。
2 指定要部署的容器镜像。
3 存活性探针。
4 HTTP GET 测试。
5 互联网方案:HTTPHTTPS。默认值为HTTP
6 容器正在监听的端口。
7 启动探针。
8 HTTP GET 测试。
9 容器正在监听的端口。
10 失败后尝试探针的次数。
11 执行探针的秒数。
Pod规范中包含使用超时的容器命令测试的存活性探针示例
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: health-check
  name: my-application
# ...
spec:
  containers:
  - name: goproxy-app (1)
    args:
    image: registry.k8s.io/goproxy:0.1 (2)
    livenessProbe: (3)
      exec: (4)
        command: (5)
        - /bin/bash
        - '-c'
        - timeout 60 /opt/eap/bin/livenessProbe.sh
      periodSeconds: 10 (6)
      successThreshold: 1 (7)
      failureThreshold: 3 (8)
# ...
1 容器名称。
2 指定要部署的容器镜像。
3 存活性探针。
4 探针类型,此处为容器命令探针。
5 在容器内执行的命令行。
6 执行探针的频率(秒)。
7 失败后显示成功所需的连续成功次数。
8 失败后尝试探针的次数。
部署中包含 TCP 套接字测试的就绪性探针和存活性探针示例
kind: Deployment
apiVersion: apps/v1
metadata:
  labels:
    test: health-check
  name: my-application
spec:
# ...
  template:
    spec:
      containers:
        - resources: {}
          readinessProbe: (1)
            tcpSocket:
              port: 8080
            timeoutSeconds: 1
            periodSeconds: 10
            successThreshold: 1
            failureThreshold: 3
          terminationMessagePath: /dev/termination-log
          name: ruby-ex
          livenessProbe: (2)
            tcpSocket:
              port: 8080
            initialDelaySeconds: 15
            timeoutSeconds: 1
            periodSeconds: 10
            successThreshold: 1
            failureThreshold: 3
# ...
1 就绪性探针。
2 存活性探针。

使用 CLI 配置健康检查

要配置就绪性、存活性及启动探针,请将一个或多个探针添加到包含要执行健康检查的容器的 Pod 规范中。

如果要向现有 Pod 添加或编辑健康检查,则必须编辑 Pod 的 `DeploymentConfig` 对象或使用 Web 控制台中的**开发者**视角。您不能使用 CLI 向现有 Pod 添加或编辑健康检查。

步骤

要为容器添加探针

  1. 创建一个Pod对象以添加一个或多个探针

    apiVersion: v1
    kind: Pod
    metadata:
      labels:
        test: health-check
      name: my-application
    spec:
      containers:
      - name: my-container (1)
        args:
        image: registry.k8s.io/goproxy:0.1 (2)
        livenessProbe: (3)
          tcpSocket:  (4)
            port: 8080 (5)
          initialDelaySeconds: 15 (6)
          periodSeconds: 20 (7)
          timeoutSeconds: 10 (8)
        readinessProbe: (9)
          httpGet: (10)
            host: my-host (11)
            scheme: HTTPS (12)
            path: /healthz
            port: 8080 (13)
        startupProbe: (14)
          exec: (15)
            command: (16)
            - cat
            - /tmp/healthy
          failureThreshold: 30 (17)
          periodSeconds: 20 (18)
          timeoutSeconds: 10 (19)
    1 指定容器名称。
    2 指定要部署的容器镜像。
    3 可选:创建存活性探针。
    4 指定要执行的测试,此处为 TCP 套接字测试。
    5 指定容器正在监听的端口。
    6 指定容器启动后探针可以被调度的秒数。
    7 指定执行探针的秒数。默认为10。此值必须大于timeoutSeconds
    8 指定探针在被认为失败之前可以处于非活动状态的秒数。默认为1。此值必须小于periodSeconds
    9 可选:创建就绪性探针。
    10 指定要执行的测试类型,此处为 HTTP 测试。
    11 指定主机 IP 地址。未定义host时,使用PodIP
    12 指定HTTPHTTPS。未定义scheme时,使用HTTP方案。
    13 指定容器正在监听的端口。
    14 可选:创建启动探针。
    15 指定要执行的测试类型,此处为容器执行探针。
    16 指定要在容器上执行的命令。
    17 指定失败后尝试探针的次数。
    18 指定执行探针的秒数。默认为10。此值必须大于timeoutSeconds
    19 指定探针在被认为失败之前可以处于非活动状态的秒数。默认为1。此值必须小于periodSeconds

    如果initialDelaySeconds值小于periodSeconds值,则由于计时器问题,第一次就绪性探针会在两个周期之间某个时间点发生。

    timeoutSeconds值必须小于periodSeconds值。

  2. 创建Pod对象

    $ oc create -f <file-name>.yaml
  3. 验证健康检查 Pod 的状态

    $ oc describe pod my-application
    示例输出
    Events:
      Type    Reason     Age   From                                  Message
      ----    ------     ----  ----                                  -------
      Normal  Scheduled  9s    default-scheduler                     Successfully assigned openshift-logging/liveness-exec to ip-10-0-143-40.ec2.internal
      Normal  Pulling    2s    kubelet, ip-10-0-143-40.ec2.internal  pulling image "registry.k8s.io/liveness"
      Normal  Pulled     1s    kubelet, ip-10-0-143-40.ec2.internal  Successfully pulled image "registry.k8s.io/liveness"
      Normal  Created    1s    kubelet, ip-10-0-143-40.ec2.internal  Created container
      Normal  Started    1s    kubelet, ip-10-0-143-40.ec2.internal  Started container

    以下是导致容器重启的探针失败的输出

    包含不健康容器的存活性检查输出示例
    $ oc describe pod pod1
    示例输出
    ....
    
    Events:
      Type     Reason          Age                From                                               Message
      ----     ------          ----               ----                                               -------
      Normal   Scheduled       <unknown>                                                             Successfully assigned aaa/liveness-http to ci-ln-37hz77b-f76d1-wdpjv-worker-b-snzrj
      Normal   AddedInterface  47s                multus                                             Add eth0 [10.129.2.11/23]
      Normal   Pulled          46s                kubelet, ci-ln-37hz77b-f76d1-wdpjv-worker-b-snzrj  Successfully pulled image "registry.k8s.io/liveness" in 773.406244ms
      Normal   Pulled          28s                kubelet, ci-ln-37hz77b-f76d1-wdpjv-worker-b-snzrj  Successfully pulled image "registry.k8s.io/liveness" in 233.328564ms
      Normal   Created         10s (x3 over 46s)  kubelet, ci-ln-37hz77b-f76d1-wdpjv-worker-b-snzrj  Created container liveness
      Normal   Started         10s (x3 over 46s)  kubelet, ci-ln-37hz77b-f76d1-wdpjv-worker-b-snzrj  Started container liveness
      Warning  Unhealthy       10s (x6 over 34s)  kubelet, ci-ln-37hz77b-f76d1-wdpjv-worker-b-snzrj  Liveness probe failed: HTTP probe failed with statuscode: 500
      Normal   Killing         10s (x2 over 28s)  kubelet, ci-ln-37hz77b-f76d1-wdpjv-worker-b-snzrj  Container liveness failed liveness probe, will be restarted
      Normal   Pulling         10s (x3 over 47s)  kubelet, ci-ln-37hz77b-f76d1-wdpjv-worker-b-snzrj  Pulling image "registry.k8s.io/liveness"
      Normal   Pulled          10s                kubelet, ci-ln-37hz77b-f76d1-wdpjv-worker-b-snzrj  Successfully pulled image "registry.k8s.io/liveness" in 244.116568ms

使用开发者视角监控应用程序健康状况

您可以使用**开发者**视角为您的容器添加三种类型的健康探针,以确保您的应用程序运行正常。

  • 使用就绪性探针检查容器是否已准备好处理请求。

  • 使用存活性探针检查容器是否正在运行。

  • 使用启动探针检查容器中的应用程序是否已启动。

您可以在创建和部署应用程序时或应用程序部署后添加健康检查。

使用开发者视角编辑健康检查

您可以使用**拓扑**视图编辑添加到应用程序的健康检查、修改它们或添加更多健康检查。

先决条件
  • 您已切换到 Web 控制台中的**开发者**视角。

  • 您已使用**开发者**视角在 OpenShift Container Platform 上创建并部署了一个应用程序。

  • 您已将健康检查添加到您的应用程序。

步骤
  1. 在**拓扑**视图中,右键单击您的应用程序并选择**编辑健康检查**。或者,在侧面板中,单击**操作**下拉列表并选择**编辑健康检查**。

  2. 在**编辑健康检查**页面中

    • 要删除先前添加的健康探针,请单击其旁边的**删除**图标。

    • 要编辑现有探针的参数

      1. 单击先前添加的探针旁边的**编辑探针**链接以查看探针的参数。

      2. 根据需要修改参数,然后单击复选标记以保存更改。

    • 要添加新的健康探针(除了现有的健康检查外),请单击添加探针链接。例如,要添加一个检查容器是否正在运行的存活性探针

      1. 单击**添加存活性探针**,以查看包含探针参数的表单。

      2. 根据需要编辑探针参数。

        超时值必须小于周期值。超时默认值为1周期默认值为10

      3. 单击表单底部的复选标记。将显示**已添加存活性探针**消息。

  3. 单击**保存**以保存您的修改并将附加探针添加到您的容器。您将被重定向到**拓扑**视图。

  4. 在侧面板中,通过单击**Pod**部分下已部署的 Pod 来验证是否已添加探针。

  5. 在**Pod 详情**页面中,单击**容器**部分中列出的容器。

  6. 在**容器详情**页面中,验证是否已将存活性探针 - HTTP Get 10.129.4.65:8080/添加到容器中,以及先前存在的探针。

使用开发者视角监控健康检查失败

如果应用程序健康检查失败,您可以使用**拓扑**视图监控这些健康检查违规。

先决条件
  • 您已切换到 Web 控制台中的**开发者**视角。

  • 您已使用**开发者**视角在 OpenShift Container Platform 上创建并部署了一个应用程序。

  • 您已将健康检查添加到您的应用程序。

步骤
  1. 在**拓扑**视图中,单击应用程序节点以查看侧面板。

  2. 单击**观察**选项卡以查看**事件(警告)**部分中的健康检查失败。

  3. 单击**事件(警告)**旁边的向下箭头以查看健康检查失败的详细信息。

其他资源