Задание Kubernetes продолжает запускать поды, которые в итоге получают статус `` Ошибка '' - PullRequest
0 голосов
/ 18 июня 2020

Я работаю над заданием cron Kubernetes, которое представляет собой интеграционный тест; это тестовый двоичный файл Go, который компилируется с помощью go test -c и копируется в контейнер Docker, запускаемый заданием cron. Kubernetes YAML запускается примерно так:

apiVersion: batch/v1beta1
kind: CronJob
spec:
  schedule: "*/15 * * * *"
  concurrencyPolicy: Forbid
  successfulJobsHistoryLimit: 7
  failedJobsHistoryLimit: 7
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: Never

В какой-то момент запуск интеграционного теста завершается неудачно (выход с кодом 1). Я вижу, что задание имеет ту же продолжительность, что и его возраст:

$ kubectl get jobs -l app=integration-test
NAME                          COMPLETIONS   DURATION   AGE
integration-test-1592457300   0/1           7m20s      7m20s

Команды kubectl get pods показывают, что поды создаются чаще, чем каждые 15 минут, как я ожидал от расписания cron:

$ kubectl get pods -l app=integration-test
NAME                                READY   STATUS   RESTARTS   AGE
integration-test-1592457300-224x8   0/1     Error    0          92s
integration-test-1592457300-5f8sz   0/1     Error    0          7m33s
integration-test-1592457300-9zvjq   0/1     Error    0          3m57s
integration-test-1592457300-th7sf   0/1     Error    0          6m26s
integration-test-1592457300-vhbr2   0/1     Error    0          5m17s

Такое поведение при развертывании новых модулей является проблемным c, потому что оно способствует подсчету запущенных модулей на узле - по сути, это потребляет ресурсы.

Как я могу сделать так, чтобы задание cron не запускает новые поды, а делает только один каждые 15 минут и не продолжает потреблять ресурсы в случае сбоя задания?

Обновление

Упрощенный пример здесь используется Kubernetes YAML, адаптированный из https://kubernetes.io/docs/tasks/job/automated-tasks-with-cron-jobs/:

$ cat cronjob.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            args:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster; exit 1
          restartPolicy: Never

Обратите внимание, что он выходит с кодом 1. Если я запустил это с помощью kubernetes apply -f cronjob.yaml, а затем проверил модули, я увижу

$ kubectl get pods
NAME                                                    READY   STATUS      RESTARTS   AGE
hello-1592459760-fnvcw                                  0/1     Error       0          30s
hello-1592459760-w75lt                                  0/1     Error       0          31s
hello-1592459760-xzhwn                                  0/1     Error       0          20s

Возраст стручков меньше минуты; другими словами, поды запускаются до истечения интервала cron. Как я могу это предотвратить?

Ответы [ 2 ]

2 голосов
/ 18 июня 2020

Это вполне конкретный c сценарий, и трудно угадать, чего вы хотите достичь ie и сработает ли он для вас.

concurrencyPolicy: Forbid не позволяет job, если предыдущее не было completed. Но я думаю, что здесь не так.

restartPolicy применяется к pod (однако в Job template вы можете использовать только OnFailure и Never). Если вы установите restartPolicy на Never, job автоматически создаст новый pods до завершения.

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

Если вы установите restartPolicy: Never, он будет создавать поды, пока не достигнет backoffLimit , однако эти pods будут по-прежнему видны в вашем кластере со статусом Error как каждый выход из капсулы с status 1. Вам нужно будет удалить его вручную. Если вы установите restartPolicy: OnFailure, он будет перезапускать один pod и больше не будет создавать.

Но есть другой способ. Что считается заданием completed?

Примеры:

1. restartPolicy: OnFailure

$ kubectl get po,jobs,cronjob
NAME                         READY   STATUS             RESTARTS   AGE
pod/hello-1592495280-w27mt   0/1     CrashLoopBackOff   5          5m21s
pod/hello-1592495340-tzc64   0/1     CrashLoopBackOff   5          4m21s
pod/hello-1592495400-w8cm6   0/1     CrashLoopBackOff   5          3m21s
pod/hello-1592495460-jjlx5   0/1     CrashLoopBackOff   4          2m21s
pod/hello-1592495520-c59tm   0/1     CrashLoopBackOff   3          80s
pod/hello-1592495580-rrdzw   0/1     Error              2          20s
NAME                         COMPLETIONS   DURATION   AGE
job.batch/hello-1592495220   0/1           6m22s      6m22s
job.batch/hello-1592495280   0/1           5m22s      5m22s
job.batch/hello-1592495340   0/1           4m22s      4m22s
job.batch/hello-1592495400   0/1           3m22s      3m22s
job.batch/hello-1592495460   0/1           2m22s      2m22s
job.batch/hello-1592495520   0/1           81s        81s
job.batch/hello-1592495580   0/1           21s        21s
NAME                  SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
cronjob.batch/hello   */1 * * * *   False     6        25s             15m

Каждый job создаст только 1 pod, который будет перезапущен до тех пор, пока job не станет finished или будет считаться completed на CronJob.

Если вы опишите CronJob в разделе Event, то можете найти.

Events:
  Type    Reason            Age                  From                Message
  ----    ------            ----                 ----                -------
  Normal  SuccessfulCreate  18m                  cronjob-controller  Created job hello-1592494740
  Normal  SuccessfulCreate  17m                  cronjob-controller  Created job hello-1592494800
  Normal  SuccessfulCreate  16m                  cronjob-controller  Created job hello-1592494860
  Normal  SuccessfulCreate  15m                  cronjob-controller  Created job hello-1592494920
  Normal  SuccessfulCreate  14m                  cronjob-controller  Created job hello-1592494980
  Normal  SuccessfulCreate  13m                  cronjob-controller  Created job hello-1592495040
  Normal  SawCompletedJob   12m                  cronjob-controller  Saw completed job: hello-1592494740
  Normal  SuccessfulCreate  12m                  cronjob-controller  Created job hello-1592495100
  Normal  SawCompletedJob   11m                  cronjob-controller  Saw completed job: hello-1592494800
  Normal  SuccessfulDelete  11m                  cronjob-controller  Deleted job hello-1592494740
  Normal  SuccessfulCreate  11m                  cronjob-controller  Created job hello-1592495160
  Normal  SawCompletedJob   10m                  cronjob-controller  Saw completed job: hello-1592494860

Почему работа hello-1592494740 считалась Completed? Cronjob значение по умолчанию .spec.backoffLimit - 6 (эту информацию можно найти в документации). Если job потерпит неудачу 6 раз (модуль не перезапустится 6 раз), Cronjob сочтет это job как Completed и удалит его. Поскольку job был удален, также будет удален и pod.

Однако в вашем примере pod был создан, дата выполнения модуля и команда echo, а затем выйдите с кодом 1. Даже если pod Вылетает написанная информация. Поскольку последняя команда была exit 1, она будет вылетать, пока не достигнет предела. В соответствии с примером ниже:

$ kubectl get pods
NAME                     READY   STATUS             RESTARTS   AGE
hello-1592495400-w8cm6   0/1     Terminating        6          5m51s
hello-1592495460-jjlx5   0/1     CrashLoopBackOff   5          4m51s
hello-1592495520-c59tm   0/1     CrashLoopBackOff   5          3m50s
hello-1592495580-rrdzw   0/1     CrashLoopBackOff   4          2m50s
hello-1592495640-nbq59   0/1     CrashLoopBackOff   4          110s
hello-1592495700-p6pcx   0/1     Error              3          50s
user@cloudshell:~ (project)$ kubectl logs hello-1592495520-c59tm
Thu Jun 18 15:55:13 UTC 2020
Hello from the Kubernetes cluster

2. restartPolicy: Never и backoffLimit: 0

YAML был использован ниже:

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            args:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster; exit 1
          restartPolicy: Never
      backoffLimit: 0

Вывод

$ kubectl get po,jobs,cronjob
NAME                         READY   STATUS   RESTARTS   AGE
pod/hello-1592497320-svd6k   0/1     Error    0          44s
NAME                         COMPLETIONS   DURATION   AGE
job.batch/hello-1592497320   0/1           44s        44s
NAME                  SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
cronjob.batch/hello   */1 * * * *   False     0        51s             11m

$ kubectl describe cronjob
...
Events:
  Type    Reason            Age                  From                Message
  ----    ------            ----                 ----                -------
  Normal  SuccessfulCreate  12m                  cronjob-controller  Created job hello-1592496720
  Normal  SawCompletedJob   11m                  cronjob-controller  Saw completed job: hello-1592496720
  Normal  SuccessfulCreate  11m                  cronjob-controller  Created job hello-1592496780
  Normal  SawCompletedJob   10m                  cronjob-controller  Saw completed job: hello-1592496780
  Normal  SuccessfulDelete  10m                  cronjob-controller  Deleted job hello-1592496720
  Normal  SuccessfulCreate  10m                  cronjob-controller  Created job hello-1592496840
  Normal  SuccessfulDelete  9m55s                cronjob-controller  Deleted job hello-1592496780
  Normal  SawCompletedJob   9m55s                cronjob-controller  Saw completed job: hello-1592496840
  Normal  SuccessfulCreate  9m5s                 cronjob-controller  Created job hello-1592496900
  Normal  SawCompletedJob   8m55s                cronjob-controller  Saw completed job: hello-1592496900
  Normal  SuccessfulDelete  8m55s                cronjob-controller  Deleted job hello-1592496840
  Normal  SuccessfulCreate  8m5s                 cronjob-controller  Created job hello-1592496960
  Normal  SawCompletedJob   7m55s                cronjob-controller  Saw completed job: hello-1592496960
  Normal  SuccessfulDelete  7m55s                cronjob-controller  Deleted job hello-1592496900
  Normal  SuccessfulCreate  7m4s                 cronjob-controller  Created job hello-1592497020

Таким образом, только один job и один pod будут работать одновременно (может быть 10-секундный перерыв, когда будет 2 задания и 2 модуля).

$ kubectl get po,job
NAME                         READY   STATUS   RESTARTS   AGE
pod/hello-1592497440-twzlf   0/1     Error    0          70s
pod/hello-1592497500-2q7fq   0/1     Error    0          10s

NAME                         COMPLETIONS   DURATION   AGE
job.batch/hello-1592497440   0/1           70s        70s
job.batch/hello-1592497500   0/1           10s        10s
user@cloudshell:~ (project)$ kk get po,job
NAME                         READY   STATUS   RESTARTS   AGE
pod/hello-1592497500-2q7fq   0/1     Error    0          11s

NAME                         COMPLETIONS   DURATION   AGE
job.batch/hello-1592497500   0/1           11s        11s

Надеюсь, это немного прояснилось. Если вы хотите получить более точный ответ, опишите подробнее свой сценарий.

0 голосов
/ 18 июня 2020

По умолчанию concurrencyPolicy : Разрешить.

Вы можете установить concurrencyPolicy: Forbid, чтобы избежать параллельного выполнения новых заданий.

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "* * * * *"
  # Allow | Forbid | Replace
  concurrencyPolicy: Forbid
  jobTemplate:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...