【问题标题】:Can a deployment be completed even when readiness probe is failing即使就绪探测失败,部署也能完成吗
【发布时间】:2021-11-04 15:30:40
【问题描述】:

我有一个在 Kubernetes 中以StatefulSet 运行的应用程序,它启动了 2 个 pod。它已经配置了一个 liveness probe 和一个 readiness probe。

liveness probe 调用一个简单的/health 端点,该端点在服务器完成加载时做出响应

readiness probe,等待一些启动工作完成。在某些情况下,该作业可能需要几分钟时间,并且只有当它完成应用程序的 api 才准备好开始接受请求。

即使 api 不可用,我的应用也会运行不依赖它的辅助作业,我希望它们也能在启动时完成。

是否可以强制 Kubernetes 部署完成并部署 2 个 Pod,即使就绪探测仍未通过?

从文档中我了解到,没有通过就绪探测的唯一影响是当前 pod 不会包含在负载均衡器服务中(这实际上是我想要的唯一效果)。

如果就绪探测失败,端点控制器将删除 Pod 的 IP 地址来自所有匹配的服务的端点 豆荚。

但是我也看到部署永远不会完成,因为 pod 1 就绪探测没有通过并且 pod 2 从未创建。

kubectl rollout restart statefulset/pod
kubectl get pods 
NAME                            READY   STATUS    RESTARTS   AGE
pod-0                           1/2     Running   0          28m

如果就绪探测失败,请始终阻止部署,是否有其他方法可以选择性地仅在负载均衡器中公开就绪的 Pod,同时在部署期间不将它们标记为未就绪?

提前致谢!

【问题讨论】:

  • 即使 api 不可用,我的应用程序也会运行不依赖它的辅助作业,我希望它们也能在启动时完成。 .那么“副业”应该从 API 中分离出来。
  • 同意,虽然这是我目前无法在我的应用程序中控制的事情
  • 澄清一下,pod-0 ready 1/2 表示这个 pod 由 2 个容器组成,而第二个容器无法创建?第一个是初始化容器吗?
  • 没错,我忘了说,每个 pod 上都有一个 init 容器,可以正常启动。问题是我的部署中还应该有一个 pod-1 永远不会出现。

标签: kubernetes kubectl kubernetes-statefulset kubernetes-deployment


【解决方案1】:

StatefulSet 部署

是否可以强制kubernetes部署完成并部署2 pods,即使就绪探测仍未通过?

假设它的意思是 statefulSet 而不是 deployment 作为对象,答案是否定的,这在设计上是不可能的,最重要的是第二点:

  • 对于具有 N 个副本的 StatefulSet,在部署 Pod 时,它们是按顺序创建的,从 {0..N-1} 开始。
  • 在对 Pod 应用扩展操作之前,它的所有前驱都必须处于运行和就绪状态。
  • 当 Pod 被删除时,它们会以相反的顺序从 {N-1..0} 终止。

当上面的 nginx 示例创建时,会部署三个 Pod 按照 web-0、web-1、web-2 的顺序。之前不会部署 web-1 web-0 正在运行并准备就绪,直到 web-1 才会部署 web-2 正在运行并准备就绪

StatefulSets - Deployment and scaling guaranties

就绪探测、端点和潜在的解决方法

如果就绪探测失败,总是阻止部署,是 还有其他方法可以选择性地仅在负载中公开准备好的 pod 平衡器,而不是在部署期间将它们标记为未就绪?

这是设计使然,一旦 Pod 处于 ready 状态,就会将它们添加到服务端点。

可以使用某种潜在的解决方法,至少在简单的示例中它确实有效,但是您应该尝试评估这种方法是否适合您的情况,这可以用作初始部署。

statefulSet 可以在不包含readyness 探针的情况下启动,这样statefulSet 将在之前为run and ready 时一个一个启动pod,liveness 可能需要设置initialDelaySeconds 所以kubernetes 不会重新启动 pod,认为它不健康。一旦statefulSet 完全运行并准备就绪,您可以将readyness 探针添加到statefulSet

当添加readyness 探针时,kubernetes 将从最后一个开始重新启动所有 pod,您的应用程序将需要重新启动。

想法是启动所有 pod,它们将能够同时处理请求 +-,而在应用 readyness 探测的情况下,例如只有一个 pod 将在 5 分钟内启动,下一个 pod 将需要 5 分钟以上等等。

示例

基于nginx webserver 和sleep 30 命令查看发生了什么的简单示例,这使得 kubernetes 在设置readyness 探针时认为 pod 是not ready

  1. 申请headless service
  2. statefulSet 中评论readyness 探测并应用清单
  3. 观察到所有 pod 都是在前一个 pod 为 running and ready 之后立即创建的
  4. 取消注释 readyness 探测并应用清单
  5. Kubernetes 将重新创建从最后一个开始的所有 Pod,这次等待 readyness 探测完成并将 Pod 标记为 running and ready

用这个命令看进度非常方便:

watch -n1 kubectl get pods -o wide

nginx-headless-svc.yaml:

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx

nginx-statefulset.yaml:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  serviceName: "nginx"
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
          name: web
        command: ["/bin/bash", "-c"]
        args: ["sleep 30 ; echo sleep completed ;  nginx -g \"daemon off;\""]
        readinessProbe:
          tcpSocket:
            port: 80
          initialDelaySeconds: 1
          periodSeconds: 5

更新

感谢@jesantana 提供了这个更简单的解决方案。

如果必须同时安排所有 pod 并且无需等待 pod 就绪,则可以将 .spec.podManagementPolicy 设置为 ParallelPod Management Policies

有用的链接:

【讨论】:

  • 在发现“在对 Pod 应用缩放操作之前,其所有前辈必须处于运行和就绪状态”之后。我们评估了将 statefulset 上的 podmanagementpolicy 更改为并行,但我们有停机时间,最后我们删除了 readinessProbe 并在应用程序级别进行了检查
猜你喜欢
  • 2020-03-17
  • 1970-01-01
  • 2019-12-05
  • 2018-07-10
  • 1970-01-01
  • 2021-09-01
  • 2021-02-06
  • 2019-09-24
  • 2019-10-12
相关资源
最近更新 更多