【问题标题】:Kubernetes Service unavailable when container crashes容器崩溃时 Kubernetes Service 不可用
【发布时间】:2021-10-05 08:38:27
【问题描述】:

在我的 Kubernetes 集群中,我有一个带有两个容器的 pod(即一个副本):servercache

我还有一个与我的 pod 匹配的 Kubernetes Service

如果cache 崩溃,当我尝试通过Serviceserver 发送HTTP 请求时,我会收到“503 服务暂时不可用”。

HTTP 请求通过 Nginx Ingress 进入集群,我怀疑问题是当 cache 崩溃时,Kubernetes 会从 Service 负载均衡器中删除我的一个 pod,正如 Kubernetes documentation 中所承诺的那样:

kubelet 使用就绪探测来了解容器何时准备好开始接受流量。当 Pod 的所有容器都准备好时,就认为 Pod 准备好了。此信号的一种用途是控制哪些 Pod 用作服务的后端。当 Pod 未准备好时,它会从服务负载均衡器中移除。

我不喜欢这种行为,因为即使cache 失败,我仍然希望server 能够响应请求。有没有办法获得这种期望的行为?

【问题讨论】:

  • 让我们看看你的部署配置
  • 分享完整的部署会很多——为了分享的目的,我创建了一个玩具示例。
  • 虽然没有活性或就绪性探测

标签: kubernetes kubernetes-pod kubernetes-service


【解决方案1】:

如果出现以下情况之一,则 POD 将进入“失败”状态

  • 其中一个容器以非零状态退出
  • Kubernates 由于运行状况检查失败而终止容器

因此,如果您需要其中一个容器在另一个容器发生故障时仍能做出响应,

  1. 确保您的活跃度探针指向您需要继续的容器。健康检查器将始终获得成功代码,并且不会将 POD 标记为“失败”

  2. 确保就绪探测指向您需要继续的容器。这将确保负载均衡器仍将流量发送到您的 pod。

  3. 确保您优雅地处理容器错误并让它们以零状态码退出。

在下面的就绪和活跃度探测示例中,确保端口 8080 由 service 容器处理,并且它的 /healthz/ready 路由处于活动状态。

    readinessProbe:
      httpGet:
        path: /healthz
        port: 8080
      initialDelaySeconds: 5
      periodSeconds: 5
    livenessProbe:
      httpGet:
        path: /ready
        port: 8080
      initialDelaySeconds: 5
      timeoutSeconds: 1

【讨论】:

  • 如果 pod 失败是因为其中一个容器以非零状态退出,我们可以使用 liveness / readiness 探针来解决这个问题吗?或者在这种情况下,探测器无关紧要?
  • 尝试将 POD 的 restartPolicy 设置为 Never。这适用于所有容器。
  • 期望的行为是,即使cache 以非零状态存在,server 仍然可以出现在Service 的可用后端列表中。如果我们使用restartPolicy: Never,那是不是意味着如果cache 退出,我们只会丢失pod?
  • Kubernates 不会尝试为这些设置重新启动容器。所以,我相信它会忽略非零状态。试一试。
  • 是的,这行得通。谢谢!想知道是否有办法在没有restartPolicy: Never 的情况下获得所需的行为。
【解决方案2】:

我正在寻找的行为可以通过publishNotReadyAddresses 选项在Service 本身上进行配置:

https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.21/#servicespec-v1-core

【讨论】:

    猜你喜欢
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    • 2019-01-25
    • 1970-01-01
    • 2016-06-02
    • 1970-01-01
    • 1970-01-01
    • 2021-12-23
    相关资源
    最近更新 更多