Выбор подходящего ресурса рабочей нагрузки

KubernetesBeginner
Практиковаться сейчас

Введение

При выполнении задач CKAD от вас часто требуется выбрать подходящий ресурс рабочей нагрузки Kubernetes еще до написания манифеста. Pod — это наименьшая единица запуска, Deployment поддерживает доступность реплик долгоживущих приложений, Job выполняет работу до завершения, а CronJob хранит шаблон для периодического запуска заданий.

В этой лабораторной работе вы сравните эти ресурсы на основе их наблюдаемого поведения, а не простого заучивания определений. Вы увидите, что отдельный Pod не восстанавливается после удаления, Deployment воссоздает свой Pod, Job завершается и фиксирует успех, а CronJob хранит расписание для повторяющихся задач.

Подготовка пространства имен для сравнения рабочих нагрузок

На этом этапе вы подготовите чистое пространство имен (namespace) для сравнения ресурсов рабочих нагрузок.

Начните работу в директории /home/labex/project. Вы будете создавать небольшие манифесты в этой директории по мере сравнения поведения ресурсов.

mkdir -p /home/labex/project
cd /home/labex/project

Убедитесь, что API-сервер Kubernetes доступен. Если виртуальная машина только что запустилась и узел еще не готов, подождите несколько секунд и повторите команду.

kubectl get nodes --request-timeout=5s

Ожидаемый вывод:

NAME         STATUS   ROLES           AGE   VERSION
labex-v135   Ready    control-plane   ...   v1.35...

Рабочие нагрузки создают Pod-ы, поэтому дождитесь готовности сетевого Pod-а кластера.

kubectl wait --namespace kube-system --for=condition=Ready pod -l k8s-app=calico-node --timeout=120s

Ожидаемый вывод:

pod/calico-node-... condition met

Создайте пространство имен с именем ckad-prep-workloads:

kubectl create namespace ckad-prep-workloads

Установите это пространство имен в качестве текущего контекста:

kubectl config set-context --current --namespace=ckad-prep-workloads

Проверьте текущее пространство имен:

kubectl config view --minify --output 'jsonpath={..namespace}'; echo

Ожидаемый вывод:

ckad-prep-workloads

Сравнение Pod и Deployment

На этом этапе вы сравните отдельный Pod с Deployment, удалив оба и наблюдая за тем, как Kubernetes отреагирует на это.

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

Создайте манифест для отдельного Pod-а. Контейнер находится в режиме ожидания, чтобы Pod оставался запущенным достаточно долго для наблюдения. Параметр terminationGracePeriodSeconds: 0 позволит ускорить выполнение лабораторной работы при последующем удалении Pod-а.

cat > standalone-pod.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
  name: standalone-task
  labels:
    app: standalone-task
    workload.labex.io/intent: direct-pod
spec:
  terminationGracePeriodSeconds: 0
  containers:
  - name: sleeper
    image: busybox:1.36
    command: ["/bin/sh", "-c", "sleep 3600"]
EOF

Создайте манифест для Deployment. Этот Deployment дает указание Kubernetes поддерживать один работающий Pod managed-worker, а его шаблон Pod-а использует ту же настройку быстрого завершения.

cat > managed-deployment.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
  name: managed-worker
  labels:
    workload.labex.io/intent: long-running
spec:
  replicas: 1
  selector:
    matchLabels:
      app: managed-worker
  template:
    metadata:
      labels:
        app: managed-worker
    spec:
      terminationGracePeriodSeconds: 0
      containers:
      - name: sleeper
        image: busybox:1.36
        command: ["/bin/sh", "-c", "sleep 3600"]
EOF

Примените оба манифеста:

kubectl apply -f standalone-pod.yaml
kubectl apply -f managed-deployment.yaml

Ожидаемый вывод:

pod/standalone-task created
deployment.apps/managed-worker created

Дождитесь готовности обеих рабочих нагрузок:

kubectl wait --for=condition=Ready pod/standalone-task --timeout=120s
kubectl wait --for=condition=Available deployment/managed-worker --timeout=120s

Ожидаемый вывод:

pod/standalone-task condition met
deployment.apps/managed-worker condition met

Получите имя Pod-а, созданного Deployment-ом, а затем удалите отдельный Pod и Pod, принадлежащий Deployment-у:

managed_pod="$(kubectl get pods -l app=managed-worker -o 'jsonpath={.items[0].metadata.name}')"
kubectl delete pod standalone-task "$managed_pod"

Ожидаемый вывод:

pod "standalone-task" deleted
pod "managed-worker-..." deleted

Дождитесь, пока Deployment снова станет доступен:

kubectl wait --for=condition=Available deployment/managed-worker --timeout=120s

Ожидаемый вывод:

deployment.apps/managed-worker condition met

Выведите список Pod-ов. Отдельный Pod должен исчезнуть, в то время как новый Pod managed-worker должен появиться.

kubectl get pods

Ожидаемый вывод включает Pod managed-worker, но не standalone-task:

NAME                              READY   STATUS    RESTARTS   AGE
managed-worker-...                1/1     Running   0          ...

Выбор Job для выполнения задачи

На этом этапе вы выберете Job для работы, которая должна успешно завершиться, а не работать бесконечно.

Deployment хорошо подходит, когда желаемое состояние — «поддерживать приложение запущенным». Job лучше подходит, когда желаемое состояние — «выполнить задачу до завершения». Именно поэтому миграции, пакетная обработка данных и разовые команды обслуживания обычно реализуются через Jobs.

Создайте Job с именем schema-migration:

kubectl create job schema-migration --image=busybox:1.36 -- /bin/sh -c 'echo migration-start; echo migration-complete'

Ожидаемый вывод:

job.batch/schema-migration created

Дождитесь, пока Job перейдет в состояние Complete:

kubectl wait --for=condition=Complete job/schema-migration --timeout=120s

Ожидаемый вывод:

job.batch/schema-migration condition met

Проверьте сводку Job. В поле COMPLETIONS должно быть 1/1, что означает успешное однократное выполнение задачи.

kubectl get job schema-migration

Ожидаемый вывод:

NAME               STATUS     COMPLETIONS   DURATION   AGE
schema-migration   Complete   1/1           ...        ...

Прочитайте логи Job:

kubectl logs job/schema-migration

Ожидаемый вывод:

migration-start
migration-complete

Выбор CronJob для периодических задач

На этом этапе вы выберете CronJob для работы, которая должна выполняться по расписанию.

CronJob — это шаблон для запланированного Job. Это правильный выбор, когда задача должна повторяться, а не просто выполниться один раз. Чтобы сделать эту лабораторную работу детерминированной, вы создадите CronJob в приостановленном состоянии. Это позволит вам изучить расписание и шаблон, не дожидаясь наступления времени запуска.

Создайте cleanup-cronjob.yaml:

cat > cleanup-cronjob.yaml <<'EOF'
apiVersion: batch/v1
kind: CronJob
metadata:
  name: cleanup-schedule
  labels:
    workload.labex.io/intent: recurring-task
spec:
  schedule: "*/5 * * * *"
  suspend: true
  successfulJobsHistoryLimit: 1
  failedJobsHistoryLimit: 1
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          containers:
          - name: cleanup
            image: busybox:1.36
            command:
            - /bin/sh
            - -c
            - 'echo cleanup-ready'
EOF

Примените манифест:

kubectl apply -f cleanup-cronjob.yaml

Ожидаемый вывод:

cronjob.batch/cleanup-schedule created

Проверьте сводку CronJob. Поле SUSPEND имеет значение True, так как в этой лабораторной работе мы используем определение CronJob для изучения выбора ресурса, не дожидаясь запланированных запусков.

kubectl get cronjob cleanup-schedule

Ожидаемый вывод:

NAME               SCHEDULE      TIMEZONE   SUSPEND   ACTIVE   LAST SCHEDULE   AGE
cleanup-schedule   */5 * * * *   <none>     True      0        <none>          ...

Прочитайте расписание и образ из шаблона напрямую из объекта:

kubectl get cronjob cleanup-schedule -o 'jsonpath={.spec.schedule}{" "}{.spec.suspend}{" "}{.spec.jobTemplate.spec.template.spec.containers[0].image}{"\n"}'

Ожидаемый вывод:

*/5 * * * * true busybox:1.36

Выведите список ресурсов рабочих нагрузок, созданных в этой лабораторной работе. Этот обзор связывает тип ресурса с предполагаемым поведением: Deployment для долгоживущей реплики, Job для завершаемой задачи и CronJob для периодических задач.

kubectl get deployment,job,cronjob

Ожидаемый вывод:

NAME                             READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/managed-worker   1/1     1            1           ...

NAME                         STATUS     COMPLETIONS   DURATION   AGE
job.batch/schema-migration   Complete   1/1           ...        ...

NAME                               SCHEDULE      TIMEZONE   SUSPEND   ACTIVE   LAST SCHEDULE   AGE
cronjob.batch/cleanup-schedule     */5 * * * *   <none>     True      0        <none>          ...

Резюме

Вы сравнили ресурсы рабочих нагрузок Kubernetes на основе их поведения. Отдельный Pod не восстановился после удаления, Deployment воссоздал свой Pod для поддержания доступности реплики, Job выполнил задачу до успешного завершения, а CronJob сохранил шаблон для периодического запуска. Эти наблюдения помогут вам выбрать правильный ресурс перед написанием манифеста в стиле CKAD.