Архитектура кластера
Кто с кем общается в кластере. Большая схема и короткие описания компонентов.
Kubernetes — не одна программа, а семь-восемь процессов, которые разнесены по нодам и разговаривают по сети. У них одно правило общения: всё идёт через apiserver. Никто никому напрямую.
Карта
kubectl — просто CLI
kubectl читает ~/.kube/config, берёт оттуда адрес и сертификат, делает обычный HTTPS-запрос к kube-apiserver. Никакой магии внутри нет: то же самое можно дёрнуть через curl и получить тот же JSON. Всю настоящую работу делает apiserver, kubectl только удобно печатает ответ.
Сам манифест kubectl всё же читает: разбирает YAML, ругается на битый отступ и на отсутствующие apiVersion или kind. А вот схему полей с версии 1.27 проверяет apiserver — раньше это делал kubectl по скачанной OpenAPI-схеме, но та врала на части полей, и опечатки проскакивали. Поэтому contaienrs вместо containers теперь отвергает сервер.
Кто за что отвечает
kube-apiserver
REST-фасад поверх etcd, валидация, аутентификация, RBAC. Все остальные компоненты ходят сюда и больше никуда. На прод-кластерах apiserver почти всегда дублируется (обычно 3 инстанса за балансировщиком) ради HA.
etcd
Распределённая key-value база на Raft, держит всё состояние кластера: объекты, секреты, ConfigMap, RBAC. apiserver сам stateless, реальные данные лежат тут. В проде запускают 3 или 5 нод для кворума по Raft, в локалке хватит одной.
kube-scheduler
Watch'ит поды без nodeName и решает, на какую ноду их положить. Учитывает запрошенные ресурсы, taint'ы, affinity, приоритеты. Когда нашёл место, делает bind через apiserver, дальше под подхватывает kubelet нужной ноды.
controller-manager
Один бинарник, внутри десятки контроллеров: Deployment, ReplicaSet, Job, Node, Endpoints. Каждый сравнивает желаемое (5 реплик) с реальным (3 реплики) и докручивает разницу через apiserver. По-английски это называется reconcile loop, по-русски обычно говорят «цикл сверки». На нём держится весь куб.
cloud-controller-manager
Появляется только на managed-кластерах (Yandex Managed Kubernetes, Selectel, EKS, GKE, AKS) и на кластерах с настроенным cloud-provider. Превращает k8s-объекты в облачные ресурсы: Service type=LoadBalancer становится облачным балансировщиком (Yandex Network LB, AWS NLB, GCP LB), PersistentVolume цепляет облачный диск (Yandex Compute Disk, EBS, GCE PD), маршруты к подам прописываются в VPC. На bare-metal этого процесса просто нет.
kubelet
Агент на каждой ноде. Watch'ит «свои» поды через apiserver, говорит контейнерному рантайму запустить образ, монтирует тома, шлёт обратно heartbeat и статус. Если heartbeat не приходит около 50 секунд, нода уходит в Unknown. Порог задаётся флагом --node-monitor-grace-period у controller-manager и настраивается.
kube-proxy
Тоже на каждой ноде. Слушает Service и Endpoints через apiserver и переписывает правила ядра так, чтобы ClusterIP резолвился в реальные поды через DNAT.
Режимов у него три. iptables — исторический дефолт, с 1.33 он переведён в режим поддержки: новых возможностей не будет, чинят только баги. ipvs появился как ответ на медленную работу iptables на больших кластерах. nftables дошёл до GA в 1.33 и стал тем, куда развитие идёт дальше: правила обновляются быстрее, и деградации на тысячах Service нет.
Эту работу всё чаще заменяют на Cilium с eBPF — быстрее, скейлится лучше, без iptables-боли.
container runtime
Реально запускает контейнеры. kubelet общается с ним по CRI (gRPC-протокол), runtime тянет образ из registry и стартует процесс через runc. Стандарт сегодня containerd, альтернатива CRI-O. В k8s 1.24 убрали dockershim (прослойку для общения с Docker), но образы, собранные через Docker, работают как и раньше — это обычные OCI-образы.
CNI plugin
Выдаёт каждому поду уникальный IP и прописывает маршруты между нодами. В простом случае kubelet зовёт CNI-плагин через exec (Calico, Cilium и подобные часто работают как агент-демон и общаются иначе). Реализаций много: Calico, Cilium, Flannel, AWS VPC CNI. Без CNI поды не общаются между нодами.
CNI и kube-proxy — разные слои: CNI даёт pod-сеть, kube-proxy поверх делает Service. Но Cilium и Calico в eBPF-режиме умеют делать обе работы сразу — в таких кластерах отдельный kube-proxy не запускают, всё закрывает eBPF-датаплейн CNI-плагина.
Hub-and-spoke
Все стрелки на схеме идут через apiserver. etcd и kubelet никогда не общаются напрямую, scheduler не лезет в kubelet, controller-manager не лезет в etcd. Любой обмен — REST к apiserver и watch на изменения.
Из этого следует две вещи. Apiserver самая нагруженная часть control plane, поэтому в проде его обычно 3 инстанса за LB. И apiserver самая важная точка отказа: лёг он, и кластером нельзя управлять, хотя поды на нодах продолжают работать сами по себе.
Managed vs bare-metal
На Yandex Managed Kubernetes, Selectel, EKS, GKE, AKS control plane спрятан целиком — платишь облаку, видишь только worker-ноды и endpoint apiserver'а. На bare-metal-кластере ты сам поднимаешь и обслуживаешь весь control plane, и cloud-controller-manager обычно не запускаешь.
Дальше разбираем Pod: что внутри, зачем контейнеры объединяют в один Pod и как kubelet его собирает.
Дрилл · вопросы как на собесе
Проверь себя без подсказок
Сформулируй ответ вслух или письменно, потом раскрой и честно отметь: знал или нет.
Что такое узел (нода) в кластере?
K8S-009Прошли материал до конца? Отметьте урок пройденным.
Прогресс сохранён в этом браузере
Почистишь историю или откроешь с телефона, и отметки пропадут. Оставь почту, они переедут в аккаунт. Пароль придумывать не нужно.
Готово. теперь в аккаунте: прогресс виден с любого устройства. Мой прогресс