Pods被卡在PodInitializing状态中无限期地。

38

我有一个由一个init容器和一个Pod容器组成的k8s定时任务。如果init容器失败,主容器中的Pod永远不会启动,并且一直停留在“PodInitializing”状态。

我的意图是,如果init容器失败,任务应该失败。

---
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: job-name
  namespace: default
  labels:
    run: job-name
spec:
  schedule: "15 23 * * *"
  startingDeadlineSeconds: 60
  concurrencyPolicy: "Forbid"
  successfulJobsHistoryLimit: 30
  failedJobsHistoryLimit: 10
  jobTemplate:
    spec:
      # only try twice
      backoffLimit: 2
      activeDeadlineSeconds: 60
      template:
        spec:
          initContainers:
          - name: init-name
            image: init-image:1.0
          restartPolicy: Never
          containers:
          - name: some-name
            image: someimage:1.0
          restartPolicy: Never

当在卡住的Pod上运行kubectl时,结果如下:

Name:               job-name-1542237120-rgvzl
Namespace:          default
Priority:           0
PriorityClassName:  <none>
Node:               my-node-98afffbf-0psc/10.0.0.0
Start Time:         Wed, 14 Nov 2018 23:12:16 +0000
Labels:             controller-uid=ID
                    job-name=job-name-1542237120
Annotations:        kubernetes.io/limit-ranger:
                      LimitRanger plugin set: cpu request for container elasticsearch-metrics; cpu request for init container elasticsearch-repo-setup; cpu requ...
Status:             Failed
IP:                 10.0.0.0
Controlled By:      Job/job-1542237120
Init Containers:
init-container-name:
    Container ID:  docker://ID
    Image:         init-image:1.0
    Image ID:      init-imageID
    Port:          <none>
    Host Port:     <none>
    State:          Terminated
      Reason:       Error
      Exit Code:    1
      Started:      Wed, 14 Nov 2018 23:12:21 +0000
      Finished:     Wed, 14 Nov 2018 23:12:32 +0000
    Ready:          False
    Restart Count:  0
    Requests:
      cpu:        100m
    Environment:  <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-wwl5n (ro)
Containers:
  some-name:
    Container ID:  
    Image:         someimage:1.0
    Image ID:      
    Port:          <none>
    Host Port:     <none>
    State:          Waiting
      Reason:       PodInitializing
    Ready:          False
    Restart Count:  0
    Requests:
      cpu:        100m
    Environment:  <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-wwl5n (ro)
Conditions:
  Type              Status
  Initialized       False 
  Ready             False 
  ContainersReady   False 
  PodScheduled      True

3
使用 kubectl logs <pod> -c <init_container_name> 命令查看初始化容器的日志总是很有帮助的! - Ivan Aracki
1
谢谢,我知道为什么它失败了,如果它失败了也没关系,问题是在于如何应对成功/失败的情况 :) - Anderson
4个回答

38
为了尝试找出问题,我会运行以下命令:
kubectl get pods - 如果需要,请添加命名空间参数。
然后复制Pod名称并运行:
kubectl describe pod {POD_NAME}
这应该会提供一些关于为什么它卡在初始化状态的信息。

2
我认为这是init容器的设计问题,它不会启动主容器,直到所有的init容器都成功运行。缺陷可能在于init容器不应该失败(在我的情况下,我确实失败了)。我继续对pod进行了描述。我已经将描述的结果添加到原始帖子中。 - Anderson

33

由于多种原因,Pod 可能会陷入初始化状态。

PodInitializing 或 Init 状态意味着该 Pod 包含一个未完成的 Init 容器(Init 容器:在 Pod 中应用容器运行之前运行的专用容器,Init 容器可以包含实用程序或设置脚本)。如果 Pod 的状态为“Init:0/1”,则表示有一个 init 容器未完成;init:N/M 意味着 Pod 有 M 个 Init 容器,目前已经完成 N 个。

Architecture



收集信息

针对这些情况,最好的方法是收集信息,因为每个 PodInitializing 问题的根本原因都可能不同。

  • 通过执行命令 kubectl describe pods pod-XXX,您可以获取 Pod 的许多信息,也可以检查是否存在任何有意义的事件。并保存 init 容器名称

  • 通过执行命令 kubectl logs pod-XXX,可以打印出 Pod 或指定资源中容器的日志。

  • kubectl logs pod-XXX -c init-container-xxx 是最准确的打印初始化容器日志的方法。为了替换成示例中的 “copy-default-config”,可以获取描述 Pod 的初始化容器名称:

    enter image description here

    kubectl logs pod-XXX -c init-container-xxx 命令的输出能够提供有关问题的有效信息,参见如下截图:

    Image-logs

    如上图所示,根本原因是初始化容器无法从 Jenkins 下载插件(超时),我们可以检查连接配置、代理、DNS 或者修改 YAML 文件,以便在不使用插件的情况下部署容器。

附加:

  • kubectl describe node node-XXX 命令描述 Pod 将会给出其节点名称,使用此命令还可以检查该节点。

  • kubectl get events 命令列出集群事件。

  • journalctl -xeu kubelet | tail -n 10 命令记录 systemd 的 kubelet 日志(journalctl -xeu docker | tail -n 1 可用于 Docker)。


解决方案

解决方案取决于收集到的信息,一旦找到根本原因

当您找到具有根本原因见解的日志时,可以研究该特定的根本原因。

以下是一些示例:

1 > 在这种情况下,当删除init容器时发生了这种情况,可以通过删除Pod以便重新创建它或重新部署来修复。在1.1相同的场景中也适用。

2 > 如果您发现“bad address 'kube-dns.kube-system'”,PVC可能无法正确回收,2提供的解决方案是运行/opt/kubernetes/bin/kube-restart.sh

3 > 在那里,找不到sh文件,解决方案是修改yaml文件或删除不必要的容器。

4 > 发现了一个 FailedSync,重启节点上的 Docker 可以解决这个问题。

通常情况下,您可以修改 YAML 文件,例如避免使用过时的 URL,尝试重新创建受影响的资源,或者仅从部署中删除导致问题的 init 容器。但具体解决方案将取决于具体的根本原因。


如果Pod的容器的postStart钩子中的一个不退出,它也会导致整个Pod被永远卡在PodInitializing状态中,而没有明确的错误原因。它还会阻止Pod的删除。 - undefined

7
我认为您可能会忽略初始化容器的预期行为。 规则是,如果初始化容器失败,则Pod不会重新启动,如果重启策略设置为Never,否则Kubernetes将继续重启它直到成功为止。
另外:
如果初始化容器失败,则主容器中的Pod永远不会启动,并且将无限期地停留在“PodInitializing”状态。
根据documentation: 一个Pod在所有Init Containers成功之前不能准备就绪。 Init Container上的端口未在服务下聚合。正在初始化的Pod处于挂起状态,但应具有设置为true的Initializing条件。
*我可以看到您尝试更改此行为,但我不确定您是否可以使用CronJob来执行此操作。我看到了一些使用Jobs的示例。但我只是理论推测,如果这篇文章没有帮助您解决问题,我可以尝试在实验室环境中重新创建它。

谢谢。我有点明白了,初始化容器并不适用于此,但如果我能自动消除PodInitialising作业,那就太好了。你说你看到了一些使用作业的例子?你能提供这些例子吗?CronJob只是控制器,Pods在jobspec下声明,所以如果我能让作业失败,那么就可以解决我的问题。 - Anderson

0

既然您已经了解到 initcontainers 的目的是要成功地运行到完成。如果您无法摆脱 init containers,我会在这种情况下确保 init container 每次都能成功地结束。init container 的结果可以写入一个 emptydir volume,类似于状态文件,由 init container 和工作 container 共享。我会将工作 container 的责任委托给它来决定在 init container 未能成功结束时该怎么做。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接