Модуль 1 / 19
Архітектура, control plane, вузол і reconciliation
Зміст
1. Цілі та результат модуля
Після модуля ви зможете пояснити шлях запиту від kubectl до працюючого контейнера, розрізняти обов’язки API Server, etcd, scheduler, controllers, kubelet і container runtime, а також довести reconciliation спостереженнями в живому кластері.
- Kubernetes керує бажаним станом через API та control loops
- API Server — єдина підтримувана точка входу до стану кластера
- etcd зберігає узгоджений стан, але не запускає контейнери
- scheduler обирає вузол, controller створює намір, kubelet реалізує Pod на вузлі
- одновузловий кластер підходить для Fundamentals, але не є HA
2. Теорія: Kubernetes як система керування станом
Користувач не просить Kubernetes виконати довгу послідовність імперативних дій. Він надсилає об’єкт із desired state. Control plane зберігає намір, порівнює його з observed state та повторює спроби зблизити стани. Цей процес називається reconciliation.
Успішна відповідь API означає, що об’єкт прийнято й збережено, а не те, що застосунок уже доступний. Фактичний результат відображають status, conditions, пов’язані об’єкти, Events і користувацька перевірка трафіку. Розрив між spec і status — нормальний тимчасовий стан або діагностичний сигнал.
3. Теорія: API Server, ресурси та об’єкти
kube-apiserver виконує authentication, authorization, admission і validation, потім читає або змінює стан. kubectl — один із клієнтів API; тим самим контрактом користуються controllers, operators, CI/CD та інші програми.
Об’єкт має apiVersion, kind, metadata, spec і часто status. Resource — API-представлення, доступне через endpoint; object — конкретний екземпляр. Namespaced і cluster-scoped ресурси мають різну область дії. Версія Kubernetes не дорівнює версії кожного API: стабільність визначає група та версія ресурсу.
Пряма зміна etcd обходить API-інваріанти та не є штатним способом керування кластером. Backup etcd важливий для відновлення, але логіка експлуатації будується навколо Kubernetes API.
4. Теорія: компоненти control plane
- kube-apiserver — API endpoint і центральна точка перевірки запитів
- etcd — консистентне key-value сховище стану control plane
- kube-scheduler — призначає unscheduled Pod придатному Node
- kube-controller-manager — запускає вбудовані control loops
- cloud-controller-manager — інтегрує підтримувані хмарні ресурси й відсутній у bare-metal лабораторії
У kubeadm-кластері API Server, scheduler, controller-manager і локальний etcd запускаються як static Pods. Їхні manifests читає kubelet з /etc/kubernetes/manifests. Вони видимі через Kubernetes API як mirror Pods, але їхній початковий lifecycle належить kubelet, а не Deployment.
5. Теорія: вузол, kubelet, runtime і мережа
kubelet спостерігає призначені цьому Node PodSpecs і через CRI просить containerd створити Pod sandbox та containers. containerd керує lifecycle контейнерів і викликає OCI runtime. CNI plugin налаштовує мережу Pod, а kube-proxy реалізує Service forwarding до обраних backend.
На одному вузлі control plane і workloads поділяють один failure domain. Зняття taint control-plane дозволяє навчальним workload плануватися на цей вузол, але не створює відмовостійкість. Відмова VM одночасно знищить API та обчислювальну ємність до відновлення.
6. Теорія: шлях створення Deployment
- kubectl серіалізує manifest і надсилає запит до API Server
- API Server перевіряє identity, RBAC, admission і schema
- об’єкт Deployment зберігається, Deployment controller створює ReplicaSet
- ReplicaSet controller створює Pod objects
- scheduler записує nodeName для нових Pod
- kubelet отримує призначення й через CRI/CNI запускає sandbox та containers
- readiness визначає готовність Pod приймати трафік
Компоненти не шикуються в один синхронний pipeline. Вони асинхронно спостерігають API й повторюють роботу. Завдяки цьому тимчасова відмова registry, runtime або вузла зазвичай залишає evidence та спричиняє нову спробу, а не втрату наміру.
7. Методичні вказівки
- Перед командами підтверджуйте context, cluster і namespace
- Розділяйте прийняття об’єкта API та готовність застосунку
- Спочатку читайте spec, status, conditions і ownerReferences, потім Events і logs
- Використовуйте kubectl explain для schema поточного API Server
- Не виправляйте відмову видаленням evidence до describe та Events
- Не редагуйте etcd і static Pod manifests без окремої задачі
- Не називайте одновузлову лабораторію production або HA
Команди sudo стосуються host-рівня й виконуються лише на k8s-fundamentals-1. kubectl-команди працюють через kubeconfig користувача k8slab.
8. Лабораторна робота: карта живого кластера
Зафіксуйте client/server versions, поточний context, адресу API, Node та verbose readiness. Потім зіставте Kubernetes Pods із процесами CRI та системними сервісами.
kubectl version
kubectl config current-context
kubectl config view --minify
kubectl cluster-info
kubectl get nodes -o wide
kubectl get --raw='/readyz?verbose'kubectl get pods -n kube-system -o wide
kubectl get pods -n kube-flannel -o wide
sudo systemctl status kubelet --no-pager
sudo systemctl status containerd --no-pager
sudo crictl --runtime-endpoint unix:///run/containerd/containerd.sock ps
sudo ss -lntp | grep -E ':(6443|2379|2380|10250)\b'kubectl api-resources
kubectl api-versions
kubectl explain deployment
kubectl explain deployment.spec
kubectl explain deployment.spec.template.spec.containersКритерій: Node Ready, readyz завершується рядком readyz check passed, усі системні Pods Running, а crictl показує control-plane containers, якими керує containerd.
9. Лабораторна робота: спостерігаємо reconciliation
Створіть Deployment із двома replicas і видаліть один керований Pod. Остання команда watch блокує термінал; завершіть її через Ctrl+C після появи нового Pod.
kubectl create namespace k8s-m01
kubectl -n k8s-m01 create deployment web --image=nginx:1.29-alpine --replicas=2
kubectl -n k8s-m01 rollout status deployment/web --timeout=120s
kubectl -n k8s-m01 get deployment,replicaset,pod -o wide
old_pod=$(kubectl -n k8s-m01 get pods -l app=web -o jsonpath='{.items[0].metadata.name}')
kubectl -n k8s-m01 delete pod "$old_pod" --wait=false
kubectl -n k8s-m01 get pods -l app=web --watchПорівняйте ім’я видаленого та нового Pod. Deployment не відновлює конкретний екземпляр: ReplicaSet controller створює заміну, бо observed replica count став меншим за desired replicas.
10. Діагностика: новий rollout не запускається
Установіть неіснуючий image tag. Старі replicas залишаться доступними, а новий Pod перейде через ErrImagePull до ImagePullBackOff. Timeout rollout тут очікуваний і збережений через || true, щоб блок можна було виконати послідовно.
container=$(kubectl -n k8s-m01 get deployment web -o jsonpath='{.spec.template.spec.containers[0].name}')
kubectl -n k8s-m01 set image deployment/web "$container"=nginx:does-not-exist
kubectl -n k8s-m01 rollout status deployment/web --timeout=20s || true
kubectl -n k8s-m01 get deployment,replicaset,pod
kubectl -n k8s-m01 describe deployment web
kubectl -n k8s-m01 describe pods -l app=web
kubectl -n k8s-m01 get events --sort-by=.metadata.creationTimestamp
kubectl -n k8s-m01 rollout history deployment/web
kubectl -n k8s-m01 rollout undo deployment/web
kubectl -n k8s-m01 rollout status deployment/web --timeout=120s
kubectl -n k8s-m01 get pods -l app=web- Deployment Conditions показують прогрес верхнього рівня
- ReplicaSet відокремлює стару та нову revisions
- Pod status показує waiting reason
- describe та Events містять точну помилку registry
- rollout history пов’язує проблему зі зміною template
- rollback відновлює попередній Pod template
Не видаляйте failed Pod як виправлення: controller створить такий самий з незміненого template. Виправляти треба джерело desired state — Deployment або систему доставки.
11. Контроль, критерії засвоєння та cleanup
- Чому успішний kubectl apply не доводить готовність застосунку?
- Як Deployment призводить до появи Pod?
- Хто обирає Node і хто запускає контейнер?
- Чому etcd не слід змінювати напряму?
- Чим static Pod відрізняється від Pod Deployment?
- Чому видалений керований Pod з’являється знову?
- Які evidence доводять причину ImagePullBackOff?
- Яке обмеження одновузлового кластера не виправити replicas?
kubectl delete namespace k8s-m01 --wait=true
kubectl get namespace k8s-m01 2>&1 || trueМодуль засвоєно, якщо ви відтворюєте шлях kubectl → API → controllers → scheduler → kubelet → CRI/CNI, спостерігаєте reconciliation та виправляєте помилковий rollout через evidence і rollback.