Модуль 20. Установка и настройка кластера
Цели:
- Понять когда какой инструмент выбирать для on-prem/облака/air-gapped/edge.
- Уметь разворачивать и обновлять кластер с HA control-plane (и понимать, что именно стало HA).
- Знать частые грабли: сеть, DNS, MTU, iptables, swap, время, сертификаты, CNI/CSI.
- Иметь чек-листы для запуска и «smoke-тестов».
Карта ландшафта: способы установки
|
Подход |
Что это |
Где уместен |
Плюсы |
Минусы |
|---|---|---|---|---|
|
kubeadm |
«Конструктор» от CNCF для сборки кластера из готовых бинарей |
On-prem, edge, air-gapped |
Гибкость, контроль, стандартная схема HA |
Больше ручной «операционки», нужно знать нутро |
|
Kubespray |
Ansible-плейбуки поверх kubeadm |
On-prem/облако, быстрая автоматизация |
Идемпотентность, много ролей «из коробки» |
Сложнее дебажить Ansible при кастомизациях |
|
kOps |
«Kubernetes-как-сервис» для AWS/и др. IaaS |
AWS-центрик, иногда bare-metal |
Интеграции с облаком, авто-HA, апгрейды |
Сильнее привязан к поддерживаемым IaaS-паттернам |
|
K3s |
Лёгкий дистрибутив с упрощённым control-plane |
Edge/Dev/POC, IoT |
Малый footprint, просто стартануть |
Не для предельных масштабов/жёстких требований |
|
Managed (MKS/GKE/ EKS/AKS) |
Управляемый control-plane от облака |
Облако/гибрид |
SLA на CP, автоапгрейды, интеграции, биллинг |
Контроль ниже, ограничения фич/сетевых паттернов |
Подготовка узлов: «нулевая миля»
Общее:
- ОС: Linux LTS (ядро свежее, но стабильное), синхронизация времени (NTP), корректный hostname/FQDN.
- Swap OFF (и в /etc/fstab), SELinux — по политике (часто Permissive), firewall — открыть нужные порты.
- containerd как CRI (дефолт современной экосистемы), cgroupDriver = systemd у kubelet.
- Модули/системные параметры: br_netfilter, net.bridge.bridge-nf-call-iptables=1, net.ipv4.ip_forward=1, nf_conntrack_max по размеру.
- Сеть: MTU учитываем (особенно если overlay/encapsulation), DNS-резолвинг до репозиториев/регистри.
Порты (суть):
- API-сервер 6443/tcp, etcd 2379–2380/tcp между членами, kubelet 10250/tcp, control-plane 10257/10259 (CM/Scheduler), сетевые — по CNI.
kubeadm: от «одиночки» до HA control-plane
Одиночный CP (для Dev/POC)
- kubeadm init с указанием podCIDR (под выбранный CNI), затем kubectl apply -f <CNI.yaml>, затем kubeadm join на воркерах.
- Подводные: забыли CNI → поды в ContainerCreating/Pending, CoreDNS в CrashLoop из-за DNS/сетевых прав.
HA control-plane (stacked etcd)
Идея: 3 (или 5) узлов control-plane, на каждом — свой etcd (stacked). Перед ними Load Balancer (L4) на 6443.
[LB:6443] -> cp-1 (apiserver+etcd)
-> cp-2 (apiserver+etcd)
-> cp-3 (apiserver+etcd)
workers --> через LB к API
Шаги (высокоуровнево):
- Готовим LB (или keepalived+haproxy) и FQDN k8s-api.company.local → 6443.
- kubeadm ClusterConfiguration с controlPlaneEndpoint: k8s-api.company.local:6443 и нужной podSubnet.
- kubeadm init --config cluster.yml на cp-1.
- Сохраняем команды kubeadm join --control-plane … и … --token … для остальных CP.
- На cp-2/cp-3: kubeadm join --control-plane.
- Workers: kubeadm join ….
- Устанавливаем CNI (Calico/Cilium), проверяем kubectl get nodes, CoreDNS, kube-proxy.
Вариант с внешним etcd: отдельный кластер etcd (3–5 нод), kubeadm на CP без встроенного etcd. Плюс — изоляция хранилища, минус — ещё одна «ферма» для обслуживания.
Тонкости и риски kubeadm
- Сертификаты: срок действия, имена SAN — следите; kubeadm умеет продлевать, но лучше иметь регламент.
- APIServer Load Balancer: health-check должны бить именно 6443 (TCP), а не HTTP.
- Drain/upgrade: PDB/TopologySpread, по одному CP из rotation; планируйте окна и снимайте «шумные» admission-webhooks.
Kubespray: та же база, но автоматизировано
Что даёт:
- Ansible-роль для контейнерного рантайма, kubelet, kubeadm, сетевого плагина (Calico/Cilium/Flannel), опции для etcd (stacked/external), iptables vs nft, user-friendly inventory.
Как работать (вкратце):
- Формируем inventory (группы: kube_control_plane, etcd, kube_node, calico_rr и т. п.).
- Настраиваем group_vars (CNI, podCIDR, CRI, HA-LB и пр.).
- Запускаем cluster.yml playbook.
- Получаем идемпотентную установку; обновления — теми же плейбуками.
Плюсы: воспроизводимость, DRY, быстро встать в on-prem.
Риски: Иногда «магия Ansible» прячет первопричину; держите навык ручной диагностики kubeadm/etcd/iptables.
kOps: ближе к «кластер как код» (особенно AWS)
- State store в объектном хранилище (напр., S3), декларации кластера/инстанс-групп, автоматическая подготовка HA control-plane и etcd, интеграция с LB/IAM/дисками.
- Хорош для «AWS-первого» сценария с инфраструктурой «из коробки» и регулярными апгрейдами.
Плюсы: автоматические паттерны HA, нативная интеграция с облаком.
Минусы: меньше свободы, чем «голым» kubeadm+Terraform; вне поддерживаемых IaaS часть фич будет недоступна.
K3s: лёгкий, но не «игрушка»
- Одно бинарное ядро (server/agent), встроенный набор компонентов, упрощённые зависимости.
- Уместен для edge/Dev/POC, где важен маленький footprint и простая эксплуатация.
- HA делается через внешний datastore (etcd/Postgres/MySQL); без него — одиночный сервер.
Плюсы: скорость запуска, минимум «танцев».
Минусы: не для экстремальных масштабов и не всегда «один в один» с vanilla Kubernetes по флагам/опциям.
Managed-сервисы: MKS/GKE/EKS/AKS
Общее:
- Control-plane обслуживает провайдер (SLA, патчи, апгрейды, etcd/LB их забота).
- Вы управляете узлами/нода-группами, версиями кластера в рамках поддерживаемого «конвейера», CNI/CSI — по каталогу провайдера.
- Интеграции: IAM, балансировщики, диски, приватные регистри.
Выбор:
- MKS (Yandex Cloud): интеграции с VPC/LB/Disk/IAM; удобно для РФ-ландшафта/латентности.
- GKE: богатый набор фич и автоматизаций, режимы Autopilot/Standard.
- EKS: гибкость VPC-CNI, экосистема AWS; чуть больше ручной настройки по узлам.
- AKS: быстрый старт, тесная интеграция с Azure-сервисами.
Плюсы: меньше «операционки» по CP, быстрый старт, поддержка.
Минусы: ограничения сетевых/безопасных паттернов, биллинг на managed-фичи, апгрейды по «каналам» провайдера, не все «низкоуровневые ручки» доступны.
Типовые проблемы при bootstrap (и как их чинить)
|
Симптом |
Вероятная причина |
Что делать |
|---|---|---|
|
CoreDNS CrashLoop |
Нет кластера DNS/права на iptables/MTU |
Проверить CNI, br_netfilter, iptables режим, MTU overlay |
|
Поды в ContainerCreating |
Не поднят CNI/нет доступа к образам |
Применить CNI манифест, проверить доступ к registry |
|
kubectl get cs/API тормозит |
LB не живой, SAN/сертификаты, время |
Проверить 6443 к каждому CP, NTP, SAN у cert |
|
Ноды NotReady |
Kubelet/CRI сбоит, iptables/сеть |
Логи kubelet, containerd, sysctl, firewall/маршрутизацию |
|
Pending у десятков подов |
Нет ресурсов/слишком жёсткий affinity/taints |
Requests/limits, taints/tolerations, topology spread |
|
NodePort не отвечает |
Файрвол/маршрут/conntrack |
Открыть порты, проверить route-таблицы, увеличить nf_conntrack_max |
|
Flapping сети |
MTU mismatch/двойная инкапсуляция |
Выставить MTU у CNI под реальную сеть |
Настройка HA control-plane: практические детали
Архитектуры:
- Stacked etcd (часто по умолчанию): просто, меньше хостов, но etcd «сидит» рядом с apiserver.
- External etcd: изоляция стораджа, лучше для больших масштабов/строгих SLA.
LB к API:
- L4 (TCP 6443) с health-check на 6443 (TCP). Если on-prem — haproxy/keepalived, в облаке — облачный L4 LB.
- DNS имени API с малым TTL (упростит cutover/апгрейды).
Планы обновлений:
- Сначала control-plane (по одному), потом узлы; учитывать deprecations API.
- PDB и TopologySpread для системных DaemonSet/Deployment.
- Проверять admission-webhooks (таймауты/политики отказа) перед апгрейдом — «похоронят» apiserver.
Практика (лабораторка «два пути»)
Вариант A: kubeadm HA on-prem
- 3 узла CP (NVMe/SSD), 2–3 воркера.
- Развернуть L4 LB (haproxy) на 6443, DNS k8s-api.internal.
- kubeadm init --config cluster.yml с controlPlaneEndpoint.
- Присоединить cp-2, cp-3, затем воркеры.
- Установить CNI (Calico/Cilium), проверить CoreDNS/kube-proxy.
- Smoke-тест: kubectl run nginx, Service/Ingress, PV/PVC с CSI.
Вариант B: Managed (напр., MKS)
- Создать кластер (версия, сетка, сервисный аккаунт, группа узлов).
- Включить NetworkPolicy, выбрать CNI/CSI из поддерживаемых.
- Подключить kubectl через kubeconfig/CLI.
- Развернуть базовые инструменты: metrics-server, ingress-controller, CSI-драйвер (если не «встроен»).
- Smoke-тест: деплой, сервис, Ingress, динамический PVC.
Чек-лист «готово к продакшену»
- Узлы подготовлены (swap off, sysctl, контейнерный рантайм, время/NTP).
- Выбран и установлен CNI (проверена MTU/NetworkPolicy).
- Есть HA CP (3+), L4 LB, controlPlaneEndpoint в kubeadm.
- Секреты/доступы к registry/репозиториям подтверждены.
- Базовые аддоны: CoreDNS/metrics-server/kube-proxy/ingress/CSI в «зелёном».
- Мониторинг control-plane (apiserver/etcd/scheduler/controller/kubelet) и алерты (см. Модуль 19).
- Процедура апгрейда и backup/restore (etcd или снапшоты управляемого CP) описана и протестирована.
- Runbook’и: «API не отвечает», «CoreDNS падает», «CNI умер/MTU».
Риски и как их снимать
|
Риск |
Проявление |
Митигировать |
|---|---|---|
|
Медленный/нестабильный etcd |
Высокая латентность API |
SSD/NVMe, отдельные диски, дефрагмент по расписанию, следить за размером БД |
|
Неправильная MTU |
Плавающие таймауты/обрывы |
Согласовать MTU overlay/underlay, настроить в CNI |
|
Admission-webhooks «кладут» API |
Таймауты на write |
Таймауты 1–5 сек, политика отказа, мониторинг latency webhooks |
|
iptables/nft конфликт |
Поломка kube-proxy |
Принудительно legacy или nft везде одинаково |
|
Время «уплыло» |
Ошибки cert/TLS |
NTP во всех зонах/ЦОД, контроль дрифта |
|
Нет процедуры апгрейда |
Деградации/простой |
Документированный план, тест на Stage, совместимость API |
Короткие фрагменты (ровно сколько нужно)
kubeadm ClusterConfiguration (фрагмент идеи, не копипастите без адаптации):
apiVersion: kubeadm.k8s.io/v1beta3 kind: ClusterConfiguration clusterName: prod-cluster controlPlaneEndpoint: "k8s-api.internal:6443" networking: podSubnet: "10.244.0.0/16" # под ваш CNI kubernetesVersion: "v1.29.0" # пример
Kubespray inventory (эскиз):
[kube_control_plane] cp-1 cp-2 cp-3 [etcd] cp-1 cp-2 cp-3 [kube_node] worker-1 worker-2
(Этого достаточно, чтобы не «заблудиться» — полные файлы и команды держим в runbook.)
Вопрос-ответ (FAQ по установке)
В: Что выбрать для on-prem — kubeadm или Kubespray?
О: Если команда сильна в Ansible и нужна идемпотентность/массовые изменения — Kubespray. Если хотите полный контроль и лучше понимать механику — kubeadm.
В: Нужен ли внешний etcd?
О: До сотен узлов и десятков тысяч подов — stacked etcd обычно достаточно. Внешний etcd нужен для изоляции стораджа, строгих SLA и удобства его отдельного апгрейда/резерва.
В: NodePort vs LoadBalancer?
О: В облаках берите LoadBalancer (интеграция с провайдером). On-prem — Ingress + L4/L7-балансировщик снаружи (MetalLB — вариант, если нужен «клауд-лайк»).
В: С какой MTU начинать?
О: Берите MTU underlay-сети минус инкапсуляция overlay. Для VXLAN часто 1450, но проверяйте трассой и реальной сеткой.
В: Можно сразу включить NetworkPolicy?
О: Да, но начните с audit-режима/«мягких» правил и шаблонов. Иначе легко «отрезать» CoreDNS/репозитории.
В: Как безопасно обновлять кластер?
О: По одному control-plane, проверяя компоненты; затем узлы с drain и PDB. Перед апгрейдом — проверка совместимости API и admission-webhooks.
В: Когда имеет смысл Managed-кластер?
О: Когда важно сократить «операционку» (SLA на CP), быстрее стартовать и использовать облачные интеграции. Минус — меньше «ручек» и ограничения провайдера.
В: K3s — можно в прод?
О: Для edge/малых инсталляций — да. Для больших мульти-тенант кластеров с жёсткими SLO лучше «ванильный» k8s.
В: Почему CoreDNS часто в CrashLoop после инсталла?
О: Нет сети (CNI не установлен/не поднялся), проблемы iptables/nft, нет доступа к внешнему DNS/репозиторию. Почините CNI/iptables/маршруты.
В: Где чаще всего «падает» первый запуск?
О: MTU несогласована, swap не выключен, нет модулей ядра, firewall режет порты control-plane, LB не настроен/health-check не на 6443.
Правильная установка Kubernetes — это не «скрипт и по домам», а продуманная механика: подготовка ОС и сети, выбор способа (kubeadm/Kubespray/kOps/K3s/managed), корректная HA-топология control-plane, и дисциплина в апгрейдах/бэкапах. Если с самого начала поставить CNI/MTU, LB на 6443, stacked или external etcd, мониторинг control-plane и иметь небольшие runbook’и — кластер будет предсказуемым и переживёт как рост нагрузки, так и регулярные обновления без сюрпризов.



