Как использовать команду docker service create для развертывания и управления службами

DockerDockerBeginner
Практиковаться сейчас

💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал

Введение

В этом практическом занятии (лабораторной работе) вы получите практический опыт использования команды docker service create для развертывания и управления службами в Docker Swarm. Вы научитесь создавать и проверять различные типы служб, включая простые реплицируемые службы для обеспечения высокой доступности и масштабируемости, а также глобальные службы, которые запускаются на каждом узле.

Кроме того, вы изучите расширенные настройки служб, такие как реализация стратегий последовательного обновления для бесперебойного развертывания, использование бинд-монтирований (bind mounts) и переменных окружения для сохранения данных и настройки, а также применение ограничений и предпочтений размещения для контроля того, где выполняются задачи вашей службы в кластере. Завершив эти шаги, вы получите твердое понимание того, как эффективно управлять контейнеризованными приложениями в среде Docker Swarm.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL docker(("Docker")) -.-> docker/ImageOperationsGroup(["Image Operations"]) docker(("Docker")) -.-> docker/ContainerOperationsGroup(["Container Operations"]) docker/ContainerOperationsGroup -.-> docker/run("Run a Container") docker/ContainerOperationsGroup -.-> docker/ls("List Containers") docker/ContainerOperationsGroup -.-> docker/ps("List Running Containers") docker/ContainerOperationsGroup -.-> docker/exec("Execute Command in Container") docker/ContainerOperationsGroup -.-> docker/inspect("Inspect Container") docker/ContainerOperationsGroup -.-> docker/create("Create Container") docker/ImageOperationsGroup -.-> docker/pull("Pull Image from Repository") subgraph Lab Skills docker/run -.-> lab-555224{{"Как использовать команду docker service create для развертывания и управления службами"}} docker/ls -.-> lab-555224{{"Как использовать команду docker service create для развертывания и управления службами"}} docker/ps -.-> lab-555224{{"Как использовать команду docker service create для развертывания и управления службами"}} docker/exec -.-> lab-555224{{"Как использовать команду docker service create для развертывания и управления службами"}} docker/inspect -.-> lab-555224{{"Как использовать команду docker service create для развертывания и управления службами"}} docker/create -.-> lab-555224{{"Как использовать команду docker service create для развертывания и управления службами"}} docker/pull -.-> lab-555224{{"Как использовать команду docker service create для развертывания и управления службами"}} end

Создание простой реплицируемой службы

На этом этапе вы научитесь создавать простую реплицируемую службу в Docker Swarm. Реплицируемая служба - это служба, которая запускает несколько идентичных задач по всему кластеру. Это обеспечивает высокую доступность и масштабируемость.

Сначала убедимся, что Docker запущен и вы находитесь в правильной директории.

docker version
pwd

Вы должны увидеть вывод, показывающий версию Docker и текущую директорию /home/labex/project.

Перед созданием службы нам нужно скачать необходимый Docker-образ. В этом примере мы будем использовать образ nginx.

docker pull nginx:latest

Эта команда загружает последнюю версию образа nginx с Docker Hub.

Теперь создадим простую реплицируемую службу с именем my-nginx-service с 3 репликами.

docker service create --name my-nginx-service --replicas 3 nginx:latest

Эта команда создает новую службу с именем my-nginx-service с использованием образа nginx:latest и устанавливает желаемое количество реплик равным 3. Затем Docker Swarm распределит эти 3 задачи по доступным узлам в кластере.

Чтобы проверить состояние службы и ее задач, вы можете использовать команды docker service ls и docker service ps.

docker service ls
docker service ps my-nginx-service

Команда docker service ls выводит список всех служб, запущенных в кластере, показывая их идентификатор, имя, режим, количество реплик и образ. Команда docker service ps my-nginx-service показывает задачи, связанные со службой my-nginx-service, включая их состояние (например, "Running" - запущено, "Shutdown" - остановлено), желаемое состояние и узел, на котором они запущены. Вы должны увидеть 3 задачи в состоянии "Running".

Создание глобальной службы и проверка ее задач

На этом этапе вы научитесь создавать глобальную службу в Docker Swarm. В отличие от реплицируемых служб, которые запускают определенное количество задач, глобальная служба запускает ровно одну задачу на каждом узле в кластере, который соответствует ограничениям службы. Это полезно для служб, таких как агенты мониторинга или сборщики журналов, которые должны запускаться на каждом узле.

В этом примере мы будем использовать образ busybox. Сначала загрузим этот образ.

docker pull busybox:latest

Эта команда загружает последнюю версию образа busybox.

Теперь создадим глобальную службу с именем my-global-service.

docker service create --name my-global-service --mode global busybox:latest sleep infinity

Эта команда создает новую службу с именем my-global-service с использованием образа busybox:latest. Флаг --mode global указывает, что это глобальная служба. Команда sleep infinity используется для того, чтобы контейнер работал бесконечно.

Для проверки задач глобальной службы вы можете использовать команду docker service ps.

docker service ps my-global-service

Эта команда покажет задачи, связанные со службой my-global-service. Поскольку это глобальная служба, вы должны увидеть по одной задаче, запущенной на каждом узле в вашем кластере. В среде этого практического занятия (лабораторной работы) вы, вероятно, увидите только одну задачу, так как здесь только один узел. Вывод будет показывать состояние задачи, желаемое состояние и узел, на котором она запущена.

Вы также можете проверить конфигурацию службы с помощью команды docker service inspect.

docker service inspect my-global-service

Эта команда предоставляет подробную информацию о службе, включая ее режим, количество реплик (для глобальной службы в списке служб это будет 0, но команда docker service ps покажет задачи на каждый узел) и другие детали конфигурации.

Создание службы с репликами и политикой последовательного обновления

На этом этапе вы научитесь создавать реплицируемую службу и настраивать ее политику последовательного обновления. Последовательные обновления позволяют обновить службу до новой версии без простоя путем постепенного замены задач на новые версии.

Мы продолжим использовать образ nginx. Создадим реплицируемую службу с именем my-nginx-update-service с 5 репликами и политикой последовательного обновления.

docker service create \
  --name my-nginx-update-service \
  --replicas 5 \
  --update-delay 10s \
  --update-parallelism 2 \
  nginx:latest

Эта команда создает службу с следующими настройками:

  • --name my-nginx-update-service: Задает имя службы.
  • --replicas 5: Задает желаемое количество реплик равным 5.
  • --update-delay 10s: Устанавливает задержку между обновлением каждой группы задач в 10 секунд.
  • --update-parallelism 2: Устанавливает количество задач, которые будут обновляться одновременно, равным 2.

Эти параметры обновления определяют, как будет обновляться служба при развертывании новой версии образа. Docker Swarm будет обновлять по 2 задачи за раз, ожидая 10 секунд перед обновлением следующей партии.

Вы можете проверить состояние службы и ее задач с помощью команд docker service ls и docker service ps.

docker service ls
docker service ps my-nginx-update-service

Вы должны увидеть службу my-nginx-update-service в списке с 5 из 5 реплик и задачи в состоянии "Running" (запущен).

Теперь имитируем обновление, изменив образ на другую версию. Мы будем использовать образ nginx:1.21. Сначала загрузим этот образ.

docker pull nginx:1.21

Теперь обновим службу, чтобы она использовала образ nginx:1.21.

docker service update --image nginx:1.21 my-nginx-update-service

Эта команда запускает последовательное обновление. Docker Swarm начнет заменять задачи с nginx:latest на задачи с nginx:1.21 в соответствии с настройками --update-parallelism и --update-delay, которые вы настроили ранее.

Вы можете наблюдать процесс последовательного обновления, многократно запуская команду docker service ps my-nginx-update-service.

docker service ps my-nginx-update-service

Вы увидите, как задачи переходят из состояния "Running" с старым образом в состояние "Shutdown", а затем запускаются новые задачи с новым образом и переходят в состояние "Running". Обновление будет происходить партиями по 2 задачи с задержкой в 10 секунд между партиями.

Создание службы с привязанными томами и переменными окружения

На этом этапе вы научитесь создавать службу, которая использует привязанные тома (bind mounts) для сохранения данных и переменные окружения для настройки приложения внутри контейнера. Привязанные тома позволяют монтировать файл или каталог с хост-машины в контейнер, делая данные доступными для контейнера и сохраняющимися даже при удалении контейнера. Переменные окружения - это распространенный способ передачи конфигурационной информации приложениям.

Сначала создадим каталог на хост-машине, который мы будем монтировать в контейнер.

mkdir -p ~/project/html

Эта команда создает каталог с именем html внутри каталога ~/project.

Теперь создадим простой HTML-файл внутри этого каталога.

echo "<h1>Hello from Bind Mount!</h1>" > ~/project/html/index.html

Эта команда создает файл с именем index.html в каталоге ~/project/html с содержимым "

Hello from Bind Mount!

".

Мы снова будем использовать образ nginx. Создадим реплицируемую службу с именем my-nginx-volume-service с 1 репликой, привязав каталог ~/project/html к стандартному корневому каталогу веб-сервера Nginx внутри контейнера (/usr/share/nginx/html) и установив переменную окружения.

docker service create \
  --name my-nginx-volume-service \
  --replicas 1 \
  --publish published=8080,target=80 \
  --mount type=bind,source=/home/labex/project/html,target=/usr/share/nginx/html \
  --env MY_VARIABLE=hello \
  nginx:latest

Разберем новые параметры:

  • --publish published=8080,target=80: Этот параметр сопоставляет порт 8080 на хост-машине с портом 80 внутри контейнера, позволяя вам доступиться к веб-серверу Nginx с хост-машины.
  • --mount type=bind,source=/home/labex/project/html,target=/usr/share/nginx/html: Этот параметр создает привязанный том. type=bind указывает тип монтирования. source=/home/labex/project/html - это путь на хост-машине. target=/usr/share/nginx/html - это путь внутри контейнера, куда будет монтироваться каталог с хост-машины.
  • --env MY_VARIABLE=hello: Этот параметр устанавливает переменную окружения с именем MY_VARIABLE со значением hello внутри контейнера.

Проверьте статус службы и задачи:

docker service ls
docker service ps my-nginx-volume-service

Подождите, пока задача перейдет в состояние "Running" (запущен).

Теперь вы можете обратиться к веб-серверу Nginx, работающему в контейнере, посетив http://localhost:8080 в веб-браузере или используя curl.

curl http://localhost:8080

Вы должны увидеть содержимое файла index.html, который вы создали: <h1>Hello from Bind Mount!</h1>. Это подтверждает, что привязанный том работает правильно.

Для проверки переменной окружения вы можете выполнить команду внутри работающего контейнера. Сначала найдите идентификатор задачи работающей службы.

docker service ps my-nginx-volume-service

Обратите внимание на идентификатор задачи (Task ID) в выводе. Затем используйте docker exec для выполнения команды внутри контейнера. Замените <task_id> на фактический идентификатор задачи.

docker exec < task_id > env | grep MY_VARIABLE

Эта команда выполняет команду env внутри контейнера, связанного с идентификатором задачи, и передает вывод в grep MY_VARIABLE для поиска переменной окружения. В выводе вы должны увидеть MY_VARIABLE=hello.

Создание службы с ограничениями и предпочтениями размещения

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

Сначала проверим текущий узел, чтобы увидеть его метки (labels). Метки - это пары ключ-значение, которые вы можете прикрепить к узлам для предоставления метаданных.

docker node inspect self --format '{{ .Spec.Labels }}'

Эта команда проверяет текущий узел (идентифицируемый как self) и форматирует вывод для отображения его меток. По умолчанию может не быть каких-либо пользовательских меток.

Добавим метку к текущему узлу. Мы добавим метку node_type=app.

docker node update --label-add node_type=app self

Эта команда обновляет текущий узел и добавляет метку node_type=app.

Теперь проверим, что метка была добавлена.

docker node inspect self --format '{{ .Spec.Labels }}'

В выводе вы должны увидеть map[node_type:app], что указывает на то, что метка была успешно добавлена.

Теперь создадим реплицируемую службу с именем my-constrained-service с ограничением размещения, которое требует, чтобы узел имел метку node_type=app. Мы будем использовать образ nginx.

docker service create \
  --name my-constrained-service \
  --replicas 1 \
  --constraint 'node.labels.node_type == app' \
  nginx:latest

Эта команда создает службу с ограничением. --constraint 'node.labels.node_type == app' указывает, что задачи для этой службы могут быть запланированы только на узлах, где метка node_type равна app. Поскольку мы добавили эту метку к текущему узлу, задача должна быть запланирована здесь.

Проверьте статус службы и задачи:

docker service ls
docker service ps my-constrained-service

Вы должны увидеть службу my-constrained-service в списке и ее задачу, запущенную на текущем узле.

Теперь создадим другую службу с предпочтением размещения. Предпочтения размещения используются для направления планировщика, но не строго применяются. Мы будем использовать образ busybox и предпочтать узлы с меткой node_type=database. Поскольку наш текущий узел не имеет этой метки, задача все равно будет запланирована на текущем узле, но если бы были другие узлы с этой меткой, планировщик бы предпочел их.

Сначала загрузите образ busybox.

docker pull busybox:latest

Теперь создайте службу с предпочтением размещения.

docker service create \
  --name my-preferred-service \
  --replicas 1 \
  --placement-pref 'spread=node.labels.node_type' \
  busybox:latest sleep infinity

Опция --placement-pref 'spread=node.labels.node_type' сообщает планировщику распределять задачи между узлами на основе значения метки node_type. В мультиузельном кластере с разными метками node_type это позволило бы более равномерно распределить задачи. В этом одноузельном окружении задача просто будет запланирована на доступном узле.

Проверьте статус службы и задачи:

docker service ls
docker service ps my-preferred-service

Вы должны увидеть службу my-preferred-service в списке и ее задачу, запущенную на текущем узле.

Резюме

В этом практическом занятии мы научились использовать команду docker service create для развертывания и управления службами в Docker Swarm. Мы начали с создания простой реплицируемой службы с использованием образа nginx, указав желаемое количество реплик для обеспечения высокой доступности и масштабируемости. Затем мы использовали команды docker service ls и docker service ps для проверки статуса службы и изучения ее запущенных задач.

Затем мы рассмотрели создание глобальной службы, поняв, что она запускает по одной задаче на каждом подходящем узле в кластере. Это продемонстрировало гибкость Docker Swarm при развертывании служб в соответствии с разными требованиями.