Перейти до вмісту

Модуль 5.2: Збої додатків

Hands-On Lab Available
K8s Cluster intermediate 45 min
Launch Lab ↗

Opens in Killercoda in a new tab

Складність: [MEDIUM] — Найпоширеніші сценарії усунення несправностей

Час на виконання: 45–55 хвилин

Передумови: Модуль 5.1 (Методологія усунення несправностей), Модуль 2.1–2.7 (Робочі навантаження)


Що ви зможете робити

Розділ «Що ви зможете робити»

Після цього модуля ви зможете:

  • Діагностувати CrashLoopBackOff, ImagePullBackOff та CreateContainerConfigError систематично
  • Виправити збої застосунків, спричинені неправильними образами, відсутніми ConfigMaps, некоректними пробами та лімітами ресурсів
  • Дебажити збої подів з кількома контейнерами, визначивши, який контейнер збоїть і чому
  • Простежити збій застосунку від симптому (под не запускається) до першопричини (конкретна помилка конфігурації)

Чому цей модуль важливий

Розділ «Чому цей модуль важливий»

Збої додатків — це найпоширеніші проблеми, з якими ви зіткнетесь — і на іспиті, і на продакшні. Під, який не запускається, контейнер, що постійно падає, або Деплоймент, що не розгортається — це щоденні випадки. Опанування усунення збоїв додатків є критичним для будь-якого адміністратора Kubernetes.

Аналогія з рестораною кухнею

Уявіть Під’и як страви, що готуються на кухні. Іноді страва не вдається через поганий рецепт (неправильний образ), іноді відсутні інгредієнти (ConfigMap/Secret), іноді кухарю не вистачає місця (ресурси), а іноді страва просто не виходить (баг додатку). Кожний збій має різні симптоми й різні виправлення.


Після завершення цього модуля ви зможете:

  • Усувати несправності Підів, що не запускаються
  • Діагностувати контейнери у CrashLoopBackOff
  • Виправляти помилки витягування образів
  • Вирішувати проблеми з конфігурацією
  • Обробляти обмеження ресурсів та OOM kill
  • Налагоджувати проблеми з розгортанням Деплойментів

  • CrashLoopBackOff має експоненціальну затримку: вона починається з 10с, потім 20с, 40с, аж до 5 хвилин між спробами перезапуску
  • Init-контейнери запускаються першими: якщо init-контейнери не вдаються, основні контейнери ніколи не запустяться — багато хто забуває їх перевірити
  • ImagePullBackOff vs ErrImagePull: ErrImagePull — це перший збій, ImagePullBackOff — після кількох повторних спроб

Частина 1: Збої запуску Підів

Розділ «Частина 1: Збої запуску Підів»

1.1 Послідовність запуску Підів

Розділ «1.1 Послідовність запуску Підів»

Розуміння того, що відбувається при запуску Підів:

┌──────────────────────────────────────────────────────────────┐
│ ПОСЛІДОВНІСТЬ ЗАПУСКУ ПІДІВ │
│ │
│ 1. Розподіл 2. Підготовка 3. Запуск │
│ ┌──────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Pending │────▶│ Container │───▶│ Init- │ │
│ │ │ │ Creating │ │ контейнери │ │
│ └──────────┘ └──────────────┘ └──────────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ • Вибір вузла • Pull образів • Запуск по черзі │
│ • Перевірка • Монтування • Кожен має │
│ ресурсів томів вийти з кодом 0 │
│ • Taints/affinity • Налашт. мережі • Тільки послідовно│
│ │
│ 4. Робота 5. Готовність │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Основні │─▶│ Readiness │ │
│ │ контейнери │ │ проби пройшли│ │
│ └──────────────┘ └──────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ • Запуск усіх • Під позначений Ready │
│ • Запуск проб • Доданий до Сервісу │
│ │
└──────────────────────────────────────────────────────────────┘

1.2 Pending — Проблеми розподілу

Розділ «1.2 Pending — Проблеми розподілу»

Коли Під застряг у Pending:

Terminal window
# Перевірити чому Під в Pending
k describe pod <pod> | grep -A 10 Events

Типові причини:

ПовідомленняПричинаРішення
0/3 nodes availableНемає відповідних вузлівПеревірте taints, правила affinity
Insufficient cpuНедостатньо CPUЗменшіть requests або додайте потужностей
Insufficient memoryНедостатньо пам’ятіЗменшіть requests або додайте потужностей
node(s) had taint that pod didn't tolerateTaints блокуютьДодайте tolerations або видаліть taints
node(s) didn't match node selectorНеспівпадіння nodeSelectorВиправте мітки або selector
persistentvolumeclaim not foundPVC відсутнійСтворіть PVC
persistentvolumeclaim not boundНемає відповідного PVПеревірте StorageClass, створіть PV

Команди для дослідження:

Terminal window
# Перевірити ресурси вузлів
k describe nodes | grep -A 5 "Allocated resources"
k top nodes
# Перевірити taints вузлів
k get nodes -o custom-columns='NAME:.metadata.name,TAINTS:.spec.taints[*].key'
# Перевірити мітки вузлів (для nodeSelector)
k get nodes --show-labels

1.3 ContainerCreating — Проблеми підготовки

Розділ «1.3 ContainerCreating — Проблеми підготовки»

Коли Під застряг у ContainerCreating:

Terminal window
# Завжди перевіряйте Events першими
k describe pod <pod> | grep -A 15 Events

Типові причини:

ПовідомленняПричинаРішення
pulling image (зависло)Повільний/великий образЗачекайте або використайте менший образ
ImagePullBackOffНеправильне ім’я образуВиправте посилання на образ
ErrImagePullПомилка автентифікації реєструПеревірте imagePullSecrets
MountVolume.SetUp failedПроблема монтування томуПеревірте наявність PVC, ConfigMap, Secret
configmap not foundВідсутній ConfigMapСтворіть ConfigMap
secret not foundВідсутній SecretСтворіть Secret
network not readyПроблеми з CNIПеревірте Під’и CNI

Команди для дослідження:

Terminal window
# Перевірити проблеми pull образів
k get events --field-selector involvedObject.name=<pod>
# Перевірити чи існують ConfigMap/Secret
k get configmap
k get secret
# Перевірити статус PVC
k get pvc
k describe pvc <name>

Частина 2: Усунення несправностей падіння контейнерів

Розділ «Частина 2: Усунення несправностей падіння контейнерів»

2.1 Розуміння CrashLoopBackOff

Розділ «2.1 Розуміння CrashLoopBackOff»
┌──────────────────────────────────────────────────────────────┐
│ ЦИКЛ CRASHLOOPBACKOFF │
│ │
│ Запуск контейнера ──▶ Падіння контейнера ──▶ Очікування ─┐│
│ ▲ ││
│ └───────────────────────────────────────────────────┘│
│ │
│ Час затримки: │
│ 1-ше падіння: чекати 10с │
│ 2-ге падіння: чекати 20с │
│ 3-тє падіння: чекати 40с │
│ 4-те падіння: чекати 80с │
│ 5-те падіння: чекати 160с │
│ 6-те+ падіння: чекати 300с (максимум 5 хв) │
│ │
│ Після 10 хвилин успішної роботи таймер скидається │
└──────────────────────────────────────────────────────────────┘

2.2 Дослідження CrashLoopBackOff

Розділ «2.2 Дослідження CrashLoopBackOff»

Покроковий підхід:

Terminal window
# Крок 1: Перевірити статус Підів та кількість перезапусків
k get pod <pod>
# Дивіться на стовпець RESTARTS
# Крок 2: Перевірити події
k describe pod <pod> | grep -A 10 Events
# Крок 3: Перевірити поточний стан контейнера
k describe pod <pod> | grep -A 10 "State:"
# Крок 4: Перевірити ПОПЕРЕДНІ логи контейнера (критично!)
k logs <pod> --previous
# Крок 5: Перевірити код виходу
k get pod <pod> -o jsonpath='{.status.containerStatuses[0].lastState.terminated.exitCode}'

2.3 Розшифровка кодів виходу

Розділ «2.3 Розшифровка кодів виходу»
Код виходуСигналЗначенняТипова причина
0-УспіхНормальний вихід (не повинен викликати CrashLoop)
1-Помилка додаткуЛогічна помилка, відсутній конфіг
2-Неправильне використання командиПомилка скрипту
126-Команда не виконуванаПроблема з правами
127-Команда не знайденаНеправильний entrypoint/command
128+NСигнал NВбитий сигналомДивіться нижче
137SIGKILL (9)Примусово вбитийOOMKilled, або kill -9
139SIGSEGV (11)Помилка сегментаціїБаг додатку
143SIGTERM (15)Graceful завершенняНормальне завершення

2.4 Дослідження OOMKilled

Розділ «2.4 Дослідження OOMKilled»

Коли код виходу 137 або статус показує OOMKilled:

Terminal window
# Перевірити статус OOMKilled
k describe pod <pod> | grep -i oom
# Перевірити ліміти пам'яті
k get pod <pod> -o jsonpath='{.spec.containers[0].resources.limits.memory}'
# Перевірити фактичне використання пам'яті (якщо Під працює)
k top pod <pod>
# Виправлення: збільшити ліміт пам'яті
k patch deployment <name> -p '{"spec":{"template":{"spec":{"containers":[{"name":"<container>","resources":{"limits":{"memory":"512Mi"}}}]}}}}'

2.5 Типові причини CrashLoopBackOff

Розділ «2.5 Типові причини CrashLoopBackOff»
СимптомДіагнозВиправлення
Код виходу 1Помилка додаткуПеревірте логи, виправте додаток
Код виходу 127Команда не знайденаВиправте command або args у специфікації
Код виходу 137 + OOMKilledПеревищення пам’ятіЗбільште ліміт пам’яті
Код виходу 137 без OOMВбитий зовніПеревірте liveness probe
Контейнер одразу завершуєтьсяНемає foreground-процесуДодайте sleep infinity або виправте команду
Логи: «file not found»Відсутній ConfigMap/SecretПеревірте наявність монтувань
Логи: «permission denied»Контекст безпекиВиправте runAsUser або fsGroup

Частина 3: Помилки витягування образів

Розділ «Частина 3: Помилки витягування образів»

3.1 Типи помилок витягування образів

Розділ «3.1 Типи помилок витягування образів»
┌──────────────────────────────────────────────────────────────┐
│ ПОТІК ПОМИЛОК ВИТЯГУВАННЯ ОБРАЗІВ │
│ │
│ Спроба витягнути ──▶ ErrImagePull ──▶ ImagePullBackOff │
│ │ │ │ │
│ │ │ │ │
│ (Успіх) (Перший збій) (Повторні збої) │
│ │
│ Причини ErrImagePull: │
│ • Образ не існує │
│ • Реєстр недоступний │
│ • Помилка автентифікації │
│ • Ліміт запитів (Docker Hub) │
│ │
└──────────────────────────────────────────────────────────────┘

3.2 Діагностика проблем з витягуванням образів

Розділ «3.2 Діагностика проблем з витягуванням образів»
Terminal window
# Перевірити події для конкретної помилки
k describe pod <pod> | grep -A 5 "Failed to pull"
# Типові повідомлення про помилки:
# "manifest unknown" - Тег образу не існує
# "unauthorized" - Помилка автентифікації реєстру
# "timeout" - Реєстр недоступний
# "toomanyrequests" - Ліміт запитів

3.3 Виправлення проблем з витягуванням образів

Розділ «3.3 Виправлення проблем з витягуванням образів»

Неправильне ім’я/тег образу:

Terminal window
# Перевірити поточний образ
k get pod <pod> -o jsonpath='{.spec.containers[0].image}'
# Виправити за допомогою set image
k set image deployment/<name> <container>=<correct-image>
# Або відредагувати напряму
k edit deployment <name>

Автентифікація реєстру:

Terminal window
# Створити секрет реєстру
k create secret docker-registry regcred \
--docker-server=registry.example.com \
--docker-username=user \
--docker-password=pass \
--docker-email=user@example.com
# Додати до специфікації Підів
k patch serviceaccount default -p '{"imagePullSecrets":[{"name":"regcred"}]}'
# Або додати до конкретного Деплоймента
k patch deployment <name> -p '{"spec":{"template":{"spec":{"imagePullSecrets":[{"name":"regcred"}]}}}}'

Ліміт запитів Docker Hub:

Terminal window
# Варіант 1: Використовувати автентифіковані запити
k create secret docker-registry dockerhub \
--docker-server=https://index.docker.io/v1/ \
--docker-username=<username> \
--docker-password=<token>
# Варіант 2: Використовувати альтернативний реєстр (gcr.io, quay.io)
# nginx:latest -> gcr.io/google-containers/nginx:latest

Частина 4: Проблеми з конфігурацією

Розділ «Частина 4: Проблеми з конфігурацією»

4.1 Відсутній ConfigMap/Secret

Розділ «4.1 Відсутній ConfigMap/Secret»

Симптоми:

  • Під застряг у ContainerCreating
  • Події показують «configmap not found» або «secret not found»

Діагностика:

Terminal window
# Перевірити які ConfigMaps/Secrets потрібні Підові
k get pod <pod> -o yaml | grep -A 5 "configMap\|secret"
# Перевірити їх наявність
k get configmap
k get secret
# Перевірити конкретний
k describe configmap <name>

Виправлення:

Terminal window
# Створити відсутній ConfigMap
k create configmap <name> --from-literal=key=value
# Створити відсутній Secret
k create secret generic <name> --from-literal=password=secret
# Якщо є файл з даними
k create configmap <name> --from-file=config.yaml
k create secret generic <name> --from-file=credentials.json

4.2 Неправильні ключі ConfigMap/Secret

Розділ «4.2 Неправильні ключі ConfigMap/Secret»

Симптоми:

  • Контейнер запускається, але додаток не працює
  • Логи показують «file not found» або «key not found»

Діагностика:

Terminal window
# Перевірити які ключі є в ConfigMap
k get configmap <name> -o yaml
# Перевірити очікувані ключі Підів
k get pod <pod> -o yaml | grep -A 10 configMapKeyRef
# Порівняти очікувані з фактичними

Виправлення:

Terminal window
# Додати відсутній ключ до ConfigMap
k patch configmap <name> -p '{"data":{"missing-key":"value"}}'
# Або перестворити
k create configmap <name> --from-literal=key1=val1 --from-literal=key2=val2 --dry-run=client -o yaml | k apply -f -

4.3 Проблеми зі змінними середовища

Розділ «4.3 Проблеми зі змінними середовища»
Terminal window
# Перевірити змінні середовища в працюючому контейнері
k exec <pod> -- env
# Перевірити що визначено в специфікації
k get pod <pod> -o jsonpath='{.spec.containers[0].env[*]}'
# Типова проблема: ім'я ключа ConfigMap не збігається з ім'ям змінної середовища
# Перевірте за допомогою:
k get pod <pod> -o yaml | grep -A 5 valueFrom

Частина 5: Збої розгортання Деплойментів

Розділ «Частина 5: Збої розгортання Деплойментів»

5.1 Застряглі Деплойменти

Розділ «5.1 Застряглі Деплойменти»

Симптоми:

  • k rollout status deployment/<name> зависає
  • Старий і новий ReplicaSets обидва існують
  • Під’и не досягають стану Ready
Terminal window
# Перевірити статус Деплоймента
k get deployment <name>
k describe deployment <name>
# Перевірити ReplicaSets
k get rs -l app=<name>
# Перевірити Під'и з нового ReplicaSet
k get pods -l app=<name>

5.2 Типові проблеми з розгортанням

Розділ «5.2 Типові проблеми з розгортанням»
┌──────────────────────────────────────────────────────────────┐
│ СТАНИ РОЗГОРТАННЯ ДЕПЛОЙМЕНТА │
│ │
│ Прогресує Застряг │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Новий RS │ │ Новий RS │ │
│ │ масштабується│ │ Під'и падають │ │
│ └──────────────┘ └──────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Старий RS │ │ Старий RS │ │
│ │ зменшується │ │ ще працює │ │
│ └──────────────┘ └──────────────┘ │
│ │
│ Розгортання чекає поки нові Під'и стануть Ready │
│ Якщо Під'и ніколи не Ready — розгортання зависає │
│ │
└──────────────────────────────────────────────────────────────┘

Дослідження:

Terminal window
# Перевірити умови Деплоймента
k describe deployment <name> | grep -A 10 Conditions
# Перевірити Під'и нового ReplicaSet
NEW_RS=$(k get rs -l app=<name> --sort-by='.metadata.creationTimestamp' -o name | tail -1)
k describe $NEW_RS
# Перевірити чому Під'и не Ready
k get pods -l app=<name> | grep -v Running
k describe pod <failing-pod>

Коли нова версія зламана:

Terminal window
# Перевірити історію розгортання
k rollout history deployment/<name>
# Відкотити до попередньої версії
k rollout undo deployment/<name>
# Відкотити до конкретної ревізії
k rollout undo deployment/<name> --to-revision=2
# Перевірити відкат
k rollout status deployment/<name>

5.4 Виправлення застряглих розгортань

Розділ «5.4 Виправлення застряглих розгортань»
Terminal window
# Варіант 1: Виправити проблему і дозволити розгортанню продовжитись
k set image deployment/<name> <container>=<fixed-image>
# Варіант 2: Відкат
k rollout undo deployment/<name>
# Варіант 3: Примусовий перезапуск (видаляє і перестворює Під'и)
k rollout restart deployment/<name>
# Варіант 4: Зменшити масштаб і збільшити (крайній варіант)
k scale deployment/<name> --replicas=0
k scale deployment/<name> --replicas=3

Частина 6: Збої проб Readiness та Liveness

Розділ «Частина 6: Збої проб Readiness та Liveness»

6.1 Огляд типів проб

Розділ «6.1 Огляд типів проб»
┌──────────────────────────────────────────────────────────────┐
│ ТИПИ ПРОБ │
│ │
│ LIVENESS READINESS │
│ Чи контейнер живий? Чи контейнер готовий? │
│ │
│ Дія при збої: Дія при збої: │
│ ПЕРЕЗАПУСТИТИ контейнер ВИДАЛИТИ з Сервісу │
│ │
│ Використовувати для: Використовувати для: │
│ • Виявлення deadlock • Залежностей при запуску │
│ • Зависших процесів • Прогріву кешів │
│ │
│ Неправильний liveness Неправильний readiness │
│ = цикли падінь = немає трафіку │
│ │
└──────────────────────────────────────────────────────────────┘

6.2 Діагностика збоїв проб

Розділ «6.2 Діагностика збоїв проб»
Terminal window
# Перевірити конфігурацію проб
k get pod <pod> -o yaml | grep -A 10 "livenessProbe\|readinessProbe"
# Перевірити збої проб у подіях
k describe pod <pod> | grep -i "unhealthy\|probe"
# Протестувати пробу вручну
k exec <pod> -- wget -qO- http://localhost:8080/health
k exec <pod> -- cat /tmp/healthy

6.3 Типові проблеми з пробами

Розділ «6.3 Типові проблеми з пробами»
ПроблемаСимптомВиправлення
Неправильний портПроба не проходить, контейнер працюєВиправте порт у специфікації проби
Неправильний шляхПомилки 404 у подіяхВиправте httpGet path
Занадто агресивнаКонтейнери постійно перезапускаютьсяЗбільшіть timeoutSeconds, periodSeconds
Відсутній initialDelaySecondsЗбій під час запускуДодайте initialDelaySeconds
Додаток повільно запускаєтьсяCrashLoop при запускуВикористовуйте startupProbe

Виправлення таймінгу проб:

livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30 # Чекати 30с перед першою пробою
periodSeconds: 10 # Проба кожні 10с
timeoutSeconds: 5 # Тайм-аут після 5с
failureThreshold: 3 # Перезапуск після 3 невдач

ПомилкаПроблемаРішення
Не перевіряти --previousНе бачите причину падінняЗавжди перевіряйте попередні логи для CrashLoop
Ігнорування init-контейнерівОсновний контейнер ніколи не запускаєтьсяПеревіряйте логи init-контейнерів теж
Виправлення симптомів, а не причиниПроблема повторюєтьсяДослідіть кореневу причину перед виправленням
Неправильні одиниці ресурсівНесподіваний OOM або тротлінгВикористовуйте правильні одиниці: Mi, Gi, m
Занадто агресивна liveness пробаЗдорові контейнери вбиваютьсяЗбільшіть тайм-аути та поріг збоїв
Забуті imagePullSecretsПриватні образи не витягуютьсяДодайте секрети на рівні ServiceAccount або Підів

Q1: Аналіз коду виходу

Розділ «Q1: Аналіз коду виходу»

Контейнер має код виходу 1 з логами «Error: REDIS_HOST not set». Яке виправлення?

Відповідь

Додатку не вистачає обов’язкової змінної середовища. Виправте, додавши її:

Terminal window
k set env deployment/<name> REDIS_HOST=redis-service

Або перевірте, що ConfigMap/Secret, який повинен її надавати, існує і правильно посилається.

Q2: Послідовність витягування образу

Розділ «Q2: Послідовність витягування образу»

Яка різниця між ErrImagePull та ImagePullBackOff?

Відповідь
  • ErrImagePull: Початковий збій витягування образу (перша спроба)
  • ImagePullBackOff: Стан після кількох невдалих спроб витягування, з експоненціальною затримкою між повторами

ErrImagePull переходить у ImagePullBackOff після першого збою. Під чергується між спробою витягування і очікуванням.

Q3: Діагностика Pending

Розділ «Q3: Діагностика Pending»

Під у Pending з повідомленням «0/3 nodes are available: 3 Insufficient memory». Усі вузли мають 8 ГБ RAM. Що ви перевіряєте?

Відповідь

Перевірте:

  1. Запит пам’яті Підів: k get pod <pod> -o jsonpath='{.spec.containers[0].resources.requests.memory}'
  2. Виділені ресурси на вузлах: k describe nodes | grep -A 5 "Allocated resources"
  3. Запити працюючих Підів: k top nodes

Запити від існуючих Підів плюс запит цього Підів перевищують доступну пам’ять. Або зменшіть запити, або додайте потужностей.

Q4: Максимум CrashLoopBackOff

Розділ «Q4: Максимум CrashLoopBackOff»

Який максимальний час затримки між спробами перезапуску контейнера?

Відповідь

5 хвилин (300 секунд). Затримка подвоюється кожного разу: 10с, 20с, 40с, 80с, 160с, 300с. Вона залишається на 300с, поки контейнер не попрацює успішно 10 хвилин, тоді скидається.

Q5: Збій init-контейнера

Розділ «Q5: Збій init-контейнера»

Основний контейнер ніколи не запускається, але в його логах немає помилок. Де шукати?

Відповідь

Перевірте init-контейнери:

Terminal window
k get pod <pod> -o jsonpath='{.spec.initContainers[*].name}'
k logs <pod> -c <init-container-name>

Init-контейнери запускаються першими і всі повинні завершитись успішно перед запуском основних контейнерів. Якщо init-контейнер не вдається, основний контейнер ніколи не розпочне роботу.

Q6: Рішення про відкат

Розділ «Q6: Рішення про відкат»

Деплоймент застряг посередині розгортання. Старий ReplicaSet має 2 Під’и, новий має 1 Під у CrashLoopBackOff. Яке найшвидше виправлення?

Відповідь
Terminal window
k rollout undo deployment/<name>

Це одразу відкотить до попередньої робочої версії. Потім можна спокійно дослідити збійний образ/конфігурацію.


Практична вправа: Сценарії збоїв додатків

Розділ «Практична вправа: Сценарії збоїв додатків»

Практика діагностики та виправлення різних збоїв додатків.

Terminal window
# Створити namespace
k create ns app-debug-lab

Сценарій 1: CrashLoopBackOff

Розділ «Сценарій 1: CrashLoopBackOff»
Terminal window
cat <<'EOF' | k apply -f -
apiVersion: v1
kind: Pod
metadata:
name: crash-app
namespace: app-debug-lab
spec:
containers:
- name: app
image: busybox:1.36
command: ['sh', '-c', 'echo "Starting..."; exit 1']
EOF

Завдання: Знайдіть чому він падає і який код виходу має.

Рішення
Terminal window
k logs crash-app -n app-debug-lab --previous
k get pod crash-app -n app-debug-lab -o jsonpath='{.status.containerStatuses[0].lastState.terminated.exitCode}'
# Код виходу 1 — команда явно завершується з помилкою

Сценарій 2: Відсутній ConfigMap

Розділ «Сценарій 2: Відсутній ConfigMap»
Terminal window
cat <<'EOF' | k apply -f -
apiVersion: v1
kind: Pod
metadata:
name: config-app
namespace: app-debug-lab
spec:
containers:
- name: app
image: nginx:1.25
volumeMounts:
- name: config
mountPath: /etc/app
volumes:
- name: config
configMap:
name: app-settings
EOF

Завдання: Знайдіть чому він застряг у ContainerCreating та виправте.

Рішення
Terminal window
# Діагностика
k describe pod config-app -n app-debug-lab | grep -A 5 Events
# "configmap "app-settings" not found"
# Виправлення
k create configmap app-settings -n app-debug-lab --from-literal=key=value
# Перевірка
k get pod config-app -n app-debug-lab

Сценарій 3: Неправильний тег образу

Розділ «Сценарій 3: Неправильний тег образу»
Terminal window
cat <<'EOF' | k apply -f -
apiVersion: v1
kind: Pod
metadata:
name: image-app
namespace: app-debug-lab
spec:
containers:
- name: app
image: nginx:v99.99.99
EOF

Завдання: Діагностуйте та виправте збій витягування образу.

Рішення
Terminal window
# Діагностика
k describe pod image-app -n app-debug-lab | grep -A 5 "Failed\|Error"
# "manifest for nginx:v99.99.99 not found"
# Виправлення — видалити та перестворити з правильним образом
k delete pod image-app -n app-debug-lab
k run image-app -n app-debug-lab --image=nginx:1.25

Сценарій 4: Обмеження ресурсів (OOM)

Розділ «Сценарій 4: Обмеження ресурсів (OOM)»
Terminal window
cat <<'EOF' | k apply -f -
apiVersion: v1
kind: Pod
metadata:
name: oom-app
namespace: app-debug-lab
spec:
containers:
- name: app
image: progrium/stress
args: ['--vm', '1', '--vm-bytes', '500M']
resources:
limits:
memory: "100Mi"
EOF

Завдання: Діагностуйте чому контейнер постійно вбивається.

Рішення
Terminal window
# Діагностика
k describe pod oom-app -n app-debug-lab | grep -i oom
k get pod oom-app -n app-debug-lab -o jsonpath='{.status.containerStatuses[0].lastState.terminated.reason}'
# "OOMKilled"
# Контейнер намагається використати 500MB, але має ліміт лише 100Mi
# Виправлення: збільшити ліміт пам'яті або зменшити використання пам'яті додатком
  • Визначили код виходу crash-app як 1
  • Створили відсутній ConfigMap для config-app
  • Виправили неправильний тег образу для image-app
  • Визначили статус OOMKilled для oom-app
Terminal window
k delete ns app-debug-lab

Вправа 1: Швидкий статус Підів (30 с)

Розділ «Вправа 1: Швидкий статус Підів (30 с)»
Terminal window
# Завдання: Показати всі Під'и з кількістю перезапусків > 0
k get pods -A -o custom-columns='NAME:.metadata.name,RESTARTS:.status.containerStatuses[0].restartCount' | awk '$2 > 0'

Вправа 2: Попередні логи (30 с)

Розділ «Вправа 2: Попередні логи (30 с)»
Terminal window
# Завдання: Отримати останні 50 рядків з попереднього екземпляра контейнера
k logs <pod> --previous --tail=50

Вправа 3: Перевірка коду виходу (1 хв)

Розділ «Вправа 3: Перевірка коду виходу (1 хв)»
Terminal window
# Завдання: Отримати код виходу з контейнера, що впав
k get pod <pod> -o jsonpath='{.status.containerStatuses[0].lastState.terminated.exitCode}'
# Або з describe:
k describe pod <pod> | grep "Exit Code"

Вправа 4: Виправлення образу (1 хв)

Розділ «Вправа 4: Виправлення образу (1 хв)»
Terminal window
# Завдання: Оновити образ у Деплойменті
k set image deployment/<name> <container>=<new-image>

Вправа 5: Створення відсутнього ConfigMap (1 хв)

Розділ «Вправа 5: Створення відсутнього ConfigMap (1 хв)»
Terminal window
# Завдання: Створити ConfigMap з літералу
k create configmap <name> --from-literal=key=value
# З файлу
k create configmap <name> --from-file=<filename>

Вправа 6: Налагодження змінних середовища (1 хв)

Розділ «Вправа 6: Налагодження змінних середовища (1 хв)»
Terminal window
# Завдання: Перевірити всі змінні середовища в працюючому контейнері
k exec <pod> -- env | sort

Вправа 7: Відкат Деплоймента (1 хв)

Розділ «Вправа 7: Відкат Деплоймента (1 хв)»
Terminal window
# Завдання: Відкотити до попередньої версії
k rollout undo deployment/<name>
k rollout status deployment/<name>

Вправа 8: Перевірка конфігурації проб (1 хв)

Розділ «Вправа 8: Перевірка конфігурації проб (1 хв)»
Terminal window
# Завдання: Переглянути конфігурацію проб
k get pod <pod> -o yaml | grep -A 15 livenessProbe
k get pod <pod> -o yaml | grep -A 15 readinessProbe

Переходьте до Модуль 5.3: Збої площини управління, щоб навчитися усувати несправності API-сервера, планувальника, controller manager та etcd.