【问题标题】:Kubernetes - Liveness and Readiness probe implementationKubernetes - Liveness 和 Readiness 探针实现
【发布时间】:2018-02-11 08:14:18
【问题描述】:

我正在使用 Spring 开发一项服务并将其部署在 OpenShift 上。目前我正在使用 Spring Actuator 健康端点作为 Kubernetes 的活跃度和就绪性探测。

但是,我将在 Actuator 健康端点中添加对另一个服务的调用,在我看来,在这种情况下,我需要为我的服务实施新的活动探测。如果我不这样做,那么第二个服务的失败将导致活动探测失败,Kubernetes 将在没有任何实际需要的情况下重新启动我的服务。

对于活性探测来说,实现一些总是返回 HTTP 状态 200 的简单 REST 控制器是否可以?如果它有效,该服务总是可以被认为是活着的吗?或者有没有更好的方法来做到这一点?

【问题讨论】:

  • “我将在执行器健康端点中添加对另一个服务的调用”是什么意思?每个健康端点应该只提供关于自身的信息,而不是关于其他服务的信息。
  • 情况是,如果第一个依赖的第二个服务不起作用,那么第一个也不起作用。
  • 这不是 Kubernetes 的本意。正如我所说,健康/活跃度探测应该检查特定服务。我同意这么随机的家伙在这里的回答,总是返回 200 可能会掩盖服务的真正错误。
  • Liveness 只会检查 http 状态码,不会检查执行器的 status: "up"

标签: spring kubernetes openshift


【解决方案1】:

活性探针

仅包括那些您认为如果失败,将通过重新启动 pod 来解决的检查。拥有一个始终返回 HTTP 200 的新端点并没有错,它将用作活性探测端点;前提是您为您的第一个服务所依赖的其他服务设置了独立的监控和警报。

简单的 http 200 活跃度有什么帮助?

好吧,让我们来看看这些例子。

    1234563它可能会变得没有反应。 pod-restart 在这里会有所帮助。
  1. 如果您在启动应用程序时没有配置内存;在负载过重的情况下,应用程序可能会超出 pod 分配的内存,并且应用程序可能会变得无响应。 pod-restart 在这里也有帮助。

就绪探针

它有两个方面。

1) 让我们考虑一个场景。可以说,在您的第二个服务上启用了身份验证。您的第一个服务(您的健康检查所在的位置)必须正确配置才能使用第二个服务进行身份验证。

我们只是说,在您的第一个服务的后续部署中,您搞砸了您应该从 configmap 或机密中读取的 authheader 变量名称。而且您正在进行滚动更新。

如果您将第二个服务的 http200 也包含在(第一个服务的)健康检查中,那么这将阻止部署的错误版本上线;您的旧版本将继续运行,因为您的新版本将永远无法通过健康检查。我们甚至可能不需要那么复杂的身份验证等等,假设第二个服务的 url 在第一个服务中是硬编码的,而您在随后发布的第一个服务中搞砸了该 url。运行状况检查中的这项额外检查将阻止错误版本上线

2) 另一方面,假设您的第一个服务具有许多其他功能,并且第二个服务关闭几个小时不会影响第一个服务提供的任何重要功能。然后,您可以通过任何方式从第一个服务的健康检查中选择退出第二个服务的活动。

无论哪种方式,您都需要为这两种服务设置适当的警报和监控。这将有助于决定何时应该进行人工干预。

我会做的是(忽略其他不相关的细节),

readinessProbe:
  httpGet:
    path: </Actuator-healthcheck-endpoint>
    port: 8080
  initialDelaySeconds: 120
  timeoutSeconds: 5
livenessProbe:
  httpGet:
    path: </my-custom-endpoint-which-always-returns200>
    port: 8080
  initialDelaySeconds: 130
  timeoutSeconds: 10
  failureThreshold: 10

【讨论】:

    【解决方案2】:

    Spring Boot Actuator 不是为准备就绪而创建自定义控制器(如其他答案中所建议的那样),而是对此具有固有的支持。

    准备就绪

    在 Spring Boot 2.0+ 中,非常容易使用 Spring Boot Actuator 实现就绪探测:

    @Component
    @Endpoint(id = "readiness")
    public class ReadinessEndpoint {
    
        @ReadOperation
        public String getReadiness() {
            // do a custom check for readiness
            if (...) {
    
            } else {
                throw new RuntimeException("Not ready");
            }
        }
    }
    

    此端点随后在/actuator/readiness 可用(默认情况下)。这是可配置的。

    活泼

    Liveliness 已经在位于(默认情况下)/actuator/health 的 Spring Boot Actuator 健康端点中可用。这是可配置的。

    【讨论】:

      【解决方案3】:

      虽然我回复的有点晚。但我认为我的实现将帮助人们在未来为 Spring Boot 应用程序实现 Kubernetes 就绪/活跃度探测。

      我的 docker 镜像的描述

      1. 由 alpine linux 构建
      2. Spring boot 2 应用程序,只能通过 SSL 访问
      3. Spring boot 执行器实现了 /actuator/health,它返回 {"status":"UP"}

      我创建了一个小的 shell 脚本“check-if-healthy.sh”作为 docker 映像的一部分来了解状态

      check-if-healthy.sh
      ===================
      curl -k https://localhost:8888/actuator/health | grep '"status":"UP"' > /dev/null && exit 0 || exit 1
      

      请注意,您需要将此脚本添加到 docker 映像中,以便它可以在运行的容器中使用并可供 kubernetes 访问,因为 kubernetes 将触发 "docker exec /bin/ash /home/config-server/检查是否健康。” 像这样

      COPY docker/check-if-healthy.sh /home/config-server/check-if-healthy.sh
      

      然后使用kubernetes readiness probe的“exec”选项来调用这个脚本。

            readinessProbe:
              exec:
                command:
                  - /bin/ash
                  - /home/config-server/check-if-healthy.sh
              initialDelaySeconds: 5
              timeoutSeconds: 1
              failureThreshold: 50
            livenessProbe:
              exec:
                command:
                  - /bin/ash
                  - /home/config-server/check-if-healthy.sh
              initialDelaySeconds: 5
              timeoutSeconds: 1
              failureThreshold: 50
      

      【讨论】:

        【解决方案4】:

        Spring Boot 2.3 内置了对 Liveness 和 Readiness Probes 的支持:

        Spring Boot 2.3 内置了关于应用程序可用性的知识,可以跟踪它是否处于活动状态以及是否准备好处理流量。

        在 Kubernetes 环境中,执行器将收集 Liveness 和 Readiness 信息,并将其暴露在健康组下。

        "/actuator/health/liveness"
        
        "/actuator/health/readiness"
        

        更多详情请查看blog postdocumentation

        文档摘要:

        应用程序的 Liveness 状态表明内部状态是否有效。如果 Liveness 被破坏,这意味着应用程序本身处于失败状态并且无法从中恢复。在这种情况下,最好的做法是重新启动应用程序实例。例如,如果本地缓存已损坏且无法修复,则依赖于本地缓存的应用程序应使其 Liveness 状态失败。

        Readiness 状态告诉应用程序是否准备好接受客户端请求。如果就绪状态未就绪,Kubernetes 不应将流量路由到此实例。如果应用程序忙于处理任务队列,则它可以将自己声明为忙,直到其负载再次可管理。

        【讨论】:

          猜你喜欢
          • 2020-12-13
          • 2019-05-18
          • 1970-01-01
          • 2023-01-30
          • 1970-01-01
          • 1970-01-01
          • 2020-12-26
          • 2020-02-05
          • 1970-01-01
          相关资源
          最近更新 更多