Бобы застряли в состоянии PodInitializing на неопределенное время

У меня есть cronjob k8s, который состоит из контейнера init и контейнера с одним модулем. Если происходит сбой контейнера 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

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

4 ответа

Чтобы попытаться понять это, я бы запустил команду:

kubectl get pods - Добавьте параметр пространства имен, если требуется.

Затем скопируйте имя модуля и запустите:

kubectl describe pod {POD_NAME}

Это должно дать вам некоторую информацию о том, почему он застрял в исходном состоянии.

Pod может застрять в статусе Init по многим причинам.

PodInitializing или статус инициализации означает, что Pod содержит контейнер инициализации, который не был завершен (контейнеры инициализации: специализированные контейнеры, которые запускаются перед контейнерами приложений в модуле, контейнеры инициализации могут содержать утилиты или сценарии установки). Если статус подов - «Init: 0/1», это означает, что один контейнер инициализации не завершен; init:N/M означает, что у Pod есть M начальных контейнеров, и N завершено на данный момент.



Собирая информацию

Для этого сценария лучше всего будет собрать информацию, поскольку основная причина может быть различной в каждой проблеме PodInitializing.

  • kubectl describe pods pod-XXXс помощью этой команды вы можете получить много информации о модуле, вы также можете проверить, есть ли какое-либо значимое событие. Сохраните имя контейнера инициализации

  • kubectl logs pod-XXX эта команда печатает журналы для контейнера в модуле или указанного ресурса.

  • Это наиболее точный способ печати журналов контейнера инициализации. Вы можете получить имя контейнера инициализации, описывающее модуль, чтобы заменить «init-container-XXX», например, на «copy-default-config», как показано ниже:

    Выход kubectl logs pod-XXX -c init-container-xxx может выдать значимую информацию о проблеме, ссылка:

    На изображении выше мы видим, что основная причина в том, что контейнер инициализации не может загрузить плагины из jenkins (тайм-аут), теперь мы можем проверить конфигурацию соединения, прокси, DNS; или просто измените yaml, чтобы развернуть контейнер без плагинов.

Дополнительный:

  • kubectl describe node node-XXX описание модуля даст вам имя его узла, которое вы также можете проверить с помощью этой команды.

  • kubectl get events для вывода списка событий кластера.

  • journalctl -xeu kubelet | tail -n 10kubelet регистрируется в systemd ( journalctl -xeu docker | tail -n 1 для докера).


Решения

Решение зависит от собранной информации после того, как будет найдена основная причина .

Когда вы найдете журнал с описанием основной причины, вы сможете исследовать эту конкретную основную причину.

Некоторые примеры:

1 > Там это произошло, когда контейнер инициализации был удален, можно исправить удаление модуля, чтобы он был воссоздан, или повторно развернуть его. Тот же сценарий в 1.1.

> Если вы обнаружили «неправильный адрес 'kube-dns.kube-system'», возможно, PVC переработан неправильно, решение, представленное в 22 , работает. /opt/kubernetes/bin/kube-restart.sh.

3 > Там sh-файл не найден, решением будет изменить yaml-файл или удалить контейнер, если это не нужно.

4 > Был обнаружен FailedSync, и было решено перезапустить докер на узле.

В общем, вы можете изменить yaml, например, чтобы избежать использования устаревшего URL-адреса, попытаться воссоздать затронутый ресурс или просто удалить контейнер инициализации, вызывающий проблему, из вашего развертывания. Однако конкретное решение будет зависеть от конкретной первопричины.

Я думаю, что вы можете пропустить, что это ожидаемое поведение контейнеров init. Правило состоит в том, что в случае сбоя initContainers модуль Pod не будет перезапущен, если для restartPolicy установлено значение Never, иначе Kubernetes продолжит перезапускать его до тех пор, пока он не завершится успешно.

Также:

Если происходит сбой контейнера init, Pod в главном контейнере никогда не запускается и остается в "PodInitializing" бесконечно.

Согласно документации:

Модуль не может быть готов, пока все контейнеры инициализации не будут выполнены успешно. Порты в контейнере инициализации не агрегированы в рамках службы. Блок, который инициализируется, находится в состоянии ожидания, но для условия инициализации должно быть установлено значение true.

* Я вижу, что вы пытались изменить это поведение, но я не уверен, что вы можете сделать это с CronJob, я видел примеры с Джобсом. Но я просто теоретизирую, и если этот пост не помог вам решить вашу проблему, я могу попытаться воссоздать ее в лабораторной среде.

Поскольку вы уже выяснили, что initcontainers предназначены для успешного выполнения до конца. Если вы не можете избавиться от init-контейнеров, то в этом случае я бы хотел убедиться, что init-контейнер все время успешно завершается. Результат контейнера init может быть записан в томе emptydir, что-то вроде файла состояния, совместно используемом как контейнером init, так и вашим рабочим контейнером. Я бы делегировал рабочему контейнеру ответственность за решение, что делать в случае неудачного завершения контейнера init.

Другие вопросы по тегам