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

Модуль 3 / 19

Pod: будова, життєвий цикл і діагностика

KUBERNETES

Зміст
01

1. Цілі модуля

Після модуля ви зможете пояснити життєвий цикл Pod і контейнерів, відрізнити phase від готовності, застосувати init container та emptyDir, виконати коректне завершення й діагностувати ImagePullBackOff.

  • Pod як одноразова одиниця виконання
  • Pod Conditions і containerStatuses
  • restartPolicy і CrashLoopBackOff
  • graceful termination та evidence-first діагностика
02

2. Теорія: Pod як одиниця виконання

Pod — мінімальна планована одиниця Kubernetes. Усі контейнери Pod призначаються на один Node, спільно використовують network namespace і взаємодіють через localhost. Спільними стають лише явно підключені volumes.

Pod зазвичай створює контролер. Під час заміни новий екземпляр отримує інший UID та IP, тому застосунок не має залежати від локальної ідентичності Pod.

03

3. Теорія: Phase, Conditions і стани контейнера

status.phase показує грубу фазу Pending, Running, Succeeded, Failed або Unknown, але не доводить готовність застосунку. Зіставляйте phase, Pod Conditions і status.containerStatuses.

  • Waiting містить reason, наприклад ImagePullBackOff
  • Running означає запущений процес, але не гарантує Ready
  • Terminated містить exitCode, signal і reason
  • restartCount рахує перезапуски контейнера в тому самому Pod
04

4. Теорія: Init containers і volumes

Init containers виконуються послідовно й мають успішно завершитися до запуску app containers. Вони підходять для підготовки файлів та одноразових перевірок залежностей; нескінченний init container назавжди затримає запуск Pod.

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

05

5. Теорія: перезапуск і завершення

restartPolicy приймає Always, OnFailure або Never. CrashLoopBackOff — експоненційна затримка повторних запусків, а не окрема phase. Перезапуск контейнера зберігає UID Pod; eviction або заміна контролером створює новий Pod.

Під час видалення kubelet запускає preStop, надсилає PID 1 сигнал TERM і чекає terminationGracePeriodSeconds. Після завершення строку процеси зупиняються примусово.

06

6. Методичні вказівки

  • Завжди вказуйте namespace та ім’я контейнера в багатоконтейнерному Pod
  • Спостерігайте phase, Conditions, containerStatuses та Events разом
  • Використовуйте logs --previous лише для попереднього екземпляра перезапущеного контейнера
  • Не вважайте Running еквівалентом Ready
  • Не використовуйте kubectl delete --force як штатний спосіб зупинки
07

7. Лабораторна робота: повний життєвий цикл

Збережіть маніфест як pod-lifecycle.yaml. Init container підготує сторінку в emptyDir, а nginx прочитає її.

terminal
apiVersion: v1
kind: Namespace
metadata: {name: lab-pods}
---
apiVersion: v1
kind: Pod
metadata: {name: lifecycle-demo, namespace: lab-pods}
spec:
  terminationGracePeriodSeconds: 20
  initContainers:
    - name: prepare
      image: busybox:1.37.0
      command: ["sh", "-c", "printf 'ready from init container\n' > /work/index.html"]
      volumeMounts: [{name: content, mountPath: /work}]
  containers:
    - name: web
      image: nginx:1.28-alpine
      lifecycle: {preStop: {exec: {command: ["sh", "-c", "sleep 5"]}}}
      volumeMounts: [{name: content, mountPath: /usr/share/nginx/html, readOnly: true}]
  volumes: [{name: content, emptyDir: {}}
terminal
kubectl apply -f pod-lifecycle.yaml
kubectl wait -n lab-pods --for=condition=Ready pod/lifecycle-demo --timeout=120s
kubectl exec -n lab-pods lifecycle-demo -c web -- wget -qO- http://127.0.0.1
kubectl logs lifecycle-demo -n lab-pods -c prepare
kubectl delete pod lifecycle-demo -n lab-pods --wait=true
terminal
kubectl get pod lifecycle-demo -n lab-pods -w
kubectl get pod lifecycle-demo -n lab-pods -o jsonpath='{.status.phase}{"\n"}'
kubectl get pod lifecycle-demo -n lab-pods -o jsonpath='{range .status.conditions[*]}{.type}{"="}{.status}{"\n"}{end}'
kubectl get pod lifecycle-demo -n lab-pods -o jsonpath='{range .status.containerStatuses[*]}{.name}{" ready="}{.ready}{" restarts="}{.restartCount}{"\n"}{end}'
kubectl describe pod lifecycle-demo -n lab-pods
kubectl events -n lab-pods --for pod/lifecycle-demo

Критерій: init container завершився з exitCode 0, web має ready=true, HTTP повертає ready from init container, а звичайне видалення дотримується grace period.

08

8. Діагностика: ImagePullBackOff

Збережіть маніфест як pod-broken-image.yaml. Неправильний tag навмисно створює ErrImagePull, а потім ImagePullBackOff.

terminal
apiVersion: v1
kind: Pod
metadata: {name: broken-image, namespace: lab-pods}
spec:
  containers: [{name: web, image: "nginx:does-not-exist"}]

Команда wait очікувано завершиться через timeout. Зберіть reason і Warning Events до виправлення image.

terminal
kubectl apply -f pod-broken-image.yaml
kubectl wait -n lab-pods --for=condition=Ready pod/broken-image --timeout=30s
kubectl describe pod broken-image -n lab-pods
kubectl events -n lab-pods --for pod/broken-image --types=Warning
kubectl set image pod/broken-image web=nginx:1.28-alpine -n lab-pods
kubectl wait -n lab-pods --for=condition=Ready pod/broken-image --timeout=120s
kubectl delete namespace lab-pods

Алгоритм: context і namespacePod Conditions → containerStatuses.state.waiting.reason → Events → перевірка image та доступу до registry → мінімальне виправлення.

09

9. Контроль і шпаргалка

  • Чому Running не означає Ready?
  • Що переживає перезапуск контейнера, але не видалення Pod?
  • Чим restart відрізняється від replacement?
  • Коли доступний logs --previous?
  • Чому preStop не замінює обробку SIGTERM?

Модуль засвоєно, якщо ви визначаєте стан кожного контейнера без здогадок, пояснюєте новий UID після заміни та відновлюєте Pod з ImagePullBackOff на підставі evidence.

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

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

Завантажити PDFPDF