Kubernetes
Kubernetes (K8s) запускает контейнеры в кластере, поддерживает заданное количество работоспособных реплик и планирует задания обучения и инференса на GPU.
Kubernetes, часто сокращаемый до K8s, — это система с открытым исходным кодом для запуска контейнеризированных приложений в кластере машин. Пользователи задают требуемое состояние рабочей нагрузки: какой образ контейнера запускать, сколько его копий поддерживать и сколько ресурсов CPU, памяти и GPU нужно каждой копии. Kubernetes непрерывно запускает, перезапускает, перемещает и масштабирует контейнеры, чтобы поддерживать заданное состояние. Google объявила о проекте в июне 2014 года, используя наработки своего внутреннего менеджера кластеров Borg. В июле 2015 года вместе с версией 1.0 Google представила Kubernetes как начальный проект недавно созданного Фонда облачных вычислений. Название означает «кормчий» по-гречески, а K8s заменяет восемь букв между K и s. В эксплуатации машинного обучения (MLOps) Kubernetes служит общим слоем для запуска заданий распределённого обучения, пакетного инференса и обслуживания моделей на общей инфраструктуре.
Архитектура и цикл управления#
Кластер состоит из плоскости управления и рабочих узлов. В плоскости управления находятся сервер API, с которым взаимодействуют все клиенты, хранилище etcd с состоянием кластера, планировщик, назначающий новые поды узлам, и контроллеры, каждый из которых следит за определённым типом объекта. На каждом рабочем узле — будь то локальный сервер или виртуальная машина в облаке — работают агент kubelet и среда выполнения контейнеров, например containerd или CRI-O. Минимальная единица планирования Kubernetes — под: один или несколько контейнеров, использующих общий сетевой адрес и тома хранилища.
Рабочие нагрузки объявляют в виде объектов, обычно записываемых в YAML и применяемых с помощью kubectl. Deployment поддерживает заданное число одинаковых подов и постепенно заменяет их при изменении образа; Service предоставляет этим подам единый стабильный адрес и распределяет между ними запросы; Job запускает поды до завершения задачи. Контроллеры сравнивают объявленное состояние с фактическим и реагируют на любые различия:
Этот же цикл обеспечивает самовосстановление Kubernetes. Когда узел выходит из строя, его поды перестают работать, и контроллер создаёт им замену на исправных узлах. Под со статусом Pending из-за нехватки ресурсов также сигнализирует средствам автоматического масштабирования кластера о необходимости добавить узлы.
Kubernetes для машинного обучения#
GPU становятся доступны подам через плагины устройств, которые объявляют их как ресурс, доступный для подсчёта, например nvidia.com/gpu, а также через динамическое выделение ресурсов, стабильное начиная с Kubernetes 1.34. Оно позволяет поду запрашивать устройства по атрибутам, например по модели GPU или объёму памяти. GPU Operator от NVIDIA устанавливает драйверы и плагины на узлах с GPU и может разделить одну GPU на секции Multi-Instance GPU или распределить её по времени между подами. В 2021 году OpenAI сообщила, что масштабировала отдельные кластеры Kubernetes до 7 500 узлов для обучения таких моделей, как GPT-3 и CLIP.
Проекты с открытым исходным кодом добавляют поверх этого специализированные для машинного обучения слои:
- Kubeflow: Запускает в кластере распределённое обучение PyTorch, конвейеры машинного обучения и блокноты.
- Kueue: Ставит пакетные задания и задания обучения в очередь, а также обеспечивает соблюдение квот команд, чтобы дорогие GPU были загружены и ни одна команда не заняла их все.
- KServe: Размещает модели за автоматически масштабируемыми конечными точками, в том числе с масштабированием до нуля для неактивных моделей.
- Горизонтальный автоскейлер подов: Добавляет или удаляет реплики для инференса в зависимости от загрузки CPU или пользовательских метрик, например длины очереди. Это позволяет поддерживать стабильную задержку при изменении трафика.
Job — самый простой способ запустить одноразовую задачу на GPU, например пакетный инференс. В официальном Docker-образе Ultralytics уже есть команда yolo и веса YOLO26 nano, поэтому в этом Job задаётся только команда и запрашивается один GPU:
apiVersion: batch/v1
kind: Job
metadata:
name: yolo26-predict
spec:
backoffLimit: 2 # retry a failed pod at most twice
template:
spec:
restartPolicy: Never
containers:
- name: yolo
image: ultralytics/ultralytics:latest
command: ["yolo", "predict", "model=yolo26n.pt", "source=https://ultralytics.com/images/bus.jpg"]
resources:
limits:
nvidia.com/gpu: 1 # schedule only onto a node with a free GPUkubectl apply -f job.yaml отправляет задание, планировщик размещает под на узле со свободной GPU, а kubectl logs job/yolo26-predict выводит результаты обнаружения объектов в режиме предсказания. Для Job обучения используется тот же подход; к нему добавляется постоянный том для контрольных точек и том в оперативной памяти по адресу /dev/shm для рабочих процессов загрузчика данных PyTorch.
Kubernetes, Docker и бессерверные вычисления#
- Docker: Собирает образы и запускает контейнеры на одной машине. Kubernetes распределяет контейнеры по многим машинам, а начиная с версии 1.24 запускает созданные Docker образы через containerd или CRI-O, а не через Docker Engine.
- Бессерверные вычисления: Такие сервисы, как Google Cloud Run и AWS Lambda, полностью скрывают кластер и взимают плату за каждый запрос. Knative переносит ту же модель масштабирования до нуля в кластеры Kubernetes.
- Управляемый Kubernetes: Google Kubernetes Engine (GKE), Amazon Elastic Kubernetes Service (EKS) и Azure Kubernetes Service (AKS) запускают плоскость управления для своих клиентов, а GKE Autopilot также управляет рабочими узлами.










