← До програми курсу

Модуль 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 для network identity. Stable identity не робить застосунок stateful автоматично: потрібні PVC, replication та backup.

DaemonSet застосовують для node agents, CNI/CSI, logs і monitoring. Кількість Pods визначають відповідні Nodes, а не replicas.

04

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

Job керує retries через backoffLimit, parallelism та 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
  • Задавайте 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 → 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