1. Архитектура Kubernetes и концептуальные отличия от HashiCorp Nomad
Архитектура Kubernetes и концептуальные отличия от HashiCorp Nomad
Представьте, что вы управляете огромным морским портом. В системе HashiCorp Nomad вы — диспетчер, который выдает четкие инструкции: «Этот контейнер поставить на этот корабль, а тот — перевезти на склад №4». Вы доверяете капитанам (агентам), но вся логика перемещений сосредоточена в ваших руках. В Kubernetes ситуация иная. Вы не даете приказов «переместить». Вы описываете идеальное состояние порта: «В любой момент времени на причале должно стоять три крана, а в зоне А — десять рефрижераторов». Если кран ломается, система сама, без вашего прямого участия, находит замену, чтобы привести реальность в соответствие с вашим описанием.
Переход от Nomad к Kubernetes — это не просто смена синтаксиса HCL на YAML. Это фундаментальный сдвиг в философии управления инфраструктурой: от императивного планировщика задач к декларативной системе управления состоянием.
Философия Control Plane: Мозг системы
Архитектура Kubernetes строится вокруг концепции Control Plane (узлы управления) и Worker Nodes (рабочие узлы). В отличие от Nomad, где серверная часть относительно легковесна и объединяет функции планировщика и хранилища, Control Plane Kubernetes представляет собой сложный ансамбль специализированных компонентов.
API Server: Единственное окно истины
Центральным элементом является kube-apiserver. Это единственный компонент, с которым взаимодействуют пользователи и другие части кластера. Важно понимать: в Kubernetes никто не правит базу данных напрямую. Любое изменение — будь то запуск нового пода или обновление секрета — проходит через API Server.
API Server выполняет три критические функции:
etcd: Хранилище, которое нельзя терять
Все состояние кластера хранится в etcd — распределенной высокодоступной базе данных типа «ключ-значение». Если Nomad может использовать Consul для хранения состояния, то Kubernetes жестко завязан на etcd.
Здесь кроется первое важное отличие для инженеров, привыкших к Nomad. В Nomad потеря части данных в Consul может быть неприятной, но планировщик часто способен восстановить картину мира. В Kubernetes потеря etcd означает смерть кластера, так как в нем хранятся не только данные о запущенных задачах, но и все определения ресурсов (Custom Resource Definitions), права доступа и конфигурации.
Scheduler: Математика размещения
kube-scheduler — это компонент, который следит за новыми подами, у которых не назначен узел. Его работа математически сложна. Он проходит через два этапа:
nodeSelector или имеют taints, которые под не может игнорировать).В Nomad планировщик (Scheduler) работает более монолитно. Kubernetes же позволяет легко подменять стандартный планировщик на кастомный или использовать несколько планировщиков одновременно для разных типов задач.
Controller Manager: Двигатель декларативности
Это, пожалуй, самый важный компонент для понимания «магии» Kubernetes. kube-controller-manager запускает контроллеры, которые представляют собой бесконечные циклы (Control Loops).
Логика работы любого контроллера описывается простой формулой:
etcd.Например, Deployment Controller следит за тем, чтобы количество запущенных реплик совпадало с числом в манифесте. Если вы вручную удалите под, контроллер увидит расхождение и немедленно даст команду на создание нового. Nomad тоже умеет перезапускать упавшие задачи, но в Kubernetes эта логика выведена на уровень абстрактных контроллеров, которые можно писать самостоятельно для управления чем угодно — от баз данных до внешних облачных ресурсов.
Анатомия рабочего узла: Где живет код
Рабочие узлы (Worker Nodes) в Kubernetes выполняют тяжелую работу. В Nomad за это отвечает nomad agent в режиме клиента. В Kubernetes функционал разделен между двумя основными демонами.
Kubelet: Капитан корабля
kubelet — это агент, работающий на каждом узле кластера. Он получает от API Server спецификации подов (PodSpecs) и гарантирует, что описанные в них контейнеры запущены и здоровы.
Важное отличие от Nomad: kubelet не управляет сетью на высоком уровне и не знает о сервисах. Его зона ответственности — жизненный цикл контейнеров на конкретной машине. Он общается с Container Runtime (например, containerd или CRI-O) через интерфейс CRI (Container Runtime Interface). Если в Nomad поддержка Docker или Java-приложений встроена через драйверы, то Kubernetes максимально абстрагирован от среды исполнения.
Kube-proxy: Сетевой регулировщик
kube-proxy отвечает за сетевую абстракцию Service. Он поддерживает сетевые правила на узле, которые позволяют подам общаться друг с другом и принимать внешний трафик. В современных кластерах он чаще всего манипулирует правилами iptables или IPVS.
В Nomad сетевое взаимодействие часто перекладывается на Consul Connect или внешние балансировщики. В Kubernetes сеть является «первоклассным гражданином»: каждый под обязан иметь свой уникальный IP-адрес в рамках кластера, и kube-proxy обеспечивает маршрутизацию к ним, даже если поды постоянно переезжают с узла на узел.
Kubernetes vs Nomad: Сравнение концепций
Для инженера, переходящего с Nomad, важно выстроить ментальную карту соответствий и различий. Несмотря на то, что обе системы решают задачу оркестрации, они делают это с разным уровнем абстракции.
Объектная модель: Job vs Deployment
В Nomad основной единицей работы является Job, внутри которой находятся Groups и Tasks.
Однако в Kubernetes мы редко работаем с подами напрямую. Мы используем Deployment. Разница в том, что Job в Nomad — это описание запуска, а Deployment в Kubernetes — это описание желаемого состояния долгоживущего сервиса.
| Характеристика | HashiCorp Nomad | Kubernetes | | :--- | :--- | :--- | | Единица деплоя | Job (HCL) | Deployment / StatefulSet (YAML) | | Минимальный атом | Task | Pod (один или несколько контейнеров) | | Хранение состояния | Server State / Consul | etcd | | Сложность | Низкая (один бинарный файл) | Высокая (множество компонентов) | | Область применения | Контейнеры, бинарники, VM | Преимущественно контейнеры | | Сетевая модель | Зависит от драйвера (Host/Bridge) | Flat Network (IP-per-pod) |
Декларативность против Императивности
Nomad тяготеет к императивному подходу. Когда вы запускаете nomad job run, вы отправляете команду планировщику. Если планировщик не может найти место для задачи, он выдаст ошибку.
Kubernetes — декларативен до мозга костей. Когда вы делаете kubectl apply, вы обновляете запись в etcd. API Server говорит: «Окей, я записал, что ты хочешь 5 реплик». Если в кластере сейчас нет места, API Server не выдаст ошибку. Он просто создаст объект Pod в состоянии Pending. Как только ресурсы появятся (например, вы добавите новую ноду), планировщик тут же подхватит этот под. Это позволяет строить системы, которые самовосстанавливаются без участия внешних скриптов автоматизации.
Сетевая топология и Service Discovery
В Nomad Service Discovery обычно реализуется через интеграцию с Consul. Приложение регистрирует себя в Consul, и другие сервисы ищут его там.
В Kubernetes Service Discovery встроен в ядро. Объект Service предоставляет стабильный IP-адрес (ClusterIP) и DNS-имя. Даже если за сервисом стоят 10 подов, которые постоянно умирают и рождаются с новыми IP, ClusterIP остается неизменным.
auth и дай его порты».http://auth-service, и внутренняя сеть кластера сама разберется, на какой под его доставить».Жизненный цикл запроса: Как работает магия
Чтобы закрепить понимание архитектуры, проследим, что происходит, когда вы вводите команду kubectl apply -f deployment.yaml.
kubectl отправляет HTTP POST запрос к API Server. Сервер проверяет ваш сертификат или токен, а затем сверяет ваши права с RBAC-политиками.ResourceQuota проверяет, не превысили ли вы лимит ресурсов в своем пространстве имен (Namespace).etcd. На этом этапе для пользователя команда kubectl завершается успешно. Но работа в кластере только начинается.ReplicaSet.ReplicaSet и создает нужное количество объектов Pod. У этих подов в поле nodeName пока пусто — они не назначены на узлы.node-01) и обновляет объект пода в API Server, записывая туда имя узла.node-01 агент kubelet постоянно опрашивает API Server на предмет подов, назначенных ему. Увидев новый под, он обращается к Container Runtime (например, Docker/containerd), чтобы скачать образы и запустить контейнеры.kube-proxy на всех узлах обновляет правила маршрутизации, чтобы трафик начал поступать в новый контейнер.Эта цепочка событий демонстрирует принцип Eventual Consistency (согласованность в конечном счете). Компоненты не вызывают друг друга напрямую, они лишь реагируют на изменения состояния в центральном хранилище.
Граничные случаи и ограничения
При переходе с Nomad на Kubernetes инженеры часто сталкиваются с «оверхедом». Nomad — это один бинарный файл, который может управлять тысячами узлов. Kubernetes требует значительных ресурсов только на поддержание работы Control Plane.
Когда Nomad может быть лучше?
Почему Kubernetes побеждает в долгосрочной перспективе?
Практический взгляд на YAML манифест
В Nomad мы привыкли к HCL (HashiCorp Configuration Language), который позволяет использовать переменные и функции прямо в коде. В Kubernetes манифесты — это чистый YAML. Это сознательное решение: манифест должен быть статичным отражением состояния. Динамика (шаблонизация) выносится во внешние инструменты, такие как Helm или Kustomize.
Типичная структура манифеста Kubernetes всегда включает четыре обязательных поля:
apiVersion: Версия API (например, apps/v1).kind: Тип ресурса (Deployment, Service, ConfigMap).metadata: Имя, пространство имен и метки (labels).spec: Спецификация — то самое «желаемое состояние».Пример базового манифеста, который мы будем детально разбирать в следующих главах:
Обратите внимание на поле selector. В Kubernetes связь между объектами (например, между Deployment и его подами или между Service и подами) осуществляется через Labels (метки). Это гораздо гибче, чем жесткие ссылки в Nomad. Если вы измените метку у пода на лету, Deployment «потеряет» его и тут же создаст новый, а старый под станет «сиротой», но продолжит работать. Эта слабая связанность компонентов — ключ к масштабируемости и устойчивости системы.
Резюмируя архитектурный сдвиг
Переход на Kubernetes требует принятия того факта, что кластер — это живой организм, а не просто набор серверов для запуска скриптов. В Nomad вы управляете задачами. В Kubernetes вы управляете ресурсами и их взаимоотношениями.
Понимание того, как etcd, API Server и контроллеры взаимодействуют между собой, является фундаментом для траблшутинга. Если ваше приложение не запускается, вы теперь знаете, где искать:
Эта прозрачность и разделение ответственности делают Kubernetes сложным в освоении, но невероятно мощным инструментом в руках инженера, стремящегося к полной автоматизации жизненного цикла приложений.