Модуль 1.1: Поглиблений розбір площини управління
Складність:
[СЕРЕДНЯ]— потрібне концептуальне розуміння.Час на проходження: 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 run5. 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-сервер зазвичай є першим компонентом площини управління для перевірки.
# 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 endpointkubectl get --raw='/healthz'
# Detailed healthkubectl get --raw='/healthz?verbose'Точки livez та readyz корисніші за стару команду стану компонентів, бо вони відкривають перевірки стану API-сервера через підтримувану модель точок доступу. Liveness (живучість) каже вам, чи слід перезапустити процес, тоді як readiness (готовність) каже, чи готовий він обслуговувати звичайний трафік. Збій готовності може бути спричинений залежностями, як-от зв’язком з etcd, post-start хуками або іншими внутрішніми перевірками. Важлива звичка — читати докладний вивід, а не сприймати стан як один зелений чи червоний індикатор.
Логи API-сервера можуть бути доступні через kubectl logs, коли шлях API достатньо справний, щоб прочитати дзеркальний Под. Під час серйозного збою це припущення може бути хибним, тож вам потрібен і локальний шлях. У кластерах kubeadm маніфест статичного Пода записує образ, прапорці команди, сертифікати, точки доступу etcd, конфігурацію допуску та налаштування прив’язки. Невелике редагування цього маніфесту може зламати вхідні двері для всього кластера, тож перевіряйте перед зміною та зберігайте копію під час тренування.
# If running as a static pod (kubeadm setup)kubectl logs -n kube-system kube-apiserver-<control-plane-node>
# If running as systemd servicejournalctl -u kube-apiserver
# Static pod manifest locationcat /etc/kubernetes/manifests/kube-apiserver.yamletcd — це довговічна пам’ять за тими вхідними дверима. 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, якщо ви читаєте лише останній рядок помилки.
# 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 podkubectl get pods -n kube-system | grep etcdkubectl 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 — ваша найкраща перша підказка, бо він фіксує, чому жоден вузол не було прийнято.
# Pod stuck in Pendingkubectl 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 має показати події планування, що згадують недостатні ресурси чи відсутність доступних вузлів, які відповідають запиту. Це передбачення корисне, бо воно утримує вас від перезапуску планувальника, коли планувальник насправді робить правильну річ.
# Scheduler podkubectl get pods -n kube-system | grep schedulerkubectl 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’и |
| ReplicaSet | ReplicaSet’ами | Забезпечує правильну кількість Подів |
| Node | Нодами | Моніторить справність вузла, виселяє Поди з мертвих вузлів |
| Job | Job’ами | Створює Поди, відстежує завершення |
| Endpoint | Сервісами, Подами | Оновлює endpoint’и Сервісу |
| ServiceAccount | Просторами імен | Створює стандартний ServiceAccount |
| Namespace | Просторами імен | Очищає ресурси при видаленні простору імен |
Приклад ReplicaSet — найчистіший спосіб зрозуміти узгодження. Ви створюєте бажану кількість реплік, а контролер ReplicaSet помічає, що нуль відповідних Подів існує. Тоді він створює Поди через API-сервер. Якщо Под пізніше зникає, контролер не сумує за конкретним об’єктом; він бачить, що кількість нижча за бажаний стан, і створює інший відповідний Под. Ось чому мітки та селектори є центральними для поведінки Kubernetes.
# You create this:apiVersion: apps/v1kind: ReplicaSetmetadata: name: webspec: replicas: 3 selector: matchLabels: app: web template: metadata: labels: app: web spec: containers: - name: nginx image: nginxController 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 вищого рівня замерзають, доки контролери не повернуться і не наздоженуть.
# Controller manager podkubectl get pods -n kube-system | grep controller-managerkubectl logs -n kube-system kube-controller-manager-<control-plane-node>
# Check for specific controller issues in logskubectl logs -n kube-system kube-controller-manager-<node> | grep -i "error\|failed"Агенти вузлів завершують шлях від бажаного стану до запущених контейнерів. Kubelet реєструє вузол, стежить за Подами, призначеними йому, просить середовище виконання контейнерів створити контейнери, звітує про стан та виконує проби справності. Kube-proxy стежить за Сервісами та EndpointSlice’ами, а потім програмує мережеві правила на рівні вузла, щоб віртуальні IP-адреси Сервісів могли дістатися до Подів, що їх обслуговують. Середовище виконання контейнерів, зазвичай containerd у кластерах у стилі kubeadm, виконує власне операції з образами та контейнерами через Container Runtime Interface.
# Check kubelet statussystemctl status kubelet
# kubelet logsjournalctl -u kubelet -f
# kubelet configurationcat /var/lib/kubelet/config.yaml# Check kube-proxykubectl get pods -n kube-system | grep kube-proxykubectl logs -n kube-system kube-proxy-<id>
# See iptables rules kube-proxy creatediptables -t nat -L KUBE-SERVICES# Check containerdsystemctl status containerdcrictl ps # List running containerscrictl images # List imagesЯкий підхід ви б обрали тут і чому: якщо Поди мають стан Running, але Сервіси не можуть до них дістатися, ви б почали з планувальника чи зі стану мережі вузла? Почніть із перевірок Сервісу, EndpointSlice, kube-proxy та брандмауера чи рівня даних вузла, бо планування вже завершено. Цей вид зіставлення компонента із симптомом — це різниця між швидкою діагностикою та шумним збиранням команд.
Наскрізний розбір розгортання та відновлення
Розділ «Наскрізний розбір розгортання та відновлення»Наведена нижче команда виглядає просто, але вона змушує кілька незалежних циклів управління співпрацювати. Читайте часову шкалу повільно й помічайте, як кожен крок залежить від того, що попередній стан стає видимим через API. Контролер Deployment не може створити ReplicaSet, доки не існує Деплоймент. Контролер ReplicaSet не може створити Поди, доки не існує ReplicaSet. Планувальник не може прив’язати Поди, доки не існують Поди без nodeName. Kubelet не може запустити контейнери, доки не побачить Поди, призначені його вузлу.
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 | vCan 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-сервера до etcd | kubectl 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, правила вузла | Планування завершено, тож наступний крок належить мережі |
Ця рамка прийняття рішень не замінює документацію чи глибше налагодження. Це запобіжник для перших десяти хвилин інциденту чи екзаменаційного завдання. У ці хвилини мета — не сплутати компонент, що записує бажаний стан, із компонентом, що його виконує. Щойно ви визначите застряглий перехід, докладна документація компонента та логи стають набагато легшими для інтерпретації.
Чи знали ви?
Розділ «Чи знали ви?»-
Статичними Подами керує kubelet, а не API-сервер. У кластерах kubeadm основні компоненти площини управління зазвичай живуть як маніфести в каталозі
/etc/kubernetes/manifests/, а Поди, показані вkube-system, є дзеркальними об’єктами. Ось чому відновлення видаленого маніфесту ремонтує компонент, тоді як видалення дзеркального Пода — ні. -
API-сервер спроєктовано бути бездержавним (stateless). Довговічний стан Kubernetes живе в etcd, тож перезапуск API-сервера не повинен стерти об’єкти. Саме ця бездержавність дозволяє кластерам із високою доступністю запускати кілька екземплярів API-сервера за балансувальником навантаження.
-
etcd використовує консенсус Raft і потребує кворуму. Кластер etcd із трьох членів витримує одного несправного члена, тоді як кластер із п’яти членів витримує двох. Кластерів із парною кількістю зазвичай уникають, бо вони додають вартість, не покращуючи стійкість до збоїв так, як багато хто очікує.
-
Планувальники та менеджери контролерів використовують вибір лідера у кластерах із високою доступністю. Кілька екземплярів можуть працювати, але лише активний лідер виконує основну роботу в певний момент. Резервні екземпляри все одно цінні, бо вони можуть перейняти роботу, коли лідер виходить з ладу.
Типові помилки
Розділ «Типові помилки»| Помилка | Чому вона трапляється | Як її виправити |
|---|---|---|
| Думати, що 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.
Практична вправа
Розділ «Практична вправа»Ця вправа розміщує командні тренування з площини управління в безпечнішій діагностичній послідовності. Виконуйте руйнівні кроки лише в одноразовому тренувальному кластері, як-от пов’язане лабораторне середовище, бо навмисне переміщення статичних маніфестів ламає компоненти площини управління. Якщо ви на спільному кластері, виконуйте лише кроки інспекції лише для читання та обговоріть завдання відновлення, замість того щоб їх виконувати.
Завдання: Дослідіть компоненти площини управління вашого кластера і потренуйтеся зіставляти симптоми з власниками.
Кероване дослідження
Розділ «Кероване дослідження»- Перелічіть усі Поди площини управління:
kubectl get pods -n kube-system- Перевірте справність компонентів:
kubectl get componentstatuseskubectl get --raw='/healthz?verbose'- Перегляньте конфігурацію API-сервера:
# On control plane nodesudo cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep -A5 "command:"- Перевірте логи планувальника на нещодавню активність:
kubectl logs -n kube-system -l component=kube-scheduler --tail=20- Спостерігайте за менеджером контролерів у дії:
# Terminal 1: Watch controller logskubectl logs -n kube-system -l component=kube-controller-manager -f
# Terminal 2: Create and delete a deploymentkubectl create deployment test --image=nginx --replicas=2
# Verify the deployment was created successfully before deletingkubectl rollout status deployment test
kubectl delete deployment test- Дослідіть etcd, якщо доступно:
# On control plane node with etcdctlsudo 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 для Сервісів | ___ |
Розв'язок
- etcd
- kube-scheduler
- kube-apiserver
- kube-controller-manager (контролер ReplicaSet)
- kubelet
- kube-proxy
Вправа 2: Усунення несправності відсутнього планувальника
Розділ «Вправа 2: Усунення несправності відсутнього планувальника»Сценарій вправи: Поди застрягли в стані Pending назавжди, бо маніфест планувальника було переміщено з каталогу маніфестів, за яким стежать. Робіть це лише на одноразовому кластері, де зламати планування прийнятно.
# Setup: Break the schedulersudo mv /etc/kubernetes/manifests/kube-scheduler.yaml /tmp/
# Create a test podkubectl run drill-pod --image=nginx
# Observe the problemkubectl get pods # Pending foreverkubectl describe pod drill-pod | grep -A5 Events
# YOUR TASK: Diagnose and fix# 1. What's missing?# 2. How do you restore it?Розв'язок
# Check control plane podskubectl get pods -n kube-system | grep scheduler # Nothing!
# Restore schedulersudo mv /tmp/kube-scheduler.yaml /etc/kubernetes/manifests/
# Wait for scheduler and verifykubectl get pods -n kube-system | grep scheduler # Running!kubectl get pod drill-pod # Now Running
# Cleanupkubectl delete pod drill-podВправа 3: Усунення несправності непрацюючого менеджера контролерів
Розділ «Вправа 3: Усунення несправності непрацюючого менеджера контролерів»Сценарій вправи: Деплойменти приймаються API-сервером, але ReplicaSet’и та Поди ніколи не створюються, бо маніфест менеджера контролерів було переміщено.
# Setupsudo mv /etc/kubernetes/manifests/kube-controller-manager.yaml /tmp/
# Create deploymentkubectl create deployment drill-deploy --image=nginx --replicas=3
# Observekubectl get deploy # Shows 0/3 readykubectl get rs # No ReplicaSet created!kubectl get pods # No pods!
# YOUR TASK: Diagnose and fixРозв'язок
# Check controller managerkubectl get pods -n kube-system | grep controller # Nothing!
# Restore controller managersudo mv /tmp/kube-controller-manager.yaml /etc/kubernetes/manifests/
# Watch pods appearkubectl get pods -w # 3 pods created
# Cleanupkubectl delete deployment drill-deployВправа 4: Глибоке занурення у справність API-сервера
Розділ «Вправа 4: Глибоке занурення у справність API-сервера»Перевірте справність API-сервера кількома методами і порівняйте, що доводить кожен метод. Метод прямого curl корисний з вузла площини управління, тоді як методи kubectl get --raw перевіряють автентифікований шлях API.
# Method 1: Basic connectivitykubectl cluster-info
# Method 2: Health endpointskubectl get --raw='/healthz'kubectl get --raw='/readyz'kubectl get --raw='/livez'
# Method 3: Detailed healthkubectl 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 errorskubectl logs -n kube-system -l component=kube-apiserver --tail=20 | grep -i errorВправа 5: Спостереження за циклом узгодження
Розділ «Вправа 5: Спостереження за циклом узгодження»Скористайтеся двома терміналами, щоб побачити, що зміна бажаного стану не запускає контейнери безпосередньо. Спершу реагує менеджер контролерів, а потім об’єкти нижчого рівня та компоненти вузла продовжують ланцюг.
# Terminal 1: Watch controller manager logskubectl logs -n kube-system -l component=kube-controller-manager -f | grep -i "replicaset\|deployment"
# Terminal 2: Create, scale, delete deploymentkubectl create deployment watch-me --image=nginx --replicas=2kubectl rollout status deployment watch-me
kubectl scale deployment watch-me --replicas=5kubectl 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 та локальні сертифікати на вузлі площини управління. Уникайте переліку всіх ключів у промислових кластерах, бо вивід може бути великим і може розкрити чутливі імена об’єктів.
# Set up etcdctl aliasexport ETCDCTL_API=3alias 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 podsetcdctl get /registry/pods --prefix --keys-only
# Get a specific pod's dataetcdctl get /registry/pods/default/<pod-name>Вправа 7: Виклик — повний перезапуск площини управління
Розділ «Вправа 7: Виклик — повний перезапуск площини управління»Сценарій вправи: перезапустіть статичні Поди площини управління, перезапустивши kubelet, а потім перевірте, що кластер відновлюється. Це просунуте практичне завдання лише для одноразових кластерів.
# WARNING: Only do this on practice clusters!
# 1. Note current statekubectl get nodeskubectl get pods -A | wc -l
# 2. Restart all control plane componentssudo systemctl restart kubelet# Static pods will restart automatically
# 3. Wait and verify recoverysleep 30kubectl get nodes # All Ready?kubectl get pods -n kube-system # All Running?
# 4. Test workload schedulingkubectl run recovery-test --image=nginxkubectl wait --for=condition=Ready pod/recovery-test --timeout=60skubectl get podskubectl delete pod recovery-testКритерії успіху
Розділ «Критерії успіху»- Можу ідентифікувати всі компоненти площини управління та їхні Поди.
- Можу перевірити живучість і готовність API-сервера через підтримувані точки стану.
- Можу знайти і прочитати логи компонентів площини управління через
kubectl, коли API справний. - Можу перейти до локальної інспекції kubelet, маніфестів та середовища виконання, коли API-сервер недоступний.
- Можу пояснити, що робить кожен компонент під час створення Деплойменту.
- Можу відновити переміщений маніфест статичного Пода планувальника чи менеджера контролерів у тренувальному кластері.
Очищення
Розділ «Очищення»# Remove test deployment if createdkubectl delete deployment test --ignore-not-foundДжерела
Розділ «Джерела»- https://kubernetes.io/docs/concepts/overview/components/
- https://kubernetes.io/docs/concepts/architecture/control-plane-node-communication/
- https://kubernetes.io/docs/reference/command-line-tools-reference/kube-apiserver/
- https://kubernetes.io/docs/reference/command-line-tools-reference/kube-scheduler/
- https://kubernetes.io/docs/reference/command-line-tools-reference/kube-controller-manager/
- https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/
- https://kubernetes.io/docs/reference/command-line-tools-reference/kube-proxy/
- https://kubernetes.io/docs/reference/using-api/health-checks/
- https://kubernetes.io/docs/tasks/administer-cluster/configure-upgrade-etcd/
- https://kubernetes.io/docs/tasks/debug/debug-cluster/
- https://kubernetes.io/docs/tasks/configure-pod-container/static-pod/
- https://etcd.io/docs/v3.6/op-guide/runtime-configuration/
Наступний модуль
Розділ «Наступний модуль»Модуль 1.2: Інтерфейси розширення (CNI, CSI, CRI) — Як Kubernetes підключає мережу, сховище та середовища виконання контейнерів.