Модуль 3 / 19
Pod: будова, життєвий цикл і діагностика
Зміст
1. Цілі модуля
Після модуля ви зможете пояснити життєвий цикл Pod і контейнерів, відрізнити phase від готовності, застосувати init container та emptyDir, виконати коректне завершення й діагностувати ImagePullBackOff.
- Pod як одноразова одиниця виконання
- Pod Conditions і containerStatuses
- restartPolicy і CrashLoopBackOff
- graceful termination та evidence-first діагностика
2. Теорія: Pod як одиниця виконання
Pod — мінімальна планована одиниця Kubernetes. Усі контейнери Pod призначаються на один Node, спільно використовують network namespace і взаємодіють через localhost. Спільними стають лише явно підключені volumes.
Pod зазвичай створює контролер. Під час заміни новий екземпляр отримує інший UID та IP, тому застосунок не має залежати від локальної ідентичності Pod.
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
4. Теорія: Init containers і volumes
Init containers виконуються послідовно й мають успішно завершитися до запуску app containers. Вони підходять для підготовки файлів та одноразових перевірок залежностей; нескінченний init container назавжди затримає запуск Pod.
emptyDir створюється для Pod і переживає перезапуски контейнерів, але видаляється разом із Pod. Він підходить для тимчасового обміну даними, а не постійного зберігання.
5. Теорія: перезапуск і завершення
restartPolicy приймає Always, OnFailure або Never. CrashLoopBackOff — експоненційна затримка повторних запусків, а не окрема phase. Перезапуск контейнера зберігає UID Pod; eviction або заміна контролером створює новий Pod.
Під час видалення kubelet запускає preStop, надсилає PID 1 сигнал TERM і чекає terminationGracePeriodSeconds. Після завершення строку процеси зупиняються примусово.
6. Методичні вказівки
- Завжди вказуйте namespace та ім’я контейнера в багатоконтейнерному Pod
- Спостерігайте phase, Conditions, containerStatuses та Events разом
- Використовуйте logs --previous лише для попереднього екземпляра перезапущеного контейнера
- Не вважайте Running еквівалентом Ready
- Не використовуйте kubectl delete --force як штатний спосіб зупинки
7. Лабораторна робота: повний життєвий цикл
Збережіть маніфест як pod-lifecycle.yaml. Init container підготує сторінку в emptyDir, а nginx прочитає її.
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: {}}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=truekubectl 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.
8. Діагностика: ImagePullBackOff
Збережіть маніфест як pod-broken-image.yaml. Неправильний tag навмисно створює ErrImagePull, а потім ImagePullBackOff.
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.
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 і namespace → Pod Conditions → containerStatuses.state.waiting.reason → Events → перевірка image та доступу до registry → мінімальне виправлення.
9. Контроль і шпаргалка
- Чому Running не означає Ready?
- Що переживає перезапуск контейнера, але не видалення Pod?
- Чим restart відрізняється від replacement?
- Коли доступний logs --previous?
- Чому preStop не замінює обробку SIGTERM?
Модуль засвоєно, якщо ви визначаєте стан кожного контейнера без здогадок, пояснюєте новий UID після заміни та відновлюєте Pod з ImagePullBackOff на підставі evidence.
PDF для роботи офлайн
Завантажте оформлену версію модуля для читання без підключення до мережі.