Что такое Kubernetes (K8s)? Основные определения: кластер, контейнер, сервисы

Эта статья объясняет ключевые понятия Kubernetes, которые потребуются для работы с Managed Kubernetes (управляемым Kubernetes). Если вы уже знакомы с Kubernetes, переходите к созданию кластера.

Полная документация Kubernetes доступна на официальном сайте.

Что такое Kubernetes

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

Вместо того чтобы вручную запускать приложение на конкретном сервере, следить за его состоянием и перезапускать при сбоях – вы описываете желаемое состояние (сколько экземпляров приложения должно работать, сколько ресурсов выделить, как обрабатывать трафик), а Kubernetes поддерживает это состояние автоматически.

Контейнеры

Контейнер – это изолированная среда для запуска приложения. В контейнер упаковывается само приложение вместе со всеми зависимостями: библиотеками, конфигурацией, средой выполнения. Благодаря этому приложение работает одинаково независимо от того, где оно запущено – на локальной машине разработчика или на сервере в cloud-инфраструктуре (облачной инфраструктуре).

Контейнеры создаются из образов (images). Образ – это шаблон, по которому запускается контейнер. Наиболее распространенный формат – Docker-образы.

Кластер

Кластер Kubernetes – это набор серверов (нод), объединенных для совместного запуска контейнерных приложений. Кластер состоит из двух типов компонентов:

  • Control plane (управляющий контур, Master-ноды) – компоненты, которые управляют состоянием кластера: принимают запросы, распределяют нагрузку, следят за состоянием приложений. Control plane полностью управляется платформой.
  • Worker-ноды – серверы, на которых непосредственно работают ваши приложения.

Ноды

Нода (node) – это отдельный сервер в кластере. Ноды бывают двух типов:

Master-нода – сервер управляющего контура. На нем работают компоненты Kubernetes, отвечающие за координацию кластера:

  • API-сервер (интерфейс программирования приложения) – принимает команды (например, от kubectl – консольного инструмента для управления Kubernetes)
  • etcd (хранилище данных) – хранилище состояния кластера
  • Scheduler (планировщик) – решает, на какой ноде запустить новый под (единицу развертывания)
  • Controller Manager (компонент управляющей плоскости) – следит, чтобы текущее состояние кластера соответствовало желаемому

Worker-нода – сервер для запуска приложений пользователя. На каждой worker-ноде работает:

  • kubelet (компонент Kubernetes) – агент, который получает инструкции от control plane и управляет контейнерами на ноде
  • kube-proxy (сетевой агент) – управляет сетевыми правилами для доступа к приложениям
  • Container runtime (контейнерная среда) – среда для запуска контейнеров

Поды (Pods)

Под (pod) – это минимальная единица развертывания в Kubernetes. Каждый контейнер в Kubernetes запускается внутри пода. Под содержит один или несколько контейнеров, которые:

  • работают на одной ноде
  • разделяют сетевое пространство (имеют общий IP-адрес – идентификатор устройства в компьютерной сети)
  • могут использовать общие тома для хранения данных

Чаще всего один под содержит один контейнер с приложением. Несколько контейнеров в одном поде используются, когда контейнеры тесно связаны и должны работать вместе (например, приложение и sidecar-прокси (шаблон проектирования) для логирования).

Поды не создаются напрямую – ими управляют контроллеры.

Контроллеры

Контроллеры следят за состоянием приложений и поддерживают его в соответствии с заданной конфигурацией.

Deployment – наиболее распространенный контроллер. Описывает, какой контейнер запустить и в скольких экземплярах (репликах). Если под падает – Deployment автоматически создает новый.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80

Этот манифест создает три пода с nginx. Если один из подов завершится с ошибкой, Deployment запустит новый, чтобы количество работающих экземпляров оставалось равным трем.

Другие распространенные контроллеры:

  • StatefulSet – для приложений с состоянием (базы данных, очереди). В отличие от Deployment, гарантирует стабильные имена подов и порядок запуска.
  • DaemonSet – запускает по одному поду на каждой ноде. Используется для системных задач: сбор логов, мониторинг, сетевые агенты.
  • Job / CronJob – для разовых или периодических задач (миграции, бэкапы, отчеты).

Сервисы (Services)

Поды в Kubernetes получают IP-адреса, но эти адреса временные – при пересоздании пода адрес меняется. Kubernetes использует сервисы, чтобы решить эту проблему: сервис предоставляет стабильный сетевой адрес для группы подов.

Сервис выбирает поды по меткам (labels) и распределяет трафик между ними.

Основные типы сервисов:

  • ClusterIP (по умолчанию) – доступен только внутри кластера. Используется для связи между компонентами приложения.
  • NodePort – открывает порт на каждой ноде кластера для доступа извне.
  • LoadBalancer – создает внешний балансировщик нагрузки. При создании сервиса типа LoadBalancer автоматически выделяется балансировщик со стороны платформы. Подробнее – в статье “Сеть и балансировщик нагрузки”.

Пространства имен (Namespaces)

Namespace – это способ логически разделить ресурсы внутри одного кластера. Разные команды, окружения или приложения могут работать в своих пространствах имен, не мешая друг другу.

По умолчанию в кластере есть несколько namespace:

  • default – используется, если namespace не указан явно
  • kube-system – системные компоненты Kubernetes
  • kube-public – ресурсы, доступные всем пользователям кластера

Создание собственного namespace:

kubectl create namespace my-app

Манифесты

Конфигурация ресурсов в Kubernetes описывается в YAML-манифестах (язык для хранения информации). Манифест – это файл, в котором указано, какой ресурс нужно создать и с какими параметрами.

Структура манифеста:

apiVersion: v1          # версия API
kind: Pod               # тип ресурса
metadata:
  name: my-pod          # имя ресурса
  namespace: default    # пространство имен
  labels:
    app: my-app         # метки для идентификации
spec:                   # спецификация ресурса
  containers:
  - name: app
    image: my-app:latest

Манифест применяется командой:

kubectl apply -f manifest.yaml

Метки (Labels) и селекторы

Метки (labels) – это пары ключ-значение, которые присваиваются ресурсам Kubernetes. Они используются для организации и выборки ресурсов.

metadata:
  labels:
    app: frontend
    env: production

Селекторы позволяют выбирать ресурсы по меткам. Например, сервис может направлять трафик только на поды с определенной меткой:

selector:
  app: frontend

Taints и Tolerations

Taints и Tolerations – механизм, который управляет тем, какие поды могут работать на каких нодах.

Taint (ограничение) – назначается ноде и запрещает запуск подов, у которых нет соответствующего Toleration.

Toleration (допуск) – указывается в спецификации пода и разрешает ему работать на ноде с определенным taint.

Как это работает

Taint состоит из ключа, значения и эффекта:

<ключ>=<значение>:<эффект>

Эффекты:

  • NoSchedule – поды без соответствующего Toleration не будут запланированы на эту ноду. Уже работающие поды не затрагиваются.
  • PreferNoSchedule – Kubernetes будет избегать размещения подов без Toleration, но при нехватке ресурсов на других нодах может разместить.
  • NoExecute – поды без Toleration не только не будут запланированы, но и будут удалены с ноды, если уже работают.

Пример

Допустим, у вас есть группа нод, выделенная под критичные сервисы. Вы назначаете taint на эти ноды:

kubectl taint nodes node1 dedicated=critical:NoSchedule

Теперь обычные поды не смогут запуститься на node1. Чтобы под мог работать на этой ноде, в его манифесте нужно указать Toleration:

spec:
  tolerations:
  - key: "dedicated"
    operator: "Equal"
    value: "critical"
    effect: "NoSchedule"
  containers:
  - name: app
    image: my-critical-app:latest

Зачем это нужно

  • Изоляция нагрузки – выделить ноды под определенные приложения, не допуская на них посторонние поды
  • Разделение окружений – запретить dev-подам работать на production-нодах
  • Специализированное оборудование – зарезервировать ноды с GPU (графическим процессором) или большим объемом памяти только для подходящих задач

Taints можно назначать при создании или редактировании worker-группы (группы узлов) – они автоматически применятся ко всем нодам группы. Подробнее – в статье “Создание и настройка кластера”.

Все статьи раздела

  1. Kubernetes (K8s) – обзор сервиса Managed Kubernetes
  2. Основы Kubernetes – вы здесь
  3. Создание и настройка кластера – конфигурация master-нод, сеть и worker-группы
  4. Подключение к кластеру и работа с kubectl (консольный инструмент для управления Kubernetes) – kubeconfig (конфигурационный файл Kubernetes), подключение и первые команды
  5. Управление кластером – добавление нод, изменение конфигурации, обновление, удаление
  6. Сеть и балансировщик нагрузки – сетевая модель, внешние и внутренние балансировщики
  7. Лимиты, квоты и ограничения – ограничения платформы, что можно и нельзя изменить

Если возникнут вопросы, напишите нам, пожалуйста, обращение в панели управления аккаунта (раздел “Помощь и поддержка”), а если вы захотите обсудить эту статью или наши продукты с коллегами по цеху и сотрудниками Beget – ждем вас в нашем сообществе в Telegram.