Skip to content

Kubernetes (K8s)

Kubernetes (K8s) - это платформа с открытым исходным кодом для автоматизации развертывания, масштабирования и управления контейнеризированными приложениями в условиях кластера. Kubernetes предоставляет средства для оркестрации и управления контейнерами, позволяя автоматизировать множество задач, связанных с развертыванием и управлением приложениями в контейнерах.

Kubernetes - это своего рода программная надстройка над кластером серверов, которая решает задачи по распределению вычислительных мощностей между трубуемыми для корректной работы того или иного приложения контейнерами. Необходимые контейнеры создаются, мониторятся, удаляются средствами kubernetes.

Архитектура кластра

В текущем контексте, под кластером подразумевается набор из нескольких серверов (зачастую - это виртуальные машины), объединенных высокопроизводительной сетью, имеющих единую точку входа (управления)

В обязательном порядке, кластер Kubernetes состоит из двух типов нод: master (control plane node) и рабочие ноды.

  • Control plane node - это ноды на которых выполняются служебные компоненты Кубера, отвечающие за управление кластером. Количество управляющих нод должно быть нечетным, чтобы исключить split brain, при выходе из строя Мастера. Минимальное количество управляющих нод для обеспечения отказоустойчивости - 3 шт.

  • Рабочие ноды (nodes) - это ноды на которых происходит запуск рабочей нагрузки, т.е. на них разворачиваются контейнеры в подах. В одном кластере может быть до 5000 рабочих нод.

На самом верхнем уровне, управление кластером осуществляется декларативным способом, т.е.: администратор описывает желаемое состояние кластера в виде YAML-файлов и передает требуемую конфигурацию через kube-apiserver в кластер Кубера, далее компоненты кластера приводят систему в требуемое состояние.

Компоненты кластера

Компоненты Control Plane ноды

  • kube-apiserver - ключевой компонент кластера Kubernetes, является API-сервером предоставляющий RESTful HTTP интерфейс для коммуникации между всеми компонентами кластера. Можно представлять API-server, как главную шину кластера, к которой подключены все остальные компоненты. API-сервер - не хранит никакое состояние, каждый запрос к нему должен содержать всю необходимую информацию. Является одним из самых высоко-нагруженных компонентов control-plane ноды, наряду с БД etcd.

    Если говорить об архитектуре, то сервер API — это по сути CRUD-приложение. То есть предназначенное для чтения, записи, обновления и удаления данных. Оно в принципе не отличается от, например, WordPress. Большая часть его работы — это хранение и предоставление данных.

RESTful API

RESTful API (Representational State Transfer API) - это архитектурный стиль для проектирования сетевых приложений, который использует принципы и ограничения HTTP (Hypertext Transfer Protocol). RESTful API предоставляет способ взаимодействия с веб-ресурсами с использованием стандартных HTTP-методов, таких как GET, POST, PUT, DELETE и другие.

Вот некоторые основные принципы и характеристики RESTful API:

  • Ресурсы (Resources): В RESTful API, каждый объект или данные, с которыми можно взаимодействовать, представляют собой ресурсы. Ресурсы идентифицируются с помощью уникальных URL (Uniform Resource Locator), которые служат их адресами.
  • HTTP Методы: RESTful API использует стандартные методы HTTP для выполнения операций над ресурсами. Например, GET используется для получения информации о ресурсе, POST для создания новых ресурсов, PUT для обновления существующих ресурсов и DELETE для удаления ресурсов.
  • Представление (Representation): Ресурсы могут иметь разные представления (например, JSON, XML, HTML), которые определяют формат данных, передаваемых между клиентом и сервером.
  • Без состояния (Stateless): Каждый запрос к RESTful API должен содержать всю необходимую информацию для выполнения этого запроса. Сервер не хранит информацию о состоянии клиента между запросами.
  • Клиент-Серверная архитектура: RESTful API подразумевает разделение клиентской и серверной частей системы. Это позволяет легко масштабировать и обновлять каждую из них независимо.
  • Удержание кэширования (Caching): Сервер может указывать, может ли клиент кэшировать ответы. Это позволяет улучшить производительность и снизить нагрузку на сервер.
  • Слой для уровня (Layered System): RESTful API может быть построено в виде многоуровневой архитектуры, где клиенты могут взаимодействовать только с ближайшим сервером, не зная о более высоких уровнях системы.

RESTful API широко используется в веб-разработке, включая создание веб-служб, мобильных приложений и многое другое. Этот стиль облегчает интеграцию и взаимодействие различных приложений и систем через интернет.

  • etcd - распределенная БД типа key-value, в которой хранится вся информация о состоянии кластера, включая информацию о подах, службах, конфигурациях, секретах и прочих ресурсов Kubernetes. Все компоненты кластера обращаются к etcd через kube-apiserver: кто-то записывает туда информацию, кто-то считывает, кто-то изменяет. Данное хранилище позволяет согласовывать действия всех узлов кластера. Хранилище etcd также является очень нагруженным, поэтому его часто делают распределенным между несколькими серверами, для повышения отказоустойчивости. Важной особенностью данной БД является возможность хранить несколько версий одного и того же значения. Компоненты кластера отслеживают изменения интересующих их папок ключей, и включаются в работу при регистрации изменений. Важно: etcd требователен к диску и сети, без них он может потерять кворум.
etcd

Etcd — распределенная KV база-данных которая обеспечивает надежное хранение информации на кластере машин.

Интересно что название это игра слов с /etc — папкой для конфигов в unix системах и d — distributed.

Есть несколько use-case использования:

  • Хранить настройки, метадату, флаги конфигурации(kubernetes)
  • Распределенная блокировка по узлам кластера(locksmith)

За изменением значений в кластере можно наблюдать что позволит вашему приложению реагировать на них моментально и изменять свое поведение.

В качестве алгоритма консенсуса используется Raft, соответственно для надежной работы кластера нужно (n / 2) + 1 живой узел иначе можно попасть в ситуацию когда нет кворума большинства и кластер развален. Хранилище устроено так что невозможно сделать шардинг, каждый узел в кластере хранит копию узла-лидера, и все изменения должны быть приняты большинством перед сохранением.

Гарантии надежности ACID:

  1. Атомарность. Операция либо завершается полностью, либо не завершается вовсе.
  2. Консистентность. Независимо от того к какому серверу обращается клиент он всегда получит одинаковые данные или события в том же порядке.
  3. Изоляция. Реализует самый высокий уровень изоляции Serializable.
  4. Долговечность. Все операции которые получили статус “выполненных” будут сохранены и не могут быть потеряны.

Ещё возможности:

  • HTTP/JSON API
  • Подписку на изменение значений(Watch)
  • Multi-version Concurrency Control
  • Распределенные блокировки
  • Транзакции
  • Пользователи, роли
  • Хорошо работает в конфигурации крос-датацентер/крос-континент
  • B-tree индексы для ключей
  • Это не in-memory база-данных все пишется на диск

Алгоритм консенсуса Raft который использует etcd имеет ряд ограничений:

  • Все сообщения на запись отправляются на узел-лидер
  • Чтение может проходить на любом узле кластера
  • Прежде чем сохранить данные большинство узлов должны подтвердить вставку
  • Если умирает узел-лидер, кластер ждет определенное время и начинает голосование за нового лидера, все сообщения в это время помещаются в специальную очередь до выбора нового лидера
  • etcd полностью исключает воможность split-brain/multi-master так как для консенсуса нужно иметь большинство живых узлов это же может привести к ситуации полного развала кластера ввиду недостатка кворума
  • kube-scheduler - компонент control-plane, который планирует распределение подов по нодам. Анализирует запросы подов и выбирает подходящие (по CPU, RAM, disk) рабочеи узлы, на которых поды стоящие в очереди будут развернуты. Обслуживает, новые поды, измененные поды, поды у которых вышла из строя нода. Алгоритм выбора наилучшей ноды сложен, учитывает мого условий: состояние все рабочих нод, конфигурацию пода, условия аффиности и антиаффиности подов (концепции распределения подов по меткам (labels), поды с подходящими метками размещаются на определенных узлах, либо наоборот - на разных узлах).

  • kube-controller-manager - набор компонентов который отвечает за мониторинг состояния ресурсов кластера и поддержание жизненного цикла приложений разворачиваемых в кластере. Включает в себя следующие компоненты:

    • Node Controller Manager - опрашивает и обновляет состояния рабочих нод кластера, записывает полученные статус в etcd
    • Job controller - специализируется на выполнении одноразовых задач типа Job в кластере. Следит за тем что б под задачи создавались поды в нужных количествах
    • Endpoint Controller Manager - отвечает за объекты Endpoint, через которые происходит маршрутизация трафика внутри кластера. Объекты Endpoint связывают ip-адреса:порты с сервисами Kubernetes, далее сервисы связываются с подами. Поды могут переезжать внутри кластера, а Endpoint Controller следит за сохранением сетевой связности, обновляя endpoints.
    • Service Account & Token Controller Manager: Отвечает за управление учетными записями служб и токенами безопасности.
    • Namespace Controller Manager: Управляет созданием и удалением пространств имен (Namespaces). Пространства имен позволяют изолировать приложения и ресурсы в кластере.
    • Service Controller Manager: Отвечает за создание и управление объектами служб (Services) и LoadBalancer Services.
    • Replication Controller Manager: Отвечает за управление контроллерами репликации, такими как ReplicaSets. Он следит за желаемым количеством экземпляров пода и обеспечивает их создание и масштабирование в соответствии с этими желаниями.
    • Daemon Set Controller Manager: Управляет объектами DaemonSet, которые обеспечивают выполнение определенных подов на каждом узле в кластере.
  • cloud-controller-manager - компонент Kubernetes, который отвечает за интеграцию с конкретными облачными провайдерами (например, AWS, Azure, Google Cloud и другими). Этот компонент вынесен из мастер-узла Kubernetes, чтобы разделить управление кластером и управление облачными ресурсами. Некоторые контроллеры имеют взаимосвязи с API облачного провайдера: node controller (для взаимодействия с облачными нодами), rote controller (для настроики сетевых маршрутов в облачной инфраструктуре), service controller (для работы с балансировщиками нагрузки)

Компоненты Рабочей ноды

  • Kubelet - агент, который работает на каждой ноде. Он отвечает за:

    • связь с control plane нодой через API-сервер: мониторит состояние ноды и подов, принимает задание с Мастера.
    • за выполнение рабочих задач связанных с подами (управление жизненным циклом подов). Это включает в себя создание, запуск, остановку и удаление подов в соответствии с их описанием.
    • отдает команды связанные с работой контейнеров.
    • управляет ресурсами выделяемыми подам.
  • kube-proxy - сетевой прокси, управляет сетевой маршрутизацией между подами, может выполнять функции балансировщика. Отвечает за сетевую связность между сервисами подами как внутри своей рабочей ноды, так и на других нодах.

  • Container Runtime - компонент, отвечающий за запуск и управление контейнерами. Container Runtime (Docker, containerd, CRI-O) выполняет инструкции для создания и управления контейнерами на рабочей ноде.