← К программе курса

Модуль 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.