Це багатосторінковий друкований вигляд цього розділу. Натисність щоб друкувати.

Повернутися до звичайного перегляду сторінки.

Запуск Jobs

Запуск Jobs із паралельною обробкою.

1 - Виконання автоматизованих завдань за допомогою CronJob

На цій сторінці показано, як виконувати автоматизовані завдання за допомогою обʼєкта Kubernetes CronJob.

Перш ніж ви розпочнете

  • Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:

Створення CronJob

CronJobs потребують файлу конфігурації. Ось маніфест CronJob, який щохвилини запускає просте демонстраційне завдання:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "* * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox:1.28
            imagePullPolicy: IfNotPresent
            command:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure

Запустіть приклад CronJob за допомогою цієї команди:

kubectl create -f https://k8s.io/examples/application/job/cronjob.yaml

Вивід подібний до такого:

cronjob.batch/hello created

Після створення CronJob отримайте його статус за допомогою цієї команди:

kubectl get cronjob hello

Вивід подібний до такого:

NAME    SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
hello   */1 * * * *   False     0        <none>          10s

Як видно з результатів команди, CronJob ще не запланував і не запустив жодного Job. Відстежуйте створення Job упродовж приблизно однієї хвилини:

kubectl get jobs --watch

Вивід подібний до такого:

NAME               COMPLETIONS   DURATION   AGE
hello-4111706356   0/1                      0s
hello-4111706356   0/1           0s         0s
hello-4111706356   1/1           5s         5s

Тепер ви побачили один запущений Job, запланований CronJob "hello". Ви можете припинити відстеження Job і знову переглянути CronJob, щоб побачити, що він запланував Job:

kubectl get cronjob hello

Вивід подібний до такого:

NAME    SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
hello   */1 * * * *   False     0        50s             75s

Ви маєте побачити, що CronJob hello успішно запланував Job у час, вказаний у LAST SCHEDULE. Наразі активних Jobs 0, тобто Job завершився успішно або з помилкою.

Тепер знайдіть Podʼи, які створив останній запланований Job, і перегляньте стандартний вивід одного з Podʼів.

Примітка:

Назва Job відрізняється від назви Podʼа.
# Замініть "hello-4111706356" на назву Job у вашій системі
pods=$(kubectl get pods --selector=job-name=hello-4111706356 --output=jsonpath={.items[*].metadata.name})

Покажіть лог Podʼа:

kubectl logs $pods

Вивід подібний до такого:

Fri Feb 22 11:02:09 UTC 2019
Hello from the Kubernetes cluster

Видалення CronJob

Коли CronJob більше не потрібен, видаліть його за допомогою kubectl delete cronjob <cronjob name>:

kubectl delete cronjob hello

Видалення CronJob вилучає всі створені ним Jobs і Podʼи та зупиняє створення нових Jobs. Докладніше про вилучення Jobs читайте в розділі збір сміття.

2 - Job із взаємодією між Podʼами

У цьому прикладі ви запустите Job у режимі завершення Indexed, налаштований так, щоб Podʼи, створені Job, могли взаємодіяти між собою за іменами хостів Podʼів, а не за IP-адресами Podʼів.

Podʼам у межах Job може знадобитися взаємодіяти між собою. Робоче навантаження користувача в кожному Podʼі могло б запитувати API-сервер Kubernetes, щоб дізнатися IP-адреси інших Podʼів, але набагато простіше покладатися на вбудоване в Kubernetes розвʼязання DNS.

Jobs у режимі завершення Indexed автоматично задають імена хостів Podʼів у форматі ${jobName}-${completionIndex}. Цей формат дозволяє детерміновано будувати імена хостів Podʼів і забезпечувати взаємодію між Podʼами без потреби створювати клієнтське зʼєднання з панеллю управління Kubernetes для отримання імен хостів або IP-адрес Podʼів через запити API.

Ця конфігурація корисна для сценаріїв, де потрібна мережева взаємодія Podʼів, але ви не хочете залежати від мережевого зʼєднання з API-сервером Kubernetes.

Перш ніж ви розпочнете

Ви вже маєте знати основи використання Job.

Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:

Версія вашого Kubernetes сервера має бути не старішою ніж v1.21.

Для перевірки версії введіть kubectl version.

Примітка:

Якщо ви використовуєте minikube або подібний інструмент, може знадобитися виконати додаткові кроки, щоб забезпечити наявність DNS.

Запуск Job із взаємодією між Podʼами

Щоб увімкнути взаємодію між Podʼами за іменами хостів Podʼів у Job, потрібно зробити таке:

  1. Налаштуйте headless Service із дійсним селектором міток для Podʼів, створених вашим Job. Headless Service має бути в тому самому просторі імен, що й Job. Простий спосіб зробити це — використати селектор job-name: <your-job-name>, оскільки Kubernetes автоматично додає мітку job-name. Ця конфігурація спонукає систему DNS створити записи імен хостів Podʼів, що виконують ваш Job.

  2. Налаштуйте headless Service як сервіс піддомену для Podʼів Job, додавши таке значення до специфікації шаблону Job:

    subdomain: <headless-svc-name>
    

Приклад

Нижче наведено робочий приклад Job з увімкненою взаємодією між Podʼами за іменами хостів Podʼів. Job завершується лише після того, як усі Podʼи успішно пропінгують один одного за іменами хостів.

Примітка:

У скрипті Bash, який виконується в кожному Podʼі у наведеному нижче прикладі, імена хостів Podʼів можуть також мати префікс простору імен, якщо Pod має бути доступний ззовні простору імен.
apiVersion: v1
kind: Service
metadata:
  name: headless-svc
spec:
  clusterIP: None # clusterIP має бути None для створення headless Service
  selector:
    job-name: example-job # має відповідати назві Job
---
apiVersion: batch/v1
kind: Job
metadata:
  name: example-job
spec:
  completions: 3
  parallelism: 3
  completionMode: Indexed
  template:
    spec:
      subdomain: headless-svc # має відповідати назві Service
      restartPolicy: Never
      containers:
      - name: example-workload
        image: bash:latest
        command:
        - bash
        - -c
        - |
          for i in 0 1 2
          do
            gotStatus="-1"
            wantStatus="0"             
            while [ $gotStatus -ne $wantStatus ]
            do                                       
              ping -c 1 example-job-${i}.headless-svc > /dev/null 2>&1
              gotStatus=$?                
              if [ $gotStatus -ne $wantStatus ]; then
                echo "Failed to ping pod example-job-${i}.headless-svc, retrying in 1 second..."
                sleep 1
              fi
            done                                                         
            echo "Successfully pinged pod: example-job-${i}.headless-svc"
          done

Після застосування наведеного вище прикладу Podʼи зможуть звертатися один до одного через мережу за допомогою <pod-hostname>.<headless-service-name>. Ви маєте побачити вивід, подібний до такого:

kubectl logs example-job-0-qws42
Failed to ping pod example-job-0.headless-svc, retrying in 1 second...
Successfully pinged pod: example-job-0.headless-svc
Successfully pinged pod: example-job-1.headless-svc
Successfully pinged pod: example-job-2.headless-svc

Примітка:

Майте на увазі, що формат назви <pod-hostname>.<headless-service-name>, використаний у цьому прикладі, не працюватиме з політикою DNS None або Default. Дивіться Політику DNS Podʼа.