← К программе курса

Модуль 11 / 19

StatefulSet, DaemonSet, Job и CronJob

KUBERNETES

Содержание
01

1. Цели модуля

Вы научитесь выбирать Deployment, StatefulSet, DaemonSet, Job или CronJob, объяснять их гарантии и диагностировать неуспешную batch-задачу.

02

2. Теория: выбор контроллера

Deployment управляет взаимозаменяемыми stateless Pods. StatefulSet даёт стабильные ordinal names, порядок и связь identity со storage. DaemonSet запускает node-local Pod на каждом подходящем Node.

Job выполняет конечную задачу до заданного числа успешных completions. CronJob по расписанию создаёт Jobs, а не Pods напрямую.

03

3. Теория: StatefulSet и DaemonSet

StatefulSet требует headless Service для сетевой identity. Stable identity не делает приложение stateful автоматически: нужны подходящие PVC, replication и backup.

DaemonSet применяют для node agents, CNI/CSI, логов и мониторинга. Количество Pods определяется подходящими Nodes, а не replicas.

04

4. Теория: Job и CronJob

Job управляет retries через backoffLimit, параллелизмом и completions; Indexed mode даёт каждой работе индекс. ttlSecondsAfterFinished очищает завершённые Jobs.

CronJob поддерживает timeZone, concurrencyPolicy и startingDeadlineSeconds. Запуск приблизителен и может быть пропущен или продублирован, поэтому задача должна быть idempotent. TZ/CRON_TZ нельзя писать внутри schedule.

05

5. Методические указания

  • Выбирайте controller по identity и completion semantics
  • Не запускайте долгоживущий server через Job
  • Делайте batch operations idempotent
  • Ограничивайте history и TTL завершённых Jobs
  • Проверяйте headless Service и PVC перед StatefulSet
  • Для CronJob задавайте timeZone и concurrencyPolicy явно
06

6. Лабораторная работа: workload controllers

Сохраните объекты как controllers-lab.yaml.

terminal
apiVersion: v1
kind: Namespace
metadata: {name: lab-controllers}
---
apiVersion: v1
kind: Service
metadata: {name: database, namespace: lab-controllers}
spec:
  clusterIP: None
  selector: {app: database}
  ports: [{name: peer, port: 8080}]
---
apiVersion: apps/v1
kind: StatefulSet
metadata: {name: database, namespace: lab-controllers}
spec:
  serviceName: database
  replicas: 2
  selector:
    matchLabels: {app: database}
  template:
    metadata:
      labels: {app: database}
    spec:
      containers:
        - {name: app, image: "busybox:1.37.0", command: ["sh", "-c", "echo $HOSTNAME; sleep 3600"]}
---
apiVersion: apps/v1
kind: DaemonSet
metadata: {name: node-agent, namespace: lab-controllers}
spec:
  selector:
    matchLabels: {app: node-agent}
  template:
    metadata:
      labels: {app: node-agent}
    spec:
      containers:
        - {name: agent, image: "busybox:1.37.0", command: ["sh", "-c", "sleep 3600"]}
---
apiVersion: batch/v1
kind: Job
metadata: {name: indexed, namespace: lab-controllers}
spec:
  completions: 3
  parallelism: 2
  completionMode: Indexed
  ttlSecondsAfterFinished: 600
  template:
    spec:
      restartPolicy: Never
      containers:
        - {name: task, image: "busybox:1.37.0", command: ["sh", "-c", "echo index=$JOB_COMPLETION_INDEX"]}
---
apiVersion: batch/v1
kind: CronJob
metadata: {name: report, namespace: lab-controllers}
spec:
  schedule: "*/5 * * * *"
  timeZone: Etc/UTC
  concurrencyPolicy: Forbid
  startingDeadlineSeconds: 120
  successfulJobsHistoryLimit: 2
  failedJobsHistoryLimit: 1
  suspend: true
  jobTemplate:
    spec:
      ttlSecondsAfterFinished: 600
      template:
        spec:
          restartPolicy: Never
          containers:
            - {name: report, image: "busybox:1.37.0", command: ["date", "-u"]}
terminal
kubectl apply -f controllers-lab.yaml
kubectl rollout status statefulset/database -n lab-controllers --timeout=120s
kubectl rollout status daemonset/node-agent -n lab-controllers --timeout=120s
kubectl wait job/indexed -n lab-controllers --for=condition=Complete --timeout=120s
kubectl get statefulset,daemonset,job,cronjob,pod -n lab-controllers -o wide
kubectl get pods -n lab-controllers -l app=database
kubectl logs -n lab-controllers -l job-name=indexed --prefix
kubectl create job report-now -n lab-controllers --from=cronjob/report
kubectl wait job/report-now -n lab-controllers --for=condition=Complete --timeout=120s
kubectl logs job/report-now -n lab-controllers

Критерий: StatefulSet создаёт database-0/1, DaemonSet имеет Ready на подходящих Nodes, Indexed Job завершает три индекса, ручной Job из CronJob успешен.

07

7. Диагностика: failed Job

Сохраните failing-job.yaml. Контейнер намеренно завершается с exitCode 42; wait Complete ожидаемо получает timeout.

terminal
apiVersion: batch/v1
kind: Job
metadata: {name: failing, namespace: lab-controllers}
spec:
  backoffLimit: 2
  activeDeadlineSeconds: 60
  template:
    spec:
      restartPolicy: Never
      containers:
        - {name: task, image: "busybox:1.37.0", command: ["sh", "-c", "echo deliberate failure >&2; exit 42"]}
terminal
kubectl apply -f failing-job.yaml
kubectl wait job/failing -n lab-controllers --for=condition=Complete --timeout=45s
kubectl get job,pod -n lab-controllers
kubectl get job failing -n lab-controllers -o jsonpath='{range .status.conditions[*]}{.type}{"="}{.status}{" reason="}{.reason}{"\n"}{end}'
kubectl logs -n lab-controllers -l job-name=failing --prefix
kubectl describe job failing -n lab-controllers
kubectl events -n lab-controllers --for job/failing
kubectl delete namespace lab-controllers

Цепочка: Job Conditions → failed/succeeded counters → Pods и exitCode → logs → Events → backoffLimit/deadline. Не увеличивайте retries, пока причина детерминирована.

08

8. Контроль и шпаргалка

  • Когда StatefulSet лучше Deployment?
  • Почему DaemonSet не имеет replicas?
  • Что означает Indexed completion?
  • Зачем batch-задаче idempotency?
  • Чем suspend CronJob отличается от удаления?

Модуль освоен, если вы обосновываете controller по требованиям и доказываете причину failed Job по status, exitCode и logs.

PDF для работы офлайн

Скачайте оформленную версию модуля для чтения без подключения к сети.

Скачать PDFPDF