Модуль 19. Архитектура Kubernetes изнутри
Kubernetes — это набор серверов-контролёров (control plane), узлов-исполнителей (worker/nodes), единая база фактов (etcd), и клиенты (контроллеры/операторы) с паттерном list-watch → reconcile.
Главная идея: любое желаемое состояние (манифесты Deployment/Service/…) записывается в etcd через kube-apiserver. Остальные компоненты наблюдают изменения (watch) и приводят мир к желаемому состоянию (reconcile): планируют поды, создают реплики, настраивают сеть, следят за здоровьем.
Участники «хореографии»:
- etcd — консенсус-хранилище (Raft). Единственный источник правды для API-объектов.
- kube-apiserver — фронт к etcd и «магистраль» событий/объектов.
- kube-controller-manager — стандартные контроллеры (Deployment/RS, Node, Job, HPA и др.).
- kube-scheduler — решает, на какой ноде запустить под (подбор узла: фильтры → скоринг → bind).
- kubelet (на каждом узле) — создаёт/убивает контейнеры через CRI (containerd), запускает пробы, отчёты статуса.
- kube-proxy (на каждом узле) — программирует dataplane сервисов (iptables/IPVS) или eBPF (некоторые CNI).
- CNI-плагин (Calico/Cilium/…) — выдаёт IP, строит overlay/политики NetworkPolicy.
Поток событий упрощённо:
- Вы применили Deployment → объект попал в etcd через apiserver.
- ReplicaSet/Deployment-controller увидел «хочу N подов» → создал Pod объекты.
- Scheduler получил несвязанный Pod → подобрал ноду (учёл taints/requests/affinity) → сделал «bind».
- На выбранной ноде kubelet через CRI запустил контейнеры, настроил тома/сеть → обновил статусы.
- kube-proxy/CNI обеспечили доступность по Service/ClusterIP и соблюдение NetworkPolicy.
Компоненты и их задачи (что смотреть и чем управлять)
kube-apiserver
- Роль: единственная точка записи/чтения состояния, авторизация/аутентификация, admission (валидация/мутации), кэширование watch.
- Чувствителен к: всплескам QPS, длинным «листам» и «тяжёлым» admission-webhook’ам, высокой кардинальности объектов/меток.
Ключевые метрики (ориентиры):
- apiserver_request_total, apiserver_request_duration_seconds{verb,resource} — латентность и частота запросов.
- apiserver_current_inflight_requests{request_kind} — сколько запросов сейчас «в воздухе».
- apiserver_flowcontrol_* — очереди APF (приоритеты/справедливость).
- etcd_request_duration_seconds (видно на стороне apiserver) — латентность операций к etcd.
Практические настройки/риски:
- Admission webhooks: ставьте таймауты и политику отказа (Fail/Ignore) осознанно; держите их рядом по сети.
- APF (приоритет/справедливость) включать и настраивать, чтобы CI/операторы не «забили» интерактив.
- Ограничьте «толстые» LIST-запросы (лейблы/поля для селекции, пагинация), следите за watch cache.
kube-controller-manager
- Роль: сотни reconcile-циклов (ReplicaSet/Deployment, Node, Namespace, ServiceAccounts, TTL-controller и др.).
- Симптомы перегруза: растёт workqueue_depth, retries, увеличивается delay reconcile.
Метрики:
- controller_workqueue_depth{controller}, controller_workqueue_adds_total, controller_workqueue_retries_total.
- rest_client_requests_total{code} — ошибки при обращении в apiserver.
Советы:
- Не взрывайте количество контролируемых объектов (тысячи ConfigMap/Secret в одном ns — плохая идея).
- Операторы (CRD) — проверяйте их эффективность и backoff.
kube-scheduler
- Роль: принимает неприбинженные Pod’ы, прогоняет предикаты/скоринг, пишет binding.
- Важные функции: preemption (вытеснение по PriorityClass), multiple profiles, topology-aware spreading.
Метрики:
- scheduler_e2e_scheduling_latency_seconds — end-to-end время планирования.
- scheduler_pending_pods — длина очереди.
- scheduler_scheduling_attempts_total{result} — успехи/ошибки.
Советы:
- Заполняйте requests/limits, иначе планировщик «не понимает» потребности.
- Используйте topologySpreadConstraints вместо исторических anti-affinity, когда нужно равномерное распределение.
- Не злоупотребляйте «жёсткими» affinity — это может резко ограничить варианты.
kubelet (на узле)
- Роль: жизненный цикл Pod/контейнеров (CRI), пробы (liveness/readiness/startup), управление cgroups, GC образов/контейнеров.
- Связи: CRI (containerd), CNI (сеть), CSI (тома).
Метрики/логи:
- kubelet_running_pods, kubelet_pod_start_duration_seconds.
- container_runtime_operations_duration_seconds (создание/старт/останов).
- Логи через journalctl -u kubelet (systemd).
Советы:
- Контролируйте inode/disk pressure (ephemeral-storage).
- Пропишите imageGCHighThresholdPercent/LowThresholdPercent.
- Пробами проверяйте функциональность, а не «ping 200 OK».
kube-proxy (dataplane Service)
- Роль: программирование IPVS/iptables для Service/EndpointSlice; некоторые CNI умеют eBPF-замены.
- Симптомы проблем: длинные таблицы правил, conntrack drop’ы, timeouts на сервисах.
Советы:
- Предпочтительно IPVS (более масштабируем), включайте EndpointSlice.
- Используйте поддерживаемый CNI (Calico/Cilium). Для большого числа сервисов — смотрите в сторону eBPF dataplane (например, Cilium).
- Следите за nf_conntrack_max и sysctl сетевого стека.
etcd (сердце кластера)
- Роль: консенсус-кластер (обычно 3/5 узлов), хранит всю спецификацию/статусы.
- Требования: быстрые SSD/NVMe, отдельные узлы/диски, низкая сет.-латентность между членами.
Метрики (критичные):
- etcd_server_leader_changes_seen_total (частая смена лидера — плохо),
- etcd_disk_wal_fsync_duration_seconds и etcd_disk_backend_commit_duration_seconds (медленные диски),
- grpc_server_handled_total{grpc_code!~"OK"} — ошибки RPC,
- etcd_debugging_mvcc_db_total_size_in_bytes — размер БД,
- etcd_network_peer_round_trip_time_seconds — задержка между членами.
Гигиена:
- Регулярные snapshots и defrag (по регламенту, не «в час пик»).
- Не держать огромные объекты (много-МБ Secrets/ConfigMaps).
- Не плодить миллионы короткоживущих объектов (Events без ретенции/агрегации).
Как компоненты взаимодействуют (глубже)
Паттерн «оператор/контроллер»
- Любой контроллер/оператор подписан на нужные объекты (list-watch) и ведёт локальный кэш (informers).
- Изменение наблюдается → объект попадает в workqueue → reconcile → запись желаемого изменения в apiserver → новый цикл.
- Правило эффективности: «мелкие» патчи (status, spec) и idempotent-операции; backoff при ошибках.
Admission цепочка
- Authentication (TLS, OIDC, ServiceAccount).
- Authorization (RBAC/ABAC/Webhook).
- Mutating Admission (подставили sidecar/аннотации).
- Validating Admission (проверили политику/Gatekeeper/Kyverno).
- Запись в etcd (через apiserver).
Риск: медленный/недоступный webhook «кладёт» весь write-поток. Держите timeouts и политику отказа корректной.
Диагностика: метрики и логи (что, где и зачем)
Где смотреть
- /metrics каждого компонента (Prometheus-формат) — собирайте kube-prometheus-stack.
-
Логи control plane:
- kubeadm/static pods — /var/log/pods/kube-system_* или journalctl -u kubelet (контейнерные логи компонентов);
- managed-сервисы — через облачные логи.
- Аудит API: включайте audit-лог apiserver (с ретеншном и ротацией), не забывайте про чувствительные данные.
Мини-шпаргалка «симптом → куда смотреть»
|
Симптом |
Первое, что открыть |
На что глянуть |
|---|---|---|
|
kubectl «тормозит» |
apiserver метрики/логи |
*_request_duration, current_inflight, webhooks таймаутят |
|
Массовые pending Pods |
scheduler |
e2e_scheduling_latency, ошибки фильтров, ресурсы/affinity/taints |
|
Реплики не сходятся |
controller-manager |
workqueue_depth, retries, ошибки REST |
|
Ноды флапают |
kubelet логи |
NotReady причины: сеть/CRI/диск/пробы |
|
Сервисы «плавают» |
kube-proxy/CNI |
IPVS/iptables состояние, conntrack, EndpointSlice |
|
Вся платформа «дёргается» |
etcd |
WAL/commit latency, leader changes, db size/defrag |
Полезные однострочники (без фанатизма)
# Загрузка API (по ресурсам/вербам) kubectl get --raw /metrics | grep -E 'apiserver_request_duration_seconds_bucket|apiserver_current_inflight_requests' | head # Состояние scheduler kubectl -n kube-system logs -l component=kube-scheduler --tail=200 # Здоровье etcd (если доступно etcdctl на ноде control-plane) etcdctl --endpoints=https://127.0.0.1:2379 endpoint health # Глубина очередей контроллеров kubectl get --raw /metrics | grep controller_workqueue_depth | head
Узкие места и как их избежать
etcd (самая частая «тонкая шея»)
Проблемы: медленные диски, большой объём БД (миллионы записей), «шумные» события/объекты, сетевые задержки между членами.
Профилактика:
- Выделенные узлы/диски (NVMe/SSD), низкая латентность сети между членами кластера.
- Регулярный snapshot + defrag, мониторинг *_commit_duration_seconds.
- Ротация Events/агрегация; не хранить «тяжёлые» данные в ConfigMap/Secret.
- В больших кластерах — несколько «функциональных» кластеров (не всё в один супер-кластер).
Перегруз apiserver
Причины: лавина LIST/GET от операторов, большие LIST без селекторов, тяжёлые admission-webhooks.
Меры:
- Включить/проверить APF (priorities/fairness), лимит QPS у клиентов (client-go).
- Индексируйте обращения: label/field selectors, пагинация.
- Webhooks — локально по сети, таймауты 1–5 сек, health-чекайте их.
- Контроль размерности CRD: меньше «взрывных» CR’ов на один ns/владелец.
kube-proxy/сеть
Проблемы: тысячи сервисов/эндпоинтов → огромные таблицы правил, conntrack overflow.
Меры:
- Режим IPVS и EndpointSlice; или dataplane eBPF (Cilium).
- Настройка nf_conntrack_max, разумные таймауты; ревизия «лишних» сервисов.
kubelet/узлы
Проблемы: OOM/pressure из-за неверных requests/limits, GC картинок, заполнение /var/lib.
Меры:
- Реалистичные requests (по замерам), лимиты на ephemeral-storage, GC образов, мониторинг inode.
Практика: «контрольная карта» control plane
Цель: за 1–2 дня получить рабочую видимость и первые пороги, чтобы не догонять аварию постфактум.
-
Собрать метрики kube-prometheus-stack; сделать базовый дашборд Control Plane:
- apiserver: RPS, p95/99, inflight, ошибки по кодам;
- etcd: commit/wal fsync p95, db size, leader changes;
- scheduler: e2e latency, pending pods;
- controller manager: workqueue depth/retries;
- kubelet: pod start latency, node conditions;
- kube-proxy: sync duration, режим (IPVS/iptables), conntrack.
- Алерты (первый срез):
- etcd_disk_backend_commit_duration_seconds_p99 > X ms (под ваш диск), leader_changes > 0/h;
- apiserver_request_duration_seconds_bucket p99 по write-вербам > X сек;
- scheduler_pending_pods скачет/растёт;
- controller_workqueue_depth стабильно высоко;
- NodeNotReady > 1–2 узлов > 5 мин.
- Аудит admission webhooks: список, таймаут/политика отказа, SLO.
- Профилирование нагрузки: найти «шумных клиентов» (операторы/сканеры), ограничить их QPS/бурст.
- Документировать лимиты: сколько Pod/Service/Endpoints «комфортно» при текущей архитектуре (оценка), когда шардировать.
Мини-гайд по ёмкости control plane (ориентиры для старта)
Это не догма. Берите как отправную точку для пилота и корректируйте по замерам.
- До ~500 узлов / 10–20k Pod: 3 контрол-плейн узла (8–16 vCPU, 32–64 GB RAM), etcd на SSD/NVMe, сеть 10 GbE между CP.
- Аппликативные лимиты: держите подов на ноду в пределах рекомендаций CNI/CRI (часто 80–110) и следите за количеством Service/Endpoints.
- etcd: отдельные диски для WAL/данных, snapshots/defrag, мониторинг p95 fsync/commit.
- apiserver: клиентские QPS/burst у CI/операторов ограничить; включить APF; admission-webhooks проверить на latency.
Частые поломки и runbook’и (коротко)
Сценарий A: apiserver «красный»/высокая латентность
- Проверить webhooks (таймауты/ошибки).
- Посмотреть inflight/flowcontrol очереди; временно меньше QPS у нарушителей.
- Проверить etcd latency (если высокий — займитесь диском/сетью/defrag).
- Если нужно — вырубить «виновный» оператор на время стабилизации.
Сценарий B: растёт scheduler pending
- Нет ресурсов? — requests слишком высокие/taints/affinity слишком строгие.
- Сломан CNI на части нод? — ноды NotReady.
- Посмотреть e2e_scheduling_latency и причины отказа в логах.
Сценарий C: etcd leader меняется/медленные commits
- Проверить сеть между членами, диски (WAL/commit p95).
- Снять snapshot, выполнить defrag (за окно).
- По возможности — выровнять нагрузку на API (уменьшить шквал LIST/watch).
Сценарий D: сервисы «плавают»
- kube-proxy режим (IPVS?), EndpointSlice OK?
- conntrack overflow? — увеличить лимит, укоротить таймауты, уменьшить лишние сервисы.
- Рассмотреть eBPF dataplane (Cilium) при больших масштабах.
Чек-лист «готово к продакшену (control plane)»
- Метрики/логи всех компонентов собираются; есть базовые дашборды и алерты.
- APF включён, «шумные» клиенты ограничены по QPS; admission-webhooks с таймаутами и SLO.
- etcd на быстрых SSD/NVMe, отдельный канал; snapshots/defrag по расписанию; мониторинг p95 commit/WAL.
- kube-proxy в IPVS (или eBPF dataplane), включены EndpointSlice; sysctl сетевого стека настроены.
- kubelet GC образов/эпфемерного диска настроен; prоbes адекватные.
- Документированы «границы» кластера (Pods/Services/EndpointSlices), план шардирования/второго кластера.
- Runbook’и на «высокий apiserver latency», «scheduler pending», «etcd деградация», «сеть/conntrack».
Архитектура Kubernetes — это конвейер изменений: apiserver/etcd фиксируют желаемое состояние, контроллеры и kubelet его добиваются, а kube-proxy/CNI дают связность. Производительность и стабильность держатся на трёх столпах: быстрый etcd, бережный apiserver (кэш, APF, дисциплина клиентов) и здоровая сеть/dataplane. С правильными метриками, алертами и простыми runbook’ами control plane перестаёт быть «чёрной коробкой» — и начинает вести себя предсказуемо.



