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

Модуль 1.1: Поглиблений розбір площини управління

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

Opens in Killercoda in a new tab

Складність: [СЕРЕДНЯ] — потрібне концептуальне розуміння.

Час на проходження: 35–45 хвилин.

Передумови: Модуль 0.1 (працездатний кластер).


Результати навчання

Розділ «Результати навчання»

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

  • Діагностувати збої площини управління, пов’язуючи симптоми з API-сервером, etcd, планувальником, менеджером контролерів, kubelet, kube-proxy або середовищем виконання контейнерів.
  • Простежити запит на створення об’єкта Kubernetes від kubectl через автентифікацію, авторизацію, допуск, збереження, планування, узгодження та виконання на вузлі.
  • Порівняти обов’язки площини управління та робочих вузлів, щоб обрати правильні логи, перевірки стану та шлях відновлення під час збою.
  • Відновити несправний компонент площини управління, що працює як статичний Под, перевіривши маніфести, прочитавши локальні логи вузла та повернувши правильний файл на місце.

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

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

Гіпотетичний сценарій: ви чергуєте на тренувальному кластері незадовго до вікна обслуговування в стилі CKA, і розробники повідомляють, що нові робочі навантаження більше не запускаються. Наявні застосунки все ще відповідають, kubectl get nodes іноді працює, Деплоймент каже, що хоче більше реплік, а кожен новий Под застрягає у стані Pending. Під тиском ці симптоми звучать схоже, але вони вказують на різні частини системи. Якщо API-сервер несправний, майже кожна команда стає ненадійною. Якщо etcd повільний або недоступний, зміни стану зупиняються. Якщо планувальника бракує, Поди можна створити, але вони ніколи не отримають призначення. Якщо менеджер контролерів зупинено, об’єкти вищого рівня можуть бути прийняті, але ніколи не узгоджені.

Площина управління — це та частина Kubernetes, яка вирішує, яким саме має бути кластер, і фіксує ці рішення в довговічному записі. Робочі вузли змушують контейнери працювати, але вони не вирішують, який Деплоймент має володіти певним ReplicaSet, який вузол має отримати конкретний Под чи чи взагалі дозволено запит. Для іспиту CKA і для реальної експлуатаційної роботи ця відмінність має велике значення, бо вона змінює те, де ви шукаєте проблему першочергово. Ви не виправляєте відсутній планувальник, видаляючи Под із kube-system, і ви не налагоджуєте проблему із сертифікатом etcd, вдивляючись у логи контейнерів застосунку.

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

Уявіть собі експлуатацію Kubernetes як завантажену диспетчерську вежу аеропорту. API-сервер — це радіодиспетчерський пульт, куди надходить кожен офіційний запит, etcd — це довговічний журнал операцій, планувальник призначає літакам доступні виходи на посадку, контролери порівнюють заплановані розклади з реальністю, а kubelet’и координують наземну команду на кожній злітно-посадковій смузі. Аналогія недосконала, бо Kubernetes — це програмне забезпечення, а не авіація, але вона допомагає запам’ятати одне ключове правило: площина управління координує та фіксує рішення, тоді як робочі вузли виконують контейнерну роботу.


Карта площини управління та шлях запиту

Розділ «Карта площини управління та шлях запиту»

Перша помилка, якої припускаються новачки, — уявляти площину управління як один великий процес. Kubernetes навмисно розділений на спеціалізовані компоненти, щоб кожна відповідальність могла окремо виходити з ладу, масштабуватися та відновлюватися. API-сервер обробляє вхідні двері та шлях валідації, etcd зберігає збережений стан кластера, планувальник обирає вузли для незапланованих Подів, а менеджер контролерів запускає цикли узгодження, які тримають бажаний і спостережуваний стан у русі назустріч один одному. Компоненти з боку робочого вузла потім втілюють ці рішення в реальність, запускаючи контейнери, звітуючи про стан і програмуючи мережеві правила.

Наведена нижче архітектурна діаграма — це стартова карта. Вона показує кластер у стилі kubeadm, де основні компоненти площини управління зазвичай працюють як статичні Поди на вузлі площини управління, тоді як kubelet, kube-proxy та середовище виконання контейнерів працюють на кожному вузлі. У промислових кластерах із високою доступністю ви можете мати кілька API-серверів, планувальників та менеджерів контролерів, де вибір лідера визначає, який екземпляр планувальника та менеджера контролерів є активним. Базовий патерн зв’язку залишається тим самим: компоненти спілкуються через API-сервер, і лише API-сервер зберігає об’єкти Kubernetes API в etcd.

┌─────────────────────────────────────────────────────────────────────┐
│ CONTROL PLANE │
│ ┌─────────────┐ ┌─────────────┐ ┌──────────────────────────────┐ │
│ │ API Server │ │ etcd │ │ Controller Manager │ │
│ │ (kube-api) │◄─┤ (storage) │ │ ┌────────────────────────┐ │ │
│ │ │ │ │ │ │ Deployment Controller │ │ │
│ └──────┬──────┘ └─────────────┘ │ │ ReplicaSet Controller │ │ │
│ │ │ │ Node Controller │ │ │
│ │ ┌─────────────────────┐ │ │ Job Controller │ │ │
│ │ │ Scheduler │ │ │ ... (40+ controllers) │ │ │
│ │ │ (kube-scheduler) │ │ └────────────────────────┘ │ │
│ │ └─────────────────────┘ └──────────────────────────────┘ │
└─────────┼───────────────────────────────────────────────────────────┘
│ kubelet talks to API server
┌─────────────────────────────────────────────────────────────────────┐
│ WORKER NODES │
│ ┌─────────────────────────────────────────────────────────────────┐│
│ │ Node 1 Node 2 Node 3 ││
│ │ ┌─────────┐ ┌──────────┐ ┌─────────┐ ┌──────────┐ ││
│ │ │ kubelet │ │kube-proxy│ │ kubelet │ │kube-proxy│ ... ││
│ │ └─────────┘ └──────────┘ └─────────┘ └──────────┘ ││
│ │ ┌──────────────────────┐ ┌──────────────────────┐ ││
│ │ │ Container Runtime │ │ Container Runtime │ ││
│ │ │ (containerd) │ │ (containerd) │ ││
│ │ └──────────────────────┘ └──────────────────────┘ ││
│ └─────────────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────────────┘

Розподіл між компонентами площини управління та робочого вузла — це не дрібниця. Він підказує вам, чи запобігає збій новим рішенням, наявним контейнерам, мережі сервісів або всьому доступу до API. Проблема з kubelet локальна для вузла, який не може запустити Поди чи звітувати про них, тоді як проблема з API-сервером може зробити весь кластер недоступним для клієнтів. Зупинений менеджер контролерів може залишити наявні Поди в спокої, але завадити узгодженню Деплойментів, Job’ів, Нод та Endpoint’ів. Проблема з планувальником зазвичай проявляється як Поди, що існують в API, але ніколи не отримують nodeName.

КомпонентПрацює наПризначення
kube-apiserverПлощина управлінняШлюз API, увесь зв’язок
etcdПлощина управлінняСховище стану кластера
kube-schedulerПлощина управлінняРішення про розміщення Подів
kube-controller-managerПлощина управлінняЦикли узгодження
kubeletКожен вузолЖиттєвий цикл контейнерів
kube-proxyКожен вузолМережеві правила
Container runtimeКожен вузолВласне запускає контейнери

Коли ви виконуєте команду на кшталт kubectl create deployment nginx --image=nginx --replicas=3, ви не спілкуєтеся з планувальником чи безпосередньо з вузлом. kubectl надсилає HTTP-запит до API-сервера, використовуючи облікові дані з вашого kubeconfig. API-сервер автентифікує користувача, авторизує дію, застосовує логіку допуску, валідує об’єкт і зберігає прийнятий бажаний стан. Лише після того, як об’єкт існує в API, контролери та планувальник можуть на нього зреагувати.

┌─────────────────────────────────────────────────────────────────┐
│ All Roads Lead to API Server │
│ │
│ kubectl ────────┐ │
│ Scheduler ──────┼────► kube-apiserver ◄───► etcd │
│ Controllers ────┤ │
│ kubelet ────────┤ │
│ Dashboard ──────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘

Те, що API-сервер є єдиним компонентом Kubernetes, який безпосередньо зберігає об’єкти API в etcd, — це захисне проєктне рішення. Воно централізує автентифікацію, авторизацію, валідацію, допуск, перетворення версій та поведінку аудиту, замість того щоб дозволяти кожному компоненту записувати сирий стан. Цей дизайн також створює чітке правило усунення несправностей: якщо kubectl не може дістатися до API-сервера, звичайна інтроспекція кластера недоступна, тож вам доведеться перейти на вузол площини управління і скористатися локальними інструментами, як-от journalctl, crictl чи перевіркою статичних маніфестів.

1. kubectl → API Server: "Create this pod please"
2. API Server: Authentication check ✓
3. API Server: Authorization check ✓
4. API Server: Admission controllers run
5. API Server: Validation check ✓
6. API Server → etcd: "Store this pod spec"
7. API Server → kubectl: "Pod created (pending)"

На цьому етапі Под може існувати лише як бажаний стан. Ніщо в наведеній вище послідовності не гарантує, що контейнер уже працює. Планувальнику ще потрібно прив’язати Под до вузла, kubelet на цьому вузлі ще має помітити призначення, а середовищу виконання контейнерів ще треба завантажити образ і створити контейнер. Цей розрив між «прийнято в API» та «працює на вузлі» — саме там живе багато сценаріїв усунення несправностей площини управління.

Зупиніться та передбачте: Якщо API-сервер недоступний, але на робочому вузлі вже працюють справні контейнери, яка діяльність може тривати, а яка зупиняється?

Зупиніться та передбачте: якщо API-сервер недоступний, але на робочому вузлі вже працюють справні контейнери, яка діяльність може тривати, а яка зупиняється? Наявні контейнери можуть продовжувати працювати, бо kubelet і середовище виконання вже мають локальну роботу, але нові рішення API, оновлення стану, планування та узгодження контролерами заблоковані або затримані. Це передбачення дає вам швидкий спосіб відрізнити «процес застосунку помер» від «цикли управління кластера не можуть просунутися».

Kubernetes 1.35+ досі дотримується цього розподілу обов’язків. Прапорці компонентів, точки стану та точні деталі маніфестів змінюються від релізу до релізу, але модель залишається досить стабільною для діагностичних міркувань. У кластері kubeadm у стилі CKA компоненти площини управління зазвичай визначаються як файли в каталозі /etc/kubernetes/manifests/. Kubelet стежить за цим каталогом і підтримує відповідні статичні Поди живими, ось чому відновлення файлу часто важливіше за kubectl delete pod під час ремонту площини управління.


API-сервер та etcd: вхідні двері та джерело істини

Розділ «API-сервер та etcd: вхідні двері та джерело істини»

API-сервер — це водночас шлюз і точка примусового застосування політик. Він отримує запити від людей, контролерів, планувальників, kubelet’ів, дашбордів, операторів та автоматизації. Він не запускає контейнери застосунків, але вирішує, чи прийнято об’єкт до запису кластера. Якщо ви досліджуєте симптом, що зачіпає всіх клієнтів, як-от масові тайм-аути kubectl, збої допуску чи помилки TLS, API-сервер зазвичай є першим компонентом площини управління для перевірки.

Terminal window
# Is the API server responding?
kubectl cluster-info
# Check API server component status (legacy)
kubectl get componentstatuses # Deprecated, may not work on all clusters
# Modern health endpoints (preferred)
kubectl get --raw='/readyz?verbose'
kubectl get --raw='/livez?verbose'
# Direct health endpoint
kubectl get --raw='/healthz'
# Detailed health
kubectl get --raw='/healthz?verbose'

Точки livez та readyz корисніші за стару команду стану компонентів, бо вони відкривають перевірки стану API-сервера через підтримувану модель точок доступу. Liveness (живучість) каже вам, чи слід перезапустити процес, тоді як readiness (готовність) каже, чи готовий він обслуговувати звичайний трафік. Збій готовності може бути спричинений залежностями, як-от зв’язком з etcd, post-start хуками або іншими внутрішніми перевірками. Важлива звичка — читати докладний вивід, а не сприймати стан як один зелений чи червоний індикатор.

Логи API-сервера можуть бути доступні через kubectl logs, коли шлях API достатньо справний, щоб прочитати дзеркальний Под. Під час серйозного збою це припущення може бути хибним, тож вам потрібен і локальний шлях. У кластерах kubeadm маніфест статичного Пода записує образ, прапорці команди, сертифікати, точки доступу etcd, конфігурацію допуску та налаштування прив’язки. Невелике редагування цього маніфесту може зламати вхідні двері для всього кластера, тож перевіряйте перед зміною та зберігайте копію під час тренування.

Terminal window
# If running as a static pod (kubeadm setup)
kubectl logs -n kube-system kube-apiserver-<control-plane-node>
# If running as systemd service
journalctl -u kube-apiserver
# Static pod manifest location
cat /etc/kubernetes/manifests/kube-apiserver.yaml

etcd — це довговічна пам’ять за тими вхідними дверима. Kubernetes зберігає об’єкти API під ключами, що відображають тип ресурсу, простір імен та ім’я об’єкта, хоча зазвичай ви взаємодієте через Kubernetes API, а не через сирі читання etcd. Втрата даних etcd — це не те саме, що втрата кешу; це означає втрату запису кластера. Ось чому резервні копії, моніторинг диска, обізнаність про кворум та справність сертифікатів є експлуатаційними темами, а не необов’язковими додатками лише для великих команд.

Key format: /registry/<resource-type>/<namespace>/<name>
Examples:
/registry/pods/default/nginx
/registry/services/kube-system/kube-dns
/registry/secrets/default/my-secret
/registry/deployments/production/web-app

У навчальному кластері з однією площиною управління etcd може бути одним статичним Подом. У промисловому середовищі etcd зазвичай розгортають як невеликий кластер із непарною кількістю членів, бо його модель консенсусу Raft вимагає, щоб більшість членів дійшли згоди. Кластер etcd із трьох членів може витримати збій одного члена; кластер із п’яти членів може витримати два. Додавання членів не просто пришвидшує кожну операцію, бо консенсус усе одно потребує зв’язку, записів на диск та кворуму. Проєктна мета — довговічна згода, а не сира швидкість ключ-значення за будь-яку ціну.

┌─────────────────────────────────────────────────────────────────┐
│ etcd Cluster (Raft Consensus) │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ etcd-1 │◄────►│ etcd-2 │◄────►│ etcd-3 │ │
│ │ (Leader) │ │(Follower)│ │(Follower)│ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │
│ Writes go to leader, replicated to followers │
│ Reads can go to any node │
│ Survives loss of 1 node (quorum = 2/3) │
│ │
└─────────────────────────────────────────────────────────────────┘

Перевірка справності etcd часто потребує локальних сертифікатів, бо API etcd захищено. Наведена нижче команда використовує шляхи до сертифікатів у стилі kubeadm, поширені в екзаменаційних лабораторіях. Якщо вона не спрацює, відрізняйте проблеми транспорту, проблеми сертифікатів, проблеми справності членів та помилки конфігурації команди. Неправильний шлях до сертифіката може виглядати як збій etcd, якщо ви читаєте лише останній рядок помилки.

Terminal window
# etcd member list (if you have etcdctl configured)
ETCDCTL_API=3 etcdctl member list \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
# Check etcd pod
kubectl get pods -n kube-system | grep etcd
kubectl logs -n kube-system etcd-<control-plane-node>

Гіпотетичний сценарій: kubectl get pods -A працює повільно, kubectl apply часто завершується тайм-аутом, а логи API-сервера показують повторювані попередження про затримку сховища. Вам слід запідозрити, що API-сервер очікує на etcd, а не звинувачувати планувальник, бо планування — це лише один пізніший споживач прийнятого стану. У такому разі перевірте справність членів etcd, тиск на диск, термін дії сертифікатів і те, чи не нехтували ущільненням (compaction) або дефрагментацією в кластері, що працює тривалий час. Експлуатаційний урок полягає в тому, що кожен цикл управління залежить від чутливості спільного сховища стану.

Перед запуском: Якого виводу ви очікуєте від kubectl get --raw='/readyz?verbose' на справній площині управління kubeadm?

Перед запуском цього: якого виводу ви очікуєте від kubectl get --raw='/readyz?verbose' на справній площині управління kubeadm? Передбачте форму виводу до того, як його виконаєте: вам слід очікувати названих перевірок із результатами ok, а не просто одного рядка успіху. Якщо перевірка не проходить, скопіюйте точну назву проблемної перевірки до своїх нотаток, бо вона зазвичай вказує точніше за фінальний HTTP-статус.


Планувальник, контролери та агенти вузлів

Розділ «Планувальник, контролери та агенти вузлів»

Після того, як API-сервер приймає об’єкт Под, планувальник стежить за Подами, які ще не мають .spec.nodeName. Його завдання — не запустити Под; його завдання — обрати придатний вузол і прив’язати Под, оновивши API. Спершу планувальник відфільтровує вузли, які не можуть запустити Под, а потім оцінює решту кандидатів. Ця двоетапна модель має значення, бо Под, що застряг у стані Pending, може взагалі не мати придатного вузла, або ж він може мати придатні вузли, але очікувати в черзі за іншою роботою з планування.

┌────────────────────────────────────────────────────────────────┐
│ Scheduling Process │
│ │
│ 1. New pod created (no nodeName) ─────────────────────┐ │
│ │ │
│ 2. Scheduler watches API server ▼ │
│ "Any pods need scheduling?" ◄────────────────── Pod Queue │
│ │
│ 3. Filtering: Which nodes CAN run this pod? │
│ - Enough CPU/memory? │
│ - Taints/tolerations match? │
│ - Node selectors match? │
│ - Affinity rules satisfied? │
│ │
│ 4. Scoring: Which node is BEST? │
│ - Resource balance │
│ - Spreading across zones │
│ - Custom priorities │
│ │
│ 5. Binding: Assign pod to winning node │
│ Scheduler → API Server: "pod X goes to node Y" │
│ │
└────────────────────────────────────────────────────────────────┘

Фільтрування стосується жорстких обмежень. Якщо Под запитує більше CPU, ніж може запропонувати будь-який вузол, потребує мітки, якої не має жоден вузол, не має толерантності до taint’у або залежить від заявки на сховище, що не прив’язана, планувальник не може вигадати гарну відповідь хитрістю. Оцінювання — це інше: воно обирає серед вузлів, що пройшли жорсткі тести, часто віддаючи перевагу кращому балансу ресурсів, топологічному рознесенню або іншим налаштованим пріоритетам. На практиці розділ Events у виводі kubectl describe pod — ваша найкраща перша підказка, бо він фіксує, чому жоден вузол не було прийнято.

Terminal window
# Pod stuck in Pending
kubectl describe pod <pod-name>
# Look for Events section:
# "0/3 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/control-plane: },
# 2 node(s) didn't match Pod's node affinity/selector"

Зупиніться та передбачте: Под запитує 4 ядра CPU та 8Gi пам’яті, але жоден окремий вузол наразі не має стільки доступної виділюваної ємності. Под має залишитися в стані Pending, а kubectl describe pod має показати події планування, що згадують недостатні ресурси чи відсутність доступних вузлів, які відповідають запиту. Це передбачення корисне, бо воно утримує вас від перезапуску планувальника, коли планувальник насправді робить правильну річ.

Terminal window
# Scheduler pod
kubectl get pods -n kube-system | grep scheduler
kubectl logs -n kube-system kube-scheduler-<control-plane-node>
# Scheduler leader election (in HA setups)
kubectl get endpoints kube-scheduler -n kube-system -o yaml

Контролери розв’язують іншу задачу. Контролер — це цикл узгодження: він стежить за бажаним станом і спостережуваним станом, порівнює їх та вживає заходів, коли вони розходяться. Kube-controller-manager — це єдиний бінарний файл, який запускає багато вбудованих контролерів, зокрема контролери Deployment, ReplicaSet, Node, Job, Endpoint, ServiceAccount та Namespace. Цей дизайн потужний, бо кожен контролер може зосередитися на одному виді збіжності, замість того щоб розміщувати всю поведінку кластера всередині API-сервера.

┌────────────────────────────────────────────────────────────────┐
│ Controller Loop Pattern │
│ │
│ ┌─────────────────┐ │
│ │ Desired State │ │
│ │ (in etcd) │ │
│ └────────┬────────┘ │
│ │ │
│ Compare │ │
│ ▼ │
│ Is current state = desired state? │
│ │ │
│ ┌──────────────┴──────────────┐ │
│ │ YES NO │ │
│ ▼ ▼ │
│ Do nothing Take action │
│ (wait & watch) (create/delete/update) │
│ │
└────────────────────────────────────────────────────────────────┘
КонтролерСтежить заРобить
DeploymentДеплойментамиСтворює/оновлює ReplicaSet’и
ReplicaSetReplicaSet’амиЗабезпечує правильну кількість Подів
NodeНодамиМоніторить справність вузла, виселяє Поди з мертвих вузлів
JobJob’амиСтворює Поди, відстежує завершення
EndpointСервісами, ПодамиОновлює endpoint’и Сервісу
ServiceAccountПросторами іменСтворює стандартний ServiceAccount
NamespaceПросторами іменОчищає ресурси при видаленні простору імен

Приклад ReplicaSet — найчистіший спосіб зрозуміти узгодження. Ви створюєте бажану кількість реплік, а контролер ReplicaSet помічає, що нуль відповідних Подів існує. Тоді він створює Поди через API-сервер. Якщо Под пізніше зникає, контролер не сумує за конкретним об’єктом; він бачить, що кількість нижча за бажаний стан, і створює інший відповідний Под. Ось чому мітки та селектори є центральними для поведінки Kubernetes.

# You create this:
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx
Controller loop:
1. Watch: "ReplicaSet 'web' wants 3 pods"
2. Check: "How many pods with label 'app=web' exist?"
3. Compare: "0 exist, 3 desired"
4. Act: "Create 3 pods"
5. Repeat forever...
Later:
- Pod dies → Controller sees 2 pods → Creates 1 more
- You scale to 5 → Controller sees 3 pods → Creates 2 more
- You scale to 2 → Controller sees 5 pods → Deletes 3

Що сталося б, якби менеджер контролерів аварійно завершився, поки API-сервер, планувальник та etcd усе ще працюють? Ви все ще можете створити простий Под, бо API-сервер може його прийняти, а планувальник може його призначити, але Деплойменти, ReplicaSet’и, Job’и, Endpoint’и та реакції на життєвий цикл вузла перестають збігатися. Наявні контейнери можуть продовжувати обслуговувати запити, бо kubelet володіє їхнім локальним життєвим циклом, проте наміри Kubernetes вищого рівня замерзають, доки контролери не повернуться і не наздоженуть.

Terminal window
# Controller manager pod
kubectl get pods -n kube-system | grep controller-manager
kubectl logs -n kube-system kube-controller-manager-<control-plane-node>
# Check for specific controller issues in logs
kubectl logs -n kube-system kube-controller-manager-<node> | grep -i "error\|failed"

Агенти вузлів завершують шлях від бажаного стану до запущених контейнерів. Kubelet реєструє вузол, стежить за Подами, призначеними йому, просить середовище виконання контейнерів створити контейнери, звітує про стан та виконує проби справності. Kube-proxy стежить за Сервісами та EndpointSlice’ами, а потім програмує мережеві правила на рівні вузла, щоб віртуальні IP-адреси Сервісів могли дістатися до Подів, що їх обслуговують. Середовище виконання контейнерів, зазвичай containerd у кластерах у стилі kubeadm, виконує власне операції з образами та контейнерами через Container Runtime Interface.

Terminal window
# Check kubelet status
systemctl status kubelet
# kubelet logs
journalctl -u kubelet -f
# kubelet configuration
cat /var/lib/kubelet/config.yaml
Terminal window
# Check kube-proxy
kubectl get pods -n kube-system | grep kube-proxy
kubectl logs -n kube-system kube-proxy-<id>
# See iptables rules kube-proxy created
iptables -t nat -L KUBE-SERVICES
Terminal window
# Check containerd
systemctl status containerd
crictl ps # List running containers
crictl images # List images

Який підхід ви б обрали тут і чому: якщо Поди мають стан Running, але Сервіси не можуть до них дістатися, ви б почали з планувальника чи зі стану мережі вузла? Почніть із перевірок Сервісу, EndpointSlice, kube-proxy та брандмауера чи рівня даних вузла, бо планування вже завершено. Цей вид зіставлення компонента із симптомом — це різниця між швидкою діагностикою та шумним збиранням команд.


Наскрізний розбір розгортання та відновлення

Розділ «Наскрізний розбір розгортання та відновлення»

Наведена нижче команда виглядає просто, але вона змушує кілька незалежних циклів управління співпрацювати. Читайте часову шкалу повільно й помічайте, як кожен крок залежить від того, що попередній стан стає видимим через API. Контролер Deployment не може створити ReplicaSet, доки не існує Деплоймент. Контролер ReplicaSet не може створити Поди, доки не існує ReplicaSet. Планувальник не може прив’язати Поди, доки не існують Поди без nodeName. Kubelet не може запустити контейнери, доки не побачить Поди, призначені його вузлу.

Terminal window
kubectl create deployment nginx --image=nginx --replicas=3
┌─────────────────────────────────────────────────────────────────┐
│ Timeline of Events │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 0ms kubectl → API Server: "Create Deployment nginx" │
│ 5ms API Server → etcd: Store Deployment │
│ │
│ 10ms Deployment Controller sees new Deployment │
│ 15ms Deployment Controller → API: "Create ReplicaSet" │
│ 20ms API Server → etcd: Store ReplicaSet │
│ │
│ 25ms ReplicaSet Controller sees new ReplicaSet │
│ 30ms ReplicaSet Controller → API: "Create Pod 1, 2, 3" │
│ 35ms API Server → etcd: Store 3 Pods (Pending) │
│ │
│ 40ms Scheduler sees 3 unscheduled Pods │
│ 50ms Scheduler → API: "Pod 1→node1, Pod 2→node2, Pod 3→node1" │
│ 55ms API Server → etcd: Update Pods with nodeName │
│ │
│ 60ms kubelet on node1 sees 2 Pods assigned to it │
│ 65ms kubelet on node2 sees 1 Pod assigned to it │
│ 70ms kubelets → containerd: "Start nginx containers" │
│ │
│ 500ms Containers running │
│ 505ms kubelets → API: "Pods are Running" │
│ 510ms API Server → etcd: Update Pod status │
│ │
│ Done! kubectl get pods shows 3/3 Running │
│ │
└─────────────────────────────────────────────────────────────────┘

Ця часова шкала водночас є контрольним списком усунення несправностей. Якщо жоден Деплоймент не з’являється, зосередьтеся на запиті клієнта, API-сервері, допуску, авторизації та шляху запису в etcd. Якщо Деплоймент існує, але жоден ReplicaSet не з’являється, запідозріть контролер Deployment усередині менеджера контролерів. Якщо ReplicaSet’и існують, але жодних Подів не з’являється, запідозріть контролер ReplicaSet або проблеми із селекторами. Якщо Поди існують, але залишаються незапланованими, перевірте стан планувальника та події Пода. Якщо Поди призначено, але контейнери не запускаються, переходьте до kubelet, завантаження образу, середовища виконання та умов вузла.

Статичні Поди додають одне важливе правило відновлення. У кластерах kubeadm API-сервер, планувальник, менеджер контролерів та etcd часто задаються як файли в каталозі /etc/kubernetes/manifests/, а kubelet створює дзеркальні Поди, щоб ви могли бачити їх через API. Видалення дзеркального Пода через kubectl не ремонтує відсутній маніфест, бо kubelet є справжнім менеджером. Якщо файл маніфесту зникає, довговічне виправлення — відновити файл із правильним вмістом та правами, а потім дати kubelet відтворити статичний Под.

Гіпотетичний сценарій: учень випадково переміщує /etc/kubernetes/manifests/kube-scheduler.yaml під час лабораторної, а потім намагається перезапустити планування, видаливши Под планувальника з kube-system. Видимий Под може зникнути, але першопричина залишається, бо kubelet більше не має маніфесту для запуску. Правильний ремонт — відновити kube-scheduler.yaml, спостерігати, як kubelet відтворює статичний Под, а потім перевірити, що Поди в стані Pending отримують призначення на вузли. Це поширений екзаменаційний патерн, бо він перевіряє володіння компонентом, а не запам’ятовування команд.

Те саме міркування стосується локальних логів. Коли API-сервер працює, kubectl logs -n kube-system ... зручний. Коли API-сервер не працює, він за визначенням недоступний, тож локальні інструменти вузла стають обов’язковими. Можливо, вам доведеться перевірити /etc/kubernetes/manifests/kube-apiserver.yaml, прочитати journalctl -u kubelet або скористатися crictl ps та crictl logs, щоб перевірити контейнери статичних Подів. Площина управління не чарівна; це набір процесів, якими kubelet і середовище виконання все ще керують локально.


Читання симптомів площини управління як ланцюга

Розділ «Читання симптомів площини управління як ланцюга»

Надійна діагностика зазвичай починається з пошуку першої зламаної ланки в життєвому циклі об’єкта. Kubernetes показує багато виглядів однієї й тієї самої події, і новачки часто збирають їх усі, не вирішивши, який перехід вони перевіряють. Деплоймент, що існує, доводить, що запит клієнта, автентифікація, авторизація, допуск і перший запис в etcd були успішними. Відсутній ReplicaSet після цього вказує на узгодження Deployment. ReplicaSet без Подів вказує на узгодження ReplicaSet. Поди без призначеного вузла вказують на планування або неможливі обмеження. Призначені Поди, які не запускаються, вказують на kubelet, завантаження образу, середовище виконання, монтування сховища або тиск на вузол.

Цей підхід на основі ланцюга швидший за запам’ятовування назв компонентів, бо він слідує за доказами. Уявіть, що учень каже: «Мій Деплоймент не вдався». Це твердження надто широке для налагодження. Запитайте, який об’єкт існує і який об’єкт мав з’явитися наступним. Якщо об’єкт Deployment відсутній, дослідіть запит до API. Якщо Деплоймент існує і має умови стану, прочитайте ці умови, перш ніж рухатися нижче. Якщо ReplicaSet існує, але має нуль бажаних Подів, перевірте селектори та стан розгортання Deployment. Кожна відповідь звужує набір компонентів без здогадок.

Той самий метод працює у зворотному напрямку, коли наявні робочі навантаження продовжують працювати під час проблем площини управління. Якщо контейнери все ще обслуговують трафік, kubelet і середовище виконання вже зробили достатньо локальної роботи, щоб тримати їх живими. Якщо API-сервер не працює, ці контейнери не вмирають миттєво, бо Kubernetes не є віддаленим супервізором процесів, який має постійно транслювати дозвіл кожному контейнеру. Однак звітування про стан, нове планування, масштабування, розгортання та багато дій самовідновлення будуть порушені. Ця відмінність пояснює, чому часткові збої можуть виглядати спокійно протягом кількох хвилин, перш ніж приховані цикли управління почнуть мати значення.

Є також різниця між «ще не відбувається» та «не може відбутися». Контролери та планувальники стежать за API і працюють асинхронно, тож невелика затримка після створення об’єкта може бути нормальною. Стійка затримка з чіткими подіями — це інше. Якщо події кажуть, що жоден вузол не відповідає правилу affinity, довше очікування не створить відповідного вузла. Якщо логи контролера показують невдалий вибір лідера, очікування може вирішитися після змін оренди, але вам усе одно потрібно зрозуміти, чому лідерство нестабільне. Ваше завдання — відрізнити нормальну зрештою-узгодженість від заблокованої передумови.

Розбір на прикладі: припустимо, ви виконуєте kubectl create deployment api --image=nginx --replicas=3, і команда повертає успіх. За хвилину kubectl get deployment api показує Деплоймент, але kubectl get rs не показує жодного ReplicaSet. Планувальник ще не мав шансу мати значення, бо немає Подів для планування. Kubelet ще не мав шансу мати значення, бо немає призначених Подів. Компонент, відповідальний за створення наступного об’єкта, — це контролер Deployment усередині менеджера контролерів, тож саме туди ви дивитеся далі.

Якщо ReplicaSet існує і три Поди існують, але всі три Поди мають стан Pending, діагностичний власник змінюється. Контролери Deployment та ReplicaSet виконали свою роботу достатньо добре, щоб створити Поди. Тепер перевірте події Пода та логи планувальника. Відповіддю може бути несправний планувальник, але це також може бути коректний планувальник, що відмовляє неможливому запиту. Под, що просить мітку, якої не має жоден вузол, має залишатися в стані Pending, доки мітка не зміниться, специфікація Пода не зміниться чи не приєднається відповідний вузол. Сприймайте планувальник як механізм прийняття рішень, а не як чарівну силу розміщення.

Якщо Поди мають заданий nodeName і залишаються в стані ContainerCreating, планувальник свою справу зробив. Подивіться на події kubelet, стан завантаження образу, приєднання тому, налаштування CNI та логи середовища виконання на призначеному вузлі. Відсутній секрет завантаження образу, зламаний сокет середовища виконання контейнерів або помилка конфігурації CNI можуть усі з’явитися після успішного планування. Площина управління все ще записує стан, але наступний корисний доказ часто локальний для вузла. Саме тут кандидати на CKA втрачають час, якщо продовжують читати логи планувальника після того, як Под уже прив’язано.

Симптоми API-сервера потребують іншої точки входу, бо API-сервер — це ваше звичайне вікно в кластер. Якщо kubectl get --raw='/readyz?verbose' працює, використовуйте його, бо він дає структуровані перевірки готовності. Якщо він не спрацьовує з помилкою «connection refused» чи помилками TLS, переходьте на вузол площини управління і перевіряйте kubelet плюс маніфест API-сервера. Якщо він працює, але повідомляє про збої готовності, пов’язані з etcd, ви маєте докази, що процес API живий, але його залежність-сховище недостатньо справна для звичайного обслуговування. Ця відмінність визначає, чи перевіряти вам прапорці API, сертифікати, мережеву досяжність чи сам etcd.

Симптоми etcd часто широкі, бо кожен збережений перехід стану залежить від сховища. Повільний etcd не завжди означає, що etcd повністю не працює; це може означати затримку диска, зростання бази даних, проблеми ущільнення (compaction), проблеми зі зв’язком між членами або помилки сертифікатів між API-сервером та точкою доступу etcd. Вивід готовності, логи API-сервера та etcdctl endpoint health чи команди членів можуть тріангулювати причину. У промисловому середовищі ви б також перевірили метрики, ємність диска та нещодавнє обслуговування. В екзаменаційній лабораторії ви зосереджуєтеся на шляхах до сертифікатів, точках доступу, справності статичних Подів та очевидних збоях диска чи процесів.

Вибір лідера додає ще один шар у кластерах із високою доступністю. Планувальник та менеджер контролерів можуть запускати кілька Подів, але лише лідер активно виконує роботу. Резервний екземпляр не зламаний лише тому, що він не приймає рішень про планування чи узгодження. Якщо жодного лідера не вдається обрати, кластер може приймати об’єкти, не просуваючись далі. Ось чому перевірка точок доступу вибору лідера чи оренд може бути корисною, коли Поди компонентів мають стан Running, але поведінка все одно заморожена. Running означає, що процес існує; лідерство означає, що процес володіє активною роботою.

Відновлення статичного Пода теж заслуговує на ретельну послідовність дій. Спершу визначте, чи існує маніфест і чи читає його kubelet. Потім перевірте, чи було створено контейнер і чому він завершився. Якщо маніфест відсутній, відновіть його, перш ніж витрачати час на видалення на рівні API. Якщо маніфест існує, але містить поганий прапорець, порівняйте його з відомою-справною резервною копією або іншим вузлом площини управління. Якщо контейнер запускається, але не проходить готовність, прочитайте логи компонента та перевірки залежностей. Кожен крок перевіряє інший шар локального стека статичного Пода.

Коли ви тренуєтеся, записуйте доказ, який дає кожна команда. kubectl get deployment доводить, що API може прочитати об’єкт Deployment, а не те, що контролер справний. kubectl get pods -n kube-system | grep scheduler доводить, що дзеркальний Под планувальника видимий, а не те, що кожен Под можна запланувати. journalctl -u kubelet доводить, що робить локальний kubelet, а не те, що зберіг etcd. Ці відмінності спершу здаються прискіпливими, але саме вони роблять часову шкалу інциденту точною.

Остання звичка — уникати зміни кількох шарів одночасно. Якщо ви відредагуєте статичний маніфест, перезапустите kubelet, виведете вузол з обслуговування і видалите робочі навантаження одним поривом, ви не зможете сказати, яка дія виправила чи погіршила симптом. Зробіть одну вузьку зміну, дочекайтеся очікуваного наступного переходу, а потім продовжуйте. Kubernetes побудований із циклів узгодження, тож гарне усунення несправностей використовує ту саму терплячість: спостерігайте за бажаним станом, спостерігайте за поточним станом, змініть один вхід і перевірте відповідь наступного циклу.

Один корисний спосіб тренувати цю дисципліну — описувати збій термінами дієслів, а не іменників. Замість «планувальник зламаний» кажіть «Под не прив’язано до вузла». Замість «менеджер контролерів зламаний» кажіть «Деплоймент не створив ReplicaSet» або «ReplicaSet не створив Подів». Описи на основі дієслів тримають вас близько до доказів і роблять передавання роботи колегам чіткішим. Інший інженер може перевірити той самий перехід, не успадковуючи ваш недоведений висновок.

Поля стану об’єкта API теж є частиною ланцюга доказів, а не декоративним виводом. Умови, мітки часу, спостережувані покоління, лічильники готовності та події кажуть вам, чи бачив контролер поточний бажаний стан. Наприклад, Деплоймент може мати новіше metadata.generation, ніж status.observedGeneration, що означає, що контролер ще не обробив найновішу специфікацію. Под може мати умову scheduled, умову ready та деталі стану контейнера, кожна з яких належить іншому власнику. Читайте ці поля як хлібні крихти крізь цикли управління.

Будьте обережні із селекторами міток під час діагностики площини управління. Контролер ReplicaSet рахує Поди за селектором, а не за історією, яку ви маєте в голові. Якщо мітка шаблону Пода не збігається із селектором, Kubernetes може відхилити об’єкт, або контролер може проігнорувати Поди, якими, як ви очікували, він володіє. Якщо селектор Сервісу не збігається з готовими Подами, Сервіс може існувати, не маючи корисних endpoint’ів. Ці помилки не є збоями процесів площини управління, але вони виглядають як зламана автоматизація, доки ви не перевірите зв’язок селектора.

Умови вузла дають ще один граничний маркер. Якщо вузол має стан NotReady, планувальник може припинити розміщувати на ньому звичайні Поди, а контролер Node може зрештою зреагувати на пропущені серцебиття. Якщо вузол має стан Ready, але перебуває під тиском пам’яті, диска чи PID, kubelet може відхиляти чи виселяти роботу, навіть якщо площина управління прийняла бажаний стан. У маленькій лабораторії ці деталі можуть здаватися другорядними, проте вони пояснюють, чому «Под існує» — недостатньо. Вузол усе ще має довести, що може безпечно виконати призначення.

Тайм-аути заслуговують на подібну обережність. Тайм-аут із боку клієнта від kubectl може означати локальні мережеві проблеми, перевантаження API-сервера, затримку вебхука допуску, затримку etcd або запит, якому потрібно передати більше даних, ніж очікувалося. Текст повідомлення, зачеплені дієслова та зачеплені ресурси мають значення. Якщо повільне лише створення Пода, порівняйте шляхи допуску, квоти, політики образів та планувальника. Якщо кожна операція list та watch повільна по всьому кластеру, придивіться уважніше до API-сервера та etcd. Ширина тайм-ауту — це доказ.

Для практики CKA перетворюйте кожен широкий інцидент на два артефакти: запідозреного власника та спростовну наступну перевірку. «Запідозрений власник: менеджер контролерів. Наступна перевірка: чи створює новий Деплоймент ReplicaSet і чи показують логи менеджера контролерів помилки узгодження або вибору лідера?» Цей формат змушує вас обрати тест, який міг би довести вашу неправоту. Якщо ReplicaSet з’являється негайно, менеджер контролерів не є поточним блокувальником. Тоді ви переходите до наступного переходу, замість того щоб захищати першу здогадку, і ваші нотатки залишаються корисними для того, хто переглядає шлях пізніше під екзаменаційним тиском чи на командному огляді.


Патерни та антипатерни

Розділ «Патерни та антипатерни»

Гарне усунення несправностей площини управління починається з класифікації симптомів. Запитайте, чи блокує збій доступ до API, збереження стану, планування, узгодження, виконання на вузлі чи мережу сервісів. Це питання звужує пошук, перш ніж ви щось чіпатимете. Воно також запобігає шкідливим виправленням, як-от перезапуску кожного компонента, коли в одного Пода неможливий селектор вузла. Перезапуск може приховати підказки про час і може перетворити частковий збій на ширший, якщо кілька компонентів уже близькі до несправності.

ПатернКоли застосовуватиЧому це працюєАспект масштабування
Починайте зі зламаного переходуРесурс застряг між прийнятим, запланованим, запущеним чи готовимКожен перехід зіставляється з невеликим набором компонентівБудуйте runbook’и навколо переходів, а не навколо випадкових команд
Віддавайте перевагу точкам стану та подіям перед перезапускамиAPI досяжний, але поведінка деградованаПеревірки готовності та події зберігають доказиЗберігайте важливі виводи в нотатках інциденту перед внесенням змін
Сприймайте статичні маніфести як джерело для статичних ПодівПод площини управління постійно зникає чи не може перезапуститисяkubelet узгоджує файли в каталозі /etc/kubernetes/manifests/Робіть резервні копії маніфестів і порівнюйте зі справним вузлом площини управління
Відокремлюйте бажаний стан від стану виконанняДеплоймент, ReplicaSet, Под чи контейнер не збігаютьсяKubernetes просувається через контролери, планувальник, kubelet та середовище виконанняВикористовуйте посилання-власники об’єктів та поля стану, щоб слідувати за ланцюгом

Антипатерни зазвичай походять від сприйняття Kubernetes як однієї коробки. Команда бачить Поди в стані Pending і перезапускає kubelet на кожному вузлі, хоча розділ Events каже, що Поди запитують забагато пам’яті. Інша команда видаляє дзеркальний статичний Под і очікує, що він залишиться видаленим, хоча kubelet негайно відтворює його з маніфесту. Ці дії зрозумілі, бо площа поверхні велика, але вони марнують час, бо ігнорують межі володіння.

АнтипатернЩо йде не такКраща альтернатива
Спершу перезапускати всі компоненти площини управлінняДокази зникають, а збій може поширитисяПрочитайте стан, події та логи, перш ніж обирати один компонент
Використовувати лише kubectl під час збою API-сервераГоловний діагностичний інструмент залежить від зламаного компонентаПід’єднайтеся по SSH до площини управління і використовуйте маніфести, kubelet та логи середовища виконання
Звинувачувати планувальник у кожному Поді в стані PendingПропускаються обмеження ресурсів, taint’и, affinity та сховищаПеревірте події kubectl describe pod, перш ніж чіпати планувальник
Редагувати статичні маніфести без резервної копіїПомилка може тримати основний компонент у циклі аварійних перезапусківСкопіюйте маніфест, зробіть одну зміну і спостерігайте за логами kubelet

Найбезпечніша звичка — назвати власника наступного переходу стану ще до того, як ви щось зміните. API-сервер володіє прийняттям запитів, etcd володіє збереженим станом, контролери володіють узгодженням, планувальник володіє прив’язкою Подів, kubelet володіє локальним для вузла виконанням Подів, kube-proxy володіє багатьма правилами рівня даних Сервісу, а середовище виконання володіє самими контейнерами. Якщо ви не можете чітко назвати власника, зупиніться і поверніться до доказів, перш ніж змінювати систему. Ця маленька, але послідовна дисципліна запобігає більшості помилок, яких новачки припускаються у площині управління.


Рамка прийняття рішень

Розділ «Рамка прийняття рішень»

Використовуйте цю рамку, коли симптом кластера виглядає широким, але точний компонент незрозумілий. Почніть з того, що все ще працює, бо негативний доказ часто корисніший за довгий список команд. Якщо жодна команда kubectl не вдається, переходьте нижче API і перевіряйте вузол площини управління локально. Якщо читання API працюють, але записи повільні чи невдалі, перевірте готовність API-сервера та справність etcd. Якщо об’єкти прийнято, але на них не реагують, слідуйте за ланцюгом бажаного стану через контролери, планувальник та kubelet.

Symptom observed
|
v
Can kubectl reach the API server?
|
+-- No --> Check kube-apiserver static Pod, kubelet logs, certificates,
| bind address, and local runtime status on the control plane.
|
+-- Yes --> Are API reads or writes slow across many resources?
|
+-- Yes --> Check API server readyz/livez and etcd health.
|
+-- No --> Does the object exist but no child object appears?
|
+-- Yes --> Check kube-controller-manager logs.
|
+-- No --> Are Pods created but Pending?
|
+-- Yes --> Check scheduler and Pod Events.
|
+-- No --> Are Pods assigned but not Running?
|
+-- Yes --> Check kubelet and runtime.
|
+-- No --> Check Service, EndpointSlice,
kube-proxy, and application readiness.
СимптомНайімовірніший власникПерша корисна перевіркаЧому ця перевірка йде першою
kubectl не може під’єднатисяAPI-сервер чи локальний для вузла стек статичних Подівjournalctl -u kubelet та маніфест API-сервераkubectl залежить від компонента, який ви перевіряєте
Усі записи повільні чи завершуються тайм-аутомШлях від API-сервера до etcdkubectl get --raw='/readyz?verbose' та справність членів etcdКожен запис має бути збережено, перш ніж зреагують інші цикли
Деплоймент існує, але ReplicaSet не з’являєтьсяМенеджер контролерівЛоги менеджера контролерів та стан вибору лідераУзгодження Deployment створює наступний об’єкт
Поди існують, але не мають nodeNameПланувальник чи обмеження плануванняПодії kubectl describe pod <pod-name>Події розкривають блокувальники ресурсів, taint’ів, affinity та томів
Под призначено, але контейнерів немаєkubelet чи середовище виконанняjournalctl -u kubelet та crictl psЛокальне для вузла виконання починається після планування
Под Running, але трафік Сервісу не проходитьkube-proxy чи endpoint’и СервісуЛоги Сервісу, EndpointSlice, kube-proxy, правила вузлаПланування завершено, тож наступний крок належить мережі

Ця рамка прийняття рішень не замінює документацію чи глибше налагодження. Це запобіжник для перших десяти хвилин інциденту чи екзаменаційного завдання. У ці хвилини мета — не сплутати компонент, що записує бажаний стан, із компонентом, що його виконує. Щойно ви визначите застряглий перехід, докладна документація компонента та логи стають набагато легшими для інтерпретації.


  1. Статичними Подами керує kubelet, а не API-сервер. У кластерах kubeadm основні компоненти площини управління зазвичай живуть як маніфести в каталозі /etc/kubernetes/manifests/, а Поди, показані в kube-system, є дзеркальними об’єктами. Ось чому відновлення видаленого маніфесту ремонтує компонент, тоді як видалення дзеркального Пода — ні.

  2. API-сервер спроєктовано бути бездержавним (stateless). Довговічний стан Kubernetes живе в etcd, тож перезапуск API-сервера не повинен стерти об’єкти. Саме ця бездержавність дозволяє кластерам із високою доступністю запускати кілька екземплярів API-сервера за балансувальником навантаження.

  3. etcd використовує консенсус Raft і потребує кворуму. Кластер etcd із трьох членів витримує одного несправного члена, тоді як кластер із п’яти членів витримує двох. Кластерів із парною кількістю зазвичай уникають, бо вони додають вартість, не покращуючи стійкість до збоїв так, як багато хто очікує.

  4. Планувальники та менеджери контролерів використовують вибір лідера у кластерах із високою доступністю. Кілька екземплярів можуть працювати, але лише активний лідер виконує основну роботу в певний момент. Резервні екземпляри все одно цінні, бо вони можуть перейняти роботу, коли лідер виходить з ладу.


ПомилкаЧому вона трапляєтьсяЯк її виправити
Думати, що kubelet працює в ПодіБільшість інших компонентів Kubernetes видимі як Поди, тож учні припускають, що kubelet тежПеревірте kubelet через systemctl status kubelet та journalctl -u kubelet на вузлі
Ігнорувати справність etcd, коли API повільнийСимптом проявляється в kubectl, тож шлях до сховища легко не помітитиПеревірте готовність API-сервера та справність членів etcd, місце на диску, сертифікати й затримку
Не перевіряти логи компонентівСтан ресурсу показує наслідок, не завжди причинуЧитайте відповідні логи kube-system, коли API працює, та локальні логи вузла, коли ні
Плутати обов’язки площини управління з робочимиKubernetes показує один API, хоча багато компонентів володіють різними переходамиЗіставте застряглий перехід з API-сервером, etcd, менеджером контролерів, планувальником, kubelet, kube-proxy чи середовищем виконання
Забувати, що статичні Поди є файлово-підкріпленимиДзеркальні Поди виглядають нормально у виводі kubectl get podsВідновіть чи відредагуйте маніфест у каталозі /etc/kubernetes/manifests/ і спостерігайте, як kubelet відтворює Под
Перезапускати планувальник через неможливі обмеження ПодаПоди в стані Pending виглядають як збої планувальника, навіть коли планувальник коректнийПеревірте події Пода на недостатні ресурси, taint’и, affinity, селектори та незв’язані PVC
Використовувати застарілий стан компонентів як єдиний сигнал справностіСтарі звички та давніші посібники досі згадують kubectl get componentstatusesВіддавайте перевагу readyz, livez, логам компонентів та прямим перевіркам etcd у кластерах Kubernetes 1.35+

Питання 1: Ваше оповіщення моніторингу каже, що затримка etcd висока, а розробники повідомляють, що команди `kubectl` повільні чи завершуються тайм-аутом. Чому затримка etcd впливає на `kubectl`, і яка інша поведінка кластера деградувала б?

API-сервер — це єдиний компонент Kubernetes, який зберігає об’єкти API в etcd, і кожен звичайний запит kubectl проходить через API-сервер. Коли etcd повільний, API-сервер може блокуватися на читаннях чи записах, тож клієнти стикаються з тайм-аутами, навіть якщо процес API-сервера все ще живий. Рішення прив’язки планувальника, оновлення стану контролерами, звіти про стан kubelet та шляхи допуску, що потребують збереженого стану, можуть усі деградувати. Ключова діагностична підказка в тому, що багато непов’язаних операцій з ресурсами стають повільними одночасно, що вказує на спільний шлях API-до-etcd, а не на один контролер робочого навантаження.

Питання 2: Розробник повідомляє, що новий Деплоймент показує `0/3` готових реплік. Ви виконуєте `kubectl get pods` і бачите три Поди, що застрягли в стані `Pending`, тоді як Под планувальника має стан Running. Які найімовірніші причини і як ви б досліджували?

Планувальник зі станом Running не гарантує, що якийсь вузол придатний для Подів. Почніть з kubectl describe pod <pod-name> і прочитайте розділ Events, бо він зазвичай згадає недостатній CPU чи пам’ять, taint’и без відповідної толерантності, невідповідності селектора вузла, збої affinity або незв’язані PersistentVolumeClaim’и. Потім порівняйте ці повідомлення з мітками вузлів, taint’ами, виділюваними ресурсами та станом сховища. Перезапуск планувальника був би передчасним, якщо тільки події чи логи планувальника не показують, що сам планувальник несправний.

Питання 3: Під час інциденту kube-controller-manager не працює вже 10 хвилин. Наявні Поди все ще обслуговують трафік, але Деплоймент, масштабований з 3 до 5 реплік, ніколи не створює додаткові Поди. Поясніть різницю.

Наявні контейнери продовжують працювати, бо kubelet і середовище виконання контейнерів керують локальним виконанням після того, як Поди вже призначено. Масштабування Деплойменту потребує узгодження контролерами: контролер Deployment оновлює ReplicaSet’и, а контролер ReplicaSet створює чи видаляє Поди, щоб відповідати бажаній кількості реплік. Коли менеджер контролерів не працює, новий бажаний стан може лежати в etcd без контролера, що на нього діє. Щойно менеджер контролерів повернеться, він має помітити невідповідність і створити відсутні Поди.

Питання 4: Колега випадково видалив `/etc/kubernetes/manifests/kube-scheduler.yaml`. Він пробує `kubectl delete pod kube-scheduler -n kube-system`, щоб перезапустити його, але планування залишається зламаним. Що пішло не так, і яке правильне виправлення?

Планувальник у площині управління kubeadm зазвичай є статичним Подом, яким керує kubelet з файлу маніфесту. Под, видимий через kubectl, є дзеркальним Подом, тож його видалення не відтворює відсутній вихідний маніфест. Правильне виправлення — відновити /etc/kubernetes/manifests/kube-scheduler.yaml з резервної копії чи зі справного вузла площини управління, а потім спостерігати, як kubelet відтворює статичний Под. Після того, як планувальник матиме стан Running, перевірте, що Поди в стані Pending отримують призначення на вузли.

Питання 5: `kubectl create pod` завершується успішно, Под отримує `nodeName`, але контейнер ніколи не запускається, і kubelet повідомляє про збої завантаження образу. Який компонент володіє наступним діагностичним кроком і чому?

API-сервер та планувальник уже зробили свою частину, бо Под існує і його призначено на вузол. Наступний власник — це kubelet на обраному вузлі, що працює із середовищем виконання контейнерів, щоб завантажити образ і створити контейнер. Вам слід перевірити kubectl describe pod на події образу, а потім перейти до journalctl -u kubelet та команд середовища виконання, як-от crictl ps чи crictl images, на цьому вузлі. Планувальник не є першим підозрюваним, бо прив’язка вже відбулася.

Питання 6: Сервіс має ClusterIP, Поди, що його обслуговують, мають стан Running та Ready, але трафік до Сервісу не проходить лише з одного вузла. Яку частину архітектури вам слід дослідити першою?

Оскільки Поди мають стан Running та Ready, площина управління вже прийняла, запланувала та узгодила робоче навантаження. Збій Сервісу на одному вузлі вказує на локальну для вузла поведінку рівня даних, особливо правила kube-proxy, правила брандмауера, стан CNI чи поширення EndpointSlice на цьому вузлі. Почніть з перевірки об’єктів Сервісу та EndpointSlice, а потім перевірте логи kube-proxy та правила вузла, як-от ланцюжок KUBE-SERVICES, якщо цей кластер використовує режим iptables. Перезапуск менеджера контролерів не був би першим кроком, бо збій локалізовано на обробці трафіку.

Питання 7: API-сервер не працює, а `kubectl logs -n kube-system kube-apiserver-` не може під'єднатися. Що вам слід робити далі і чому?

Коли API-сервер не працює, kubectl logs залежить від зламаного шляху, тож це неправильний інструмент для наступного кроку. Під’єднайтеся по SSH до вузла площини управління і перевірте локальний стан: journalctl -u kubelet, статичний маніфест за шляхом /etc/kubernetes/manifests/kube-apiserver.yaml та логи середовища виконання через crictl, якщо потрібно. Це працює, бо kubelet і середовище виконання є локальними процесами, які все ще можуть надати докази, навіть коли Kubernetes API недоступний. Мета — з’ясувати, чи статичний Под відсутній, у циклі аварійних перезапусків, неправильно налаштований чи не може дістатися до etcd.


Ця вправа розміщує командні тренування з площини управління в безпечнішій діагностичній послідовності. Виконуйте руйнівні кроки лише в одноразовому тренувальному кластері, як-от пов’язане лабораторне середовище, бо навмисне переміщення статичних маніфестів ламає компоненти площини управління. Якщо ви на спільному кластері, виконуйте лише кроки інспекції лише для читання та обговоріть завдання відновлення, замість того щоб їх виконувати.

Завдання: Дослідіть компоненти площини управління вашого кластера і потренуйтеся зіставляти симптоми з власниками.

Кероване дослідження

Розділ «Кероване дослідження»
  1. Перелічіть усі Поди площини управління:
Terminal window
kubectl get pods -n kube-system
  1. Перевірте справність компонентів:
Terminal window
kubectl get componentstatuses
kubectl get --raw='/healthz?verbose'
  1. Перегляньте конфігурацію API-сервера:
Terminal window
# On control plane node
sudo cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep -A5 "command:"
  1. Перевірте логи планувальника на нещодавню активність:
Terminal window
kubectl logs -n kube-system -l component=kube-scheduler --tail=20
  1. Спостерігайте за менеджером контролерів у дії:
Terminal window
# Terminal 1: Watch controller logs
kubectl logs -n kube-system -l component=kube-controller-manager -f
# Terminal 2: Create and delete a deployment
kubectl create deployment test --image=nginx --replicas=2
# Verify the deployment was created successfully before deleting
kubectl rollout status deployment test
kubectl delete deployment test
  1. Дослідіть etcd, якщо доступно:
Terminal window
# On control plane node with etcdctl
sudo ETCDCTL_API=3 etcdctl get /registry/namespaces/default \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key

Вправа 1: Перегони на ідентифікацію компонентів

Розділ «Вправа 1: Перегони на ідентифікацію компонентів»

Не заглядаючи в нотатки, визначте, який компонент обробляє кожен сценарій. Ціль — дві хвилини, але точність важливіша за швидкість, бо кожен рядок зіставляється з екзаменаційним шляхом усунення несправностей.

СценарійКомпонент
Зберігає весь стан кластера___
Вирішує, який вузол запускає новий Под___
Автентифікує запити kubectl___
Створює Поди, коли змінюється ReplicaSet___
Звітує про стан вузла площині управління___
Підтримує правила iptables для Сервісів___
Розв'язок
  1. etcd
  2. kube-scheduler
  3. kube-apiserver
  4. kube-controller-manager (контролер ReplicaSet)
  5. kubelet
  6. kube-proxy

Вправа 2: Усунення несправності відсутнього планувальника

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

Сценарій вправи: Поди застрягли в стані Pending назавжди, бо маніфест планувальника було переміщено з каталогу маніфестів, за яким стежать. Робіть це лише на одноразовому кластері, де зламати планування прийнятно.

Terminal window
# Setup: Break the scheduler
sudo mv /etc/kubernetes/manifests/kube-scheduler.yaml /tmp/
# Create a test pod
kubectl run drill-pod --image=nginx
# Observe the problem
kubectl get pods # Pending forever
kubectl describe pod drill-pod | grep -A5 Events
# YOUR TASK: Diagnose and fix
# 1. What's missing?
# 2. How do you restore it?
Розв'язок
Terminal window
# Check control plane pods
kubectl get pods -n kube-system | grep scheduler # Nothing!
# Restore scheduler
sudo mv /tmp/kube-scheduler.yaml /etc/kubernetes/manifests/
# Wait for scheduler and verify
kubectl get pods -n kube-system | grep scheduler # Running!
kubectl get pod drill-pod # Now Running
# Cleanup
kubectl delete pod drill-pod

Вправа 3: Усунення несправності непрацюючого менеджера контролерів

Розділ «Вправа 3: Усунення несправності непрацюючого менеджера контролерів»

Сценарій вправи: Деплойменти приймаються API-сервером, але ReplicaSet’и та Поди ніколи не створюються, бо маніфест менеджера контролерів було переміщено.

Terminal window
# Setup
sudo mv /etc/kubernetes/manifests/kube-controller-manager.yaml /tmp/
# Create deployment
kubectl create deployment drill-deploy --image=nginx --replicas=3
# Observe
kubectl get deploy # Shows 0/3 ready
kubectl get rs # No ReplicaSet created!
kubectl get pods # No pods!
# YOUR TASK: Diagnose and fix
Розв'язок
Terminal window
# Check controller manager
kubectl get pods -n kube-system | grep controller # Nothing!
# Restore controller manager
sudo mv /tmp/kube-controller-manager.yaml /etc/kubernetes/manifests/
# Watch pods appear
kubectl get pods -w # 3 pods created
# Cleanup
kubectl delete deployment drill-deploy

Вправа 4: Глибоке занурення у справність API-сервера

Розділ «Вправа 4: Глибоке занурення у справність API-сервера»

Перевірте справність API-сервера кількома методами і порівняйте, що доводить кожен метод. Метод прямого curl корисний з вузла площини управління, тоді як методи kubectl get --raw перевіряють автентифікований шлях API.

Terminal window
# Method 1: Basic connectivity
kubectl cluster-info
# Method 2: Health endpoints
kubectl get --raw='/healthz'
kubectl get --raw='/readyz'
kubectl get --raw='/livez'
# Method 3: Detailed health
kubectl get --raw='/readyz?verbose' | grep -E "^\[|ok|failed"
# Method 4: Direct curl (from control plane)
curl -k https://localhost:6443/healthz
# Method 5: Check API server logs for errors
kubectl logs -n kube-system -l component=kube-apiserver --tail=20 | grep -i error

Вправа 5: Спостереження за циклом узгодження

Розділ «Вправа 5: Спостереження за циклом узгодження»

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

Terminal window
# Terminal 1: Watch controller manager logs
kubectl logs -n kube-system -l component=kube-controller-manager -f | grep -i "replicaset\|deployment"
# Terminal 2: Create, scale, delete deployment
kubectl create deployment watch-me --image=nginx --replicas=2
kubectl rollout status deployment watch-me
kubectl scale deployment watch-me --replicas=5
kubectl rollout status deployment watch-me
kubectl delete deployment watch-me
# Observe logs in Terminal 1 - see the controller react to each change

Вправа 6: Дослідження etcd

Розділ «Вправа 6: Дослідження etcd»

Дослідіть, що зберігає etcd, якщо у вас є etcdctl та локальні сертифікати на вузлі площини управління. Уникайте переліку всіх ключів у промислових кластерах, бо вивід може бути великим і може розкрити чутливі імена об’єктів.

Terminal window
# Set up etcdctl alias
export ETCDCTL_API=3
alias etcdctl='etcdctl --endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key'
# List all keys (be careful in production!)
etcdctl get / --prefix --keys-only | head -50
# Find all pods
etcdctl get /registry/pods --prefix --keys-only
# Get a specific pod's data
etcdctl get /registry/pods/default/<pod-name>

Вправа 7: Виклик — повний перезапуск площини управління

Розділ «Вправа 7: Виклик — повний перезапуск площини управління»

Сценарій вправи: перезапустіть статичні Поди площини управління, перезапустивши kubelet, а потім перевірте, що кластер відновлюється. Це просунуте практичне завдання лише для одноразових кластерів.

Terminal window
# WARNING: Only do this on practice clusters!
# 1. Note current state
kubectl get nodes
kubectl get pods -A | wc -l
# 2. Restart all control plane components
sudo systemctl restart kubelet
# Static pods will restart automatically
# 3. Wait and verify recovery
sleep 30
kubectl get nodes # All Ready?
kubectl get pods -n kube-system # All Running?
# 4. Test workload scheduling
kubectl run recovery-test --image=nginx
kubectl wait --for=condition=Ready pod/recovery-test --timeout=60s
kubectl get pods
kubectl delete pod recovery-test
  • Можу ідентифікувати всі компоненти площини управління та їхні Поди.
  • Можу перевірити живучість і готовність API-сервера через підтримувані точки стану.
  • Можу знайти і прочитати логи компонентів площини управління через kubectl, коли API справний.
  • Можу перейти до локальної інспекції kubelet, маніфестів та середовища виконання, коли API-сервер недоступний.
  • Можу пояснити, що робить кожен компонент під час створення Деплойменту.
  • Можу відновити переміщений маніфест статичного Пода планувальника чи менеджера контролерів у тренувальному кластері.
Terminal window
# Remove test deployment if created
kubectl delete deployment test --ignore-not-found

Модуль 1.2: Інтерфейси розширення (CNI, CSI, CRI) — Як Kubernetes підключає мережу, сховище та середовища виконання контейнерів.