Оркестрация контейнеров

Рейтинг: 74.1% · 11 голосов
Специализация LPIC-3 305 (v3.0): KVM/QEMU и libvirt, Xen, образы дисков, контейнеры (namespaces/cgroups, LXC/LXD, Docker), оркестрация (Compose, Swarm, Kubernetes, Helm), Vagrant/Packer/cloud-init.
Ответить
Аватара пользователя
Sergey_Sysadmin
Сообщения: 134
Зарегистрирован: 11 май 2026, 05:31

Оркестрация контейнеров

Сообщение Sergey_Sysadmin »

Оглавление курса (16)
  1. Введение в LPIC-3 305: виртуализация и контейнеризация
  2. Концепции и теория виртуализации [351.1]
  3. Xen [351.2]
  4. QEMU и KVM [351.3]
  5. Управление ВМ через libvirt [351.4, часть 1]
  6. libvirt: виртуальные сети и пулы хранилищ [351.4, часть 2]
  7. Управление образами дисков ВМ [351.5]
  8. Концепции контейнеризации [352.1]
  9. LXC и LXD [352.2]
  10. Docker: образы и контейнеры [352.3, часть 1]
  11. Docker: тома, сети, логирование, ресурсы [352.3, часть 2]
  12. Оркестрация контейнеров (вы здесь)
  13. Облачные инструменты: OpenStack и Terraform [353.1]
  14. Packer [353.2]
  15. cloud-init [353.3]
  16. Vagrant [353.4]
Урок 11. Оркестрация контейнеров

Запустить один контейнер через podman run или docker run вы уже умеете. Но реальная задача администратора другая: поднять десяток связанных сервисов (приложение, база, кеш, очередь), дать им общую сеть, постоянное хранилище, настроить рестарт при падении, а потом размазать это по нескольким хостам так, чтобы выживала смерть узла. Этим занимается оркестратор. В этом уроке разберём четыре уровня: Docker Compose для одного хоста, Docker Swarm для небольшого кластера, Kubernetes для большого, и Helm как пакетный менеджер поверх Kubernetes. Главная мысль урока - понимать, какой инструмент под какую задачу, а не тащить Kubernetes туда, где хватает compose-файла.

Изображение

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

Оркестрация - это переход от императива к декларативу. Вы не пишете последовательность команд "создай сеть, запусти базу, дождись её, запусти приложение". Вы описываете желаемое состояние в YAML, а оркестратор сам приводит систему к нему и удерживает в нём. Это и есть reconciliation loop: процесс постоянно сравнивает "что есть" с "что должно быть" и устраняет разницу.

Docker Compose - самый простой уровень. Это один хост и один файл compose.yaml. Compose читает описание сервисов и за вас создаёт сеть, тома и контейнеры в правильном порядке. По спецификации Compose (актуальная редакция 2026 года) ключ version в начале файла больше не нужен и считается устаревшим. Compose не даёт отказоустойчивости между машинами - умер хост, умерло всё. Это инструмент разработки и небольших одиночных прод-серверов.

Docker Swarm - встроенный в Docker Engine кластерный режим. Несколько узлов объединяются в swarm: менеджеры держат состояние через распределённый Raft-лог, воркеры крутят задачи. Вы запускаете не контейнер, а сервис с желаемым числом реплик, и Swarm раскидывает их по узлам, перезапускает при падении и балансирует через встроенный routing mesh. Порог входа низкий, синтаксис тот же стек compose-файлов. Но проект давно в режиме поддержки без активного развития.

Kubernetes (k8s) - индустриальный стандарт. Минимальная единица запуска - под (pod), один или несколько контейнеров с общим сетевым namespace и томами. Подами вы напрямую не управляете: их создаёт Deployment, который держит нужное число реплик через ReplicaSet и умеет катить обновления без простоя. Доступ к подам даёт Service - стабильный виртуальный IP и DNS-имя поверх меняющихся подов. Namespace - логическая изоляция объектов внутри кластера (dev, prod, команды) с квотами и правами. За всем этим стоит API-сервер, etcd как хранилище состояния и контроллеры, крутящие тот самый reconciliation loop.

Helm - пакетный менеджер Kubernetes. Чарт - это параметризованный набор шаблонов манифестов плюс values.yaml со значениями по умолчанию. Helm рендерит шаблоны и ставит результат как единый release, который можно обновлять и откатывать. Helm 4 (ноябрь 2025) перешёл на server-side apply и новую систему плагинов, при этом чарты Helm 3 работают без переделки.

Команды и примеры

Минимальный compose.yaml с приложением, базой, сетью и томом:

Код: Выделить всё

services:
  web:
    image: nginx:1.27
    ports:
      - "8080:80"
    networks: [front]
    depends_on:
      db:
        condition: service_healthy
  db:
    image: postgres:17
    environment:
      POSTGRES_PASSWORD: secret
    volumes:
      - pgdata:/var/lib/postgresql/data
    networks: [front]
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      retries: 5

volumes:
  pgdata:
networks:
  front:
Запуск и управление (Compose v2 - это плагин docker, пишется через пробел; старый docker-compose через дефис удалён):

Код: Выделить всё

docker compose up -d
docker compose ps
docker compose logs -f web
docker compose down -v   # -v удалит и тома
В Debian/Ubuntu и в RHEL/Fedora пакет одинаков - это плагин docker-compose-plugin из репозитория Docker. Podman-аналог - утилита podman-compose или встроенный podman kube play.

Docker Swarm - кластер из узлов и сервис с репликами:

Код: Выделить всё

docker swarm init --advertise-addr 192.168.10.5
docker swarm join-token worker          # покажет команду для воркеров
docker node ls
docker service create --name web --replicas 3 -p 80:80 nginx:1.27
docker service scale web=5
docker stack deploy -c compose.yaml app  # деплой целого стека
Kubernetes - то же приложение декларативно. Deployment плюс Service:

Код: Выделить всё

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
  namespace: shop
spec:
  replicas: 3
  selector:
    matchLabels: { app: web }
  template:
    metadata:
      labels: { app: web }
    spec:
      containers:
        - name: web
          image: nginx:1.27
          ports: [ { containerPort: 80 } ]
---
apiVersion: v1
kind: Service
metadata:
  name: web
  namespace: shop
spec:
  selector: { app: web }
  ports:
    - port: 80
      targetPort: 80
Базовые команды kubectl:

Код: Выделить всё

kubectl create namespace shop
kubectl apply -f web.yaml
kubectl get pods -n shop -o wide
kubectl scale deployment web --replicas=5 -n shop
kubectl rollout status deployment/web -n shop
kubectl rollout undo deployment/web -n shop   # откат версии
Helm - установка и обновление чарта с переопределением значений:

Код: Выделить всё

helm repo add bitnami https://charts.bitnami.com/bitnami
helm install shop bitnami/nginx -n shop --create-namespace \
     --set replicaCount=3
helm upgrade shop bitnami/nginx -n shop --set replicaCount=5
helm rollback shop 1 -n shop
helm list -n shop
kubectl и helm ставятся одинаково из официальных репозиториев на обоих семействах: apt install для Debian/Ubuntu, dnf install для RHEL/Fedora, либо как статические бинарники.

Частые грабли
  • depends_on в Compose без condition ждёт только запуска контейнера, а не готовности сервиса. База ещё инициализируется, а приложение уже ломится к ней. Нужен healthcheck плюс service_healthy.
  • down -v молча сносит именованные тома вместе с данными. На проде про флаг -v надо помнить отдельно.
  • В Swarm ключи build, depends_on и profiles из compose-файла игнорируются - stack deploy умеет не всё, что docker compose up.
  • Чётное число менеджеров в Swarm не повышает отказоустойчивость Raft, а иногда вредит кворуму. Держите 3 или 5 менеджеров, не 2 и не 4.
  • Service в Kubernetes не видит поды, если labels в селекторе не совпали с labels в шаблоне пода буква в букву. Трафик молча уходит в никуда.
  • latest как тег образа - источник невоспроизводимых деплоев. В манифестах и чартах всегда фиксируйте версию.
  • helm install при упавшем релизе оставляет его в статусе failed, и повторная установка спотыкается. Чистите helm uninstall или используйте upgrade --install.
Мини-лаба
  • На одном хосте напишите compose.yaml из примера, поднимите docker compose up -d, убедитесь через docker compose ps, что web стартовал только после healthy базы.
  • Проверьте сохранность данных: создайте таблицу в postgres, сделайте docker compose down без -v, поднимите заново и убедитесь, что данные на месте.
  • Инициализируйте Swarm на этом же хосте (swarm init), сконвертируйте стек через docker stack deploy и масштабируйте web до 4 реплик.
  • Поднимите учебный кластер Kubernetes: kind или minikube. Примените Deployment и Service из урока в namespace shop.
  • Сломайте под намеренно (kubectl delete pod) и понаблюдайте kubectl get pods -w, как Deployment поднимает замену.
  • Установите тот же nginx через Helm, переопределив replicaCount, затем сделайте upgrade и rollback, сверяя helm history.
Контрольные вопросы
  • Чем под Kubernetes отличается от контейнера и зачем в одном поде держать несколько контейнеров?
  • Какая цепочка объектов обеспечивает заданное число реплик и плавное обновление: Deployment, ReplicaSet, под - кто кого создаёт?
  • Как Service находит свои поды и что произойдёт при несовпадении labels селектора?
  • Почему рекомендуют нечётное число узлов-менеджеров в Swarm и как это связано с Raft?
  • Что именно делает Helm с чартом при install и чем release отличается от чарта?
  • В каких сценариях Docker Compose достаточно, а где обоснован переход на Kubernetes?
👍2 ❤️5 🔥2 😄 🤔
Аватара пользователя
grpc9
Сообщения: 1
Зарегистрирован: 01 июн 2026, 13:09

Re: Оркестрация контейнеров

Сообщение grpc9 »

А если у меня всего три сервиса на одном VPS, есть смысл городить k8s или хватит compose с restart: always? Пока не вижу выгоды кроме хайпа.
👍1 ❤️1 🔥 😄 🤔2
Аватара пользователя
nixos2003
Сообщения: 1
Зарегистрирован: 15 май 2026, 21:18

Re: Оркестрация контейнеров

Сообщение nixos2003 »

Поймал ровно те грабли с depends_on: контейнер базы up, а приложение падает с connection refused. Спас condition: service_healthy плюс healthcheck с pg_isready, спасибо что разжевали.
👍1 ❤️ 🔥1 😄 🤔
Ответить
← Предыдущая глава
Docker: тома, сети, логирование, ресурсы [352.3, часть 2]
Следующая глава →
Облачные инструменты: OpenStack и Terraform [353.1]

Все главы курса «LPIC-3 305: виртуализация и контейнеризация»

Поделиться темой: ✈ Telegram VK

Вернуться в «LPIC-3 305: виртуализация и контейнеры»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость