← До програми курсу

Модуль 1 / 19

Архітектура, control plane, вузол і reconciliation

KUBERNETES

Зміст
01

1. Цілі та результат модуля

Після модуля ви зможете пояснити шлях запиту від kubectl до працюючого контейнера, розрізняти обов’язки API Server, etcd, scheduler, controllers, kubelet і container runtime, а також довести reconciliation спостереженнями в живому кластері.

  • Kubernetes керує бажаним станом через API та control loops
  • API Server — єдина підтримувана точка входу до стану кластера
  • etcd зберігає узгоджений стан, але не запускає контейнери
  • scheduler обирає вузол, controller створює намір, kubelet реалізує Pod на вузлі
  • одновузловий кластер підходить для Fundamentals, але не є HA
02

2. Теорія: Kubernetes як система керування станом

Користувач не просить Kubernetes виконати довгу послідовність імперативних дій. Він надсилає об’єкт із desired state. Control plane зберігає намір, порівнює його з observed state та повторює спроби зблизити стани. Цей процес називається reconciliation.

Успішна відповідь API означає, що об’єкт прийнято й збережено, а не те, що застосунок уже доступний. Фактичний результат відображають status, conditions, пов’язані об’єкти, Events і користувацька перевірка трафіку. Розрив між spec і status — нормальний тимчасовий стан або діагностичний сигнал.

03

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.

04

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.

05

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 та обчислювальну ємність до відновлення.

06

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 та спричиняє нову спробу, а не втрату наміру.

07

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.

08

8. Лабораторна робота: карта живого кластера

Зафіксуйте client/server versions, поточний context, адресу API, Node та verbose readiness. Потім зіставте Kubernetes Pods із процесами CRI та системними сервісами.

terminal
kubectl version
kubectl config current-context
kubectl config view --minify
kubectl cluster-info
kubectl get nodes -o wide
kubectl get --raw='/readyz?verbose'
terminal
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'
terminal
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.

09

9. Лабораторна робота: спостерігаємо reconciliation

Створіть Deployment із двома replicas і видаліть один керований Pod. Остання команда watch блокує термінал; завершіть її через Ctrl+C після появи нового Pod.

terminal
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

10. Діагностика: новий rollout не запускається

Установіть неіснуючий image tag. Старі replicas залишаться доступними, а новий Pod перейде через ErrImagePull до ImagePullBackOff. Timeout rollout тут очікуваний і збережений через || true, щоб блок можна було виконати послідовно.

terminal
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

11. Контроль, критерії засвоєння та cleanup

  • Чому успішний kubectl apply не доводить готовність застосунку?
  • Як Deployment призводить до появи Pod?
  • Хто обирає Node і хто запускає контейнер?
  • Чому etcd не слід змінювати напряму?
  • Чим static Pod відрізняється від Pod Deployment?
  • Чому видалений керований Pod з’являється знову?
  • Які evidence доводять причину ImagePullBackOff?
  • Яке обмеження одновузлового кластера не виправити replicas?
terminal
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.