指定了 startupProbe 和 initialDelaySeconds 的 K8S Pod 等待太长时间才能变为就绪

All*_*len 5 kubernetes kubernetes-deployment kubernetes-pod microk8s

我一直在尝试调试 K8S 部署中的一个非常奇怪的延迟。我已经追踪到下面的简单复制。看起来是,如果我在启动探测器上设置了一个 initialDelaySeconds 或将其保留为 0 并且有一次失败,那么探测器在一段时间内不会再次运行,并以至少 1-1.5 分钟的延迟进入就绪状态:真状态。

我在本地使用 Ubutunu 18.04 和 microk8s v1.19.3 运行以下版本:

  • kubelet:v1.19.3-34+a56971609ff35a
  • kube 代理:v1.19.3-34+a56971609ff35a
  • 容器d://1.3.7
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: microbot
  name: microbot
spec:
  replicas: 1
  selector:
    matchLabels:
      app: microbot
  strategy: {}
  template:
    metadata:
      labels:
        app: microbot
    spec:
      containers:
      - image: cdkbot/microbot-amd64
        name: microbot
        command: ["/bin/sh"]
        args: ["-c", "sleep 3; /start_nginx.sh"]
        #args: ["-c", "/start_nginx.sh"]
        ports:
        - containerPort: 80
        startupProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 0  # 5 also has same issue
          periodSeconds: 1
          failureThreshold: 10
          successThreshold: 1
        ##livenessProbe:
        ##  httpGet:
        ##    path: /
        ##    port: 80
        ##  initialDelaySeconds: 0
        ##  periodSeconds: 10
        ##  failureThreshold: 1
        resources: {}
      restartPolicy: Always
      serviceAccountName: ""
status: {}
---
apiVersion: v1
kind: Service
metadata:
  name: microbot
  labels:
    app: microbot
spec:
  ports:
    - port: 80
      protocol: TCP
      targetPort: 80
  selector:
    app: microbot
Run Code Online (Sandbox Code Playgroud)

问题是,如果我在 startupProbe 中有任何延迟,或者如果出现初始故障,pod 会进入 Initialized:true 状态,但具有 Ready:False 和 ContainersReady:False。1-1.5 分钟内不会从此状态改变。我还没有找到设置的模式。

我也留下了注释设置,这样你就可以看到我想在这里做什么。我拥有的是一个正在启动的容器,它有一项需要几秒钟才能启动的服务。我想告诉 startupProbe 稍等片刻,然后每秒检查一下,看看我们是否准备好了。配置似乎有效,但有一个我无法追踪的延迟。即使在启动探针通过后,它也不会将 pod 转换为 Ready 超过一分钟。

如果 Pod 最初未就绪,k8s 中的其他地方是否有一些设置会延迟 Pod 进入就绪状态之前的时间?

任何想法都非常感谢。

jt9*_*t97 5

其实我在评论中犯了一个错误,你可以initialDelaySeconds在startupProbe中使用,但你应该使用failureThresholdandperiodSeconds来代替。


正如这里提到的

Kubernetes 探针

Kubernetes 支持版本的就绪和活跃度探测吗?1.15. 启动探针在 1.16 中作为 alpha 功能添加,并在 1.18 中升级为 beta(警告:1.16 弃用了几个 Kubernetes API。使用此迁移指南检查兼容性)。所有探头都有以下参数:

  • initialDelaySeconds : 在启动活跃度或就绪度探测之前等待的秒数
  • periodSeconds:多久检查一次探针
  • timeoutSeconds:将探测标记为超时之前的秒数(健康检查失败)
  • successThreshold :探测通过的最小连续成功检查次数
  • failureThreshold :将探测标记为失败之前的重试次数。对于活性探针,这将导致 pod 重新启动。对于就绪探针,这会将 pod 标记为未就绪。

那么为什么要使用failureThresholdandperiodSeconds呢?

考虑一个应用程序,它偶尔需要下载大量数据或在流程开始时执行昂贵的操作。由于initialDelaySeconds是一个静态数字,我们被迫总是采取最坏的情况(或延长可能影响长时间运行行为的failureThreshold)并等待很长时间,即使该应用程序不需要进行长时间运行初始化步骤。随着启动探头,我们可以自行配置failureThresholdperiodSeconds这种不确定性更好的模型。例如,设置failureThreshold至15和periodSeconds至5的装置,应用程序将获得15(15)×5(五)= 75S到启动失败之前。

此外,如果您需要更多信息,请查看有关媒体的这篇文章


引用自 kubernetes文档关于使用启动探针保护慢启动容器

有时,您必须处理在首次初始化时可能需要额外启动时间的遗留应用程序。在这种情况下,在不影响对激发这种探测的死锁的快速响应的情况下设置活性探测参数可能会很棘手。诀窍是使用相同的命令(HTTP 或 TCP 检查)设置启动探测,并使用足够长的 failureThreshold * periodSeconds 来覆盖最坏情况下的启动时间。

因此,前面的示例将变为:

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
Run Code Online (Sandbox Code Playgroud)

多亏了启动探针,应用程序将有最多 5 分钟(30 * 10 = 300 秒)的时间来完成其启动。一旦启动探测器成功一次,活性探测器就会接管以提供对容器死锁的快速响应。如果启动探测从未成功,容器会在 300 秒后被杀死并受 pod 的 restartPolicy 约束。