Олег Марков
Назначение и примеры Controllers в Kubernetes
Введение
Kubernetes стал основой современной облачной инфраструктуры. Он автоматизирует развертывание, масштабирование и управление контейнеризированными приложениями. Одним из важнейших компонентов Kubernetes являются контроллеры (Controllers). Многие слышали о них вскользь, но мало кто понимает, какую задачу они решают и как именно помогают в управлении состоянием кластера.
Контроллеры позволяют Kubernetes следить за состоянием объектов, такими как Pod, Deployment, Service и другими. Если текущее состояние отличается от желаемого, контроллеры автоматически вносят необходимые изменения, чтобы привести всё в порядок. Рассмотрим подробнее: как работают контроллеры, какие типы контроллеров бывают и как они используются в реальных сценариях.
Основные принципы работы Controllers
Контроллеры — это основной инструмент автоматизации в Kubernetes. Их задача — следить, чтобы желаемое состояние, описанное пользователем в манифестах, всегда совпадало с фактическим состоянием объектов в кластере.
Контроллер — это оператор цикла контроля
Когда вы создаёте ресурс в Kubernetes (например, Deployment), вы описываете только желаемое состояние. Контроллер следит за этим объектом и делает всё возможное, чтобы текущее состояние в кластере совпадало с этим описанием.
Контроллеры реализуют цикл контроля (control loop):
- Считывают желаемое состояние ресурса из etcd (через API Server).
- Сравнивают его с фактическим состоянием.
- Если есть различия — вносят необходимые изменения: создают или удаляют объекты, обновляют их параметры.
Как контроллеры интегрируются в архитектуру Kubernetes
Контроллеры работают как часть управляющих компонентов на мастер-нодах (Control Plane). Большинство из них встроены в контроллер-менеджер (kube-controller-manager
), который запускается как отдельный процесс.
- Они взаимодействуют с API Server: получают уведомления об изменениях и выполняют действия по поддержанию нужного состояния.
- Могут работать как самостоятельные процессы либо как часть общей сборки контроллеров.
Основные типы контроллеров в Kubernetes
Deployment Controller
Этот контроллер управляет ресурсами типа Deployment. Он автоматически создает или удаляет Pod’ы так, чтобы всегда работало нужное количество экземпляров вашего приложения.
Ключевые задачи:
- Масштабирование Pod’ов (scale up, scale down)
- Согласованные обновления (rolling update, rollback)
- Восстановление нужного количества Pod’ов при сбое
Пример Deployment и его контроллера
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3 # Количество нужных Pod’ов
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
Пояснения:
- Здесь мы описываем желаемое состояние: всегда 3 Pod с nginx должны быть запущены.
- Если один из Pod’ов упадет — контроллер добавит новый.
- Если мы уменьшим replicas до 2 — контроллер удалит лишний Pod.
ReplicaSet Controller
ReplicaSet — это контроллер более низкого уровня, который следит, чтобы определённое количество Pod’ов работало в каждый момент времени. Чаще всего вы напрямую не работаете с ReplicaSet (они создаются автоматически для Deployment), но иногда можете делать это вручную.
Пример ReplicaSet
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend
spec:
replicas: 2 # Нужное количество Pod’ов
selector:
matchLabels:
tier: frontend
template:
metadata:
labels:
tier: frontend
spec:
containers:
- name: nginx
image: nginx:1.19
Пояснения:
- Вы определяете количество рабочих Pod’ов через replicas.
- Подходит для случаев, когда обновления приложения не нужны, а только поддерживается количество Pod’ов.
StatefulSet Controller
Этот контроллер — для приложений, которым важен порядок и уникальные идентификаторы Pod’ов (например, базы данных).
Ключевые возможности:
- Уникальные стабильные идентификаторы для Pod’ов
- Гарантированный порядок запуска и завершения работы Pod’ов
- Привязка каждого Pod к своему persistent volume
Пример StatefulSet
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
Пояснения:
- StatefulSet создаёт Pod’ы с именами web-0, web-1, web-2.
- Каждый Pod стабильно получает свои volume и данные не теряются при перезапуске.
- Запуск и удаление Pod’ов производится по порядку, что важно для кластеров баз данных.
DaemonSet Controller
Контроллер DaemonSet гарантирует, что на каждой (или выбранной) ноде будет по одному экземпляру определённого Pod’а. Эта схема полезна для системных задач, например, сбора логов или мониторинга всех узлов.
Пример DaemonSet
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: node-exporter
spec:
selector:
matchLabels:
app: node-exporter
template:
metadata:
labels:
app: node-exporter
spec:
containers:
- name: exporter
image: prom/node-exporter
ports:
- containerPort: 9100
Пояснения:
- На каждой ноде в кластере развернётся отдельный Pod node-exporter для сбора метрик.
- Если добавить новую ноду — контроллер автомагически создаст там нужный Pod.
Job и CronJob Controllers
Job — задача, которая должна быть выполнена определённое количество раз и завершиться успешно.
CronJob — позволяет запускать Job по расписанию (по cron-выражениям).
Пример Job
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
completions: 1
template:
spec:
containers:
- name: pi
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
Пояснения:
- Контроллер Job завершит работу объекта, когда задача будет успешно выполнена.
- Можно указать количество попыток/retries и политику завершения.
Пример CronJob
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *" # Каждую минуту запускается задача
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure
Пояснения:
- Задание будет запускаться по расписанию (здесь — каждую минуту).
- Это удобно для регулярных задач — бекапы, отчёты, автоматизация.
Horizontal Pod Autoscaler (HPA) Controller
Этот контроллер следит за метриками (CPU, память, внешние метрики) и автоматически масштабирует количество Pod’ов вашей нагрузки.
Пример описания HPA
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: nginx-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx-deployment
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
Пояснения:
- HPA будет автоматически следить за средней загрузкой CPU.
- Количество Pod’ов будет увеличиваться или уменьшаться в рамках заданных min и maxReplicas.
Контроллеры собственных ресурсов (Custom Controller, Operator)
Kubernetes позволяет создавать собственные контроллеры (Custom Controller) для управления ресурсами, которых нет “из коробки”. Это делается через Custom Resource Definitions (CRD).
Применение:
- Автоматизация специфических для вашего бизнеса процессов
- Реализация более сложной логики, чем у стандартных контроллеров
Пример общего процесса создания Custom Controller
- Создаёте описание нового типа ресурса (CRD).
- Пишете контроллер, который следит за изменениями этого ресурса и реагирует нужным образом.
- Разворачиваете контроллер в кластере.
Базовую структуру можно реализовать на Go, Python и даже Bash (через k8s API или kubectl).
Пример контроллера обычно выходит за рамки простого примера YAML, поэтому здесь лишь коротко опишу:
// Примерный контур кастомного контроллера на Go
func main() {
// Подключаемся к kube-apiserver
// Читаем события по вашему CRD-ресурсу
// В случае изменений — вызываем обработчик
}
Пояснения:
- Кастомные контроллеры позволяют реализовать любые процессы автоматизации с использованием Kubernetes API.
- Вам не обязательно писать всё “с нуля” — существуют фреймворки, такие как Kubebuilder и Operator SDK.
Как работают контроллеры: кейсы из жизни
Самовосстановление приложения
Даже если вы вручную удалите Pod, созданный через Deployment, контроллер автоматически создаст новый, чтобы количество экземпляров всегда было правильным. Это основа высокой доступности Kubernetes.
Автоматизация масштабирования
HPA или контроллер реплик позволяют подстраивать нагрузку под реальные запросы пользователей. Вы просто изменяете параметр — контроллер всё “подбирает” за вас.
Продвинутая автоматизация с помощью операторов
Операторы позволяют спрятать бизнес-логику и автоматизацию управления сложными приложениями (например, кластерами БД) за своими контроллерами. Пример — оператор PostgreSQL, который следит за резервным копированием, восстановлением, масштабированием и обновлением.
Детали механизма работы Controllers
- Event Loop: контроллер подписывается на события изменений в ресурсе через API Server.
- Обработка изменений: когда обнаружено несовпадение, контроллер создаёт/удаляет объекты, обновляет их спецификацию.
- Реакция на сбои: если Pod упал — ReplicaSet/Deployment исправит это, создав новый.
- Реализация идемпотентности: контроллеры выполняют свои действия столько раз, сколько потребуется, пока состояние не совпадёт с ожидаемым.
Чем отличаются контроллеры и операторы
- Контроллер — программный цикл, который следит и корректирует состояние конкретного ресурса/типа ресурса (например, ReplicaSet, Deployment).
- Оператор (Operator) — архитектурный паттерн; это кастомный контроллер, который реализует экспертизу управления жизненным циклом не только объекта, но и бизнес-логики (например, развёртывание кластера БД, обновления, бэкапы). Оператор сочетает собственный CRD и контроллер/контроллеры.
Заключение
Контроллеры формируют фундамент работу Kubernetes, обеспечивая автоматическое поддержание декларативно заданного состояния. С помощью встроенных контроллеров вы масштабируете приложения, достигаете надёжности и автоматизации. Продвинутые сценарии, в том числе ваши собственные игровые “правила”, реализуются с помощью кастомных контроллеров и операторов. Понимание, как работает механизм контроля, важно для каждого, кто строит отказоустойчивые и управляемые инфраструктуры на базе Kubernetes.
Частозадаваемые технические вопросы по теме Controllers в Kubernetes
Как заставить контроллер игнорировать определённые Pod’ы или ноды?
Чтобы контроллеры пропускали некоторые Pod’ы или ноды, используйте поля nodeSelector
, affinity
, или taints/tolerations
в спецификации Pod. Например:
yaml
spec:
nodeSelector:
disktype: ssd
Это ограничит создание Pod только на ноды с указанным label.
Как посмотреть, какие контроллеры сейчас управляют объектом?
Выполните:
bash
kubectl get deployment nginx-deployment -o yaml
В секции metadata.ownerReferences
вы увидите, какой контроллер отвечает за объект (например, ReplicaSet для Deployment).
Как “отвязать” контроллер от объекта, чтобы управлять объектом вручную?
Удалите запись о контроллере из секции metadata.ownerReferences
у объекта. После этого контроллер перестанет автоматически “ремонтировать” объект. Либо удалите связку label-selector или разверните Pod вне контролирующего ресурса.
Как узнать, почему контроллер не создаёт или не удаляет Pod?
Используйте команду:
bash
kubectl describe deployment <имя>
В разделе Events будут показаны ошибки — например, нехватка ресурсов, ошибки в манифесте, проблемы с image и прочее.
Можно ли написать свой контроллер без глубоких знаний Go?
Да, можно! Для этого существуют проекты типа Kopf (Python), Java-реализации, а также обработка событий через kubectl/kubewatch. Однако для продакшн-решений рекомендуется использовать Go и фреймворки Operator SDK, Kubebuilder.
Постройте личный план изучения Kubernetes до уровня Middle — бесплатно!
Kubernetes — часть карты развития DevOps
100+ шагов развития
30 бесплатных лекций
300 бонусных рублей на счет
Бесплатные лекции
Все гайды по Kubernetes
Лучшие курсы по теме

Kubernetes и Helm
Антон Ларичев
Docker и Ansible
Антон Ларичев