Docker: Swarm mode, Compose и scaling

Автор: | 03/11/2017
 

Быстрый пример запуска и управления сервисами в Docker Swarm.

Имеется две VM в Azure.

Master setup

Подключаемся к Мастеру:

ssh setevoy@23.97.132.113
...
setevoy@jm-sw-arseny-test-1-master:~$

Устанавливаем Docker:

sudo curl https://get.docker.com/ | sudo bash

Добавляем пользователя в группу docker:

sudo usermod -aG docker setevoy

Перелогиниваемся, поверяем:

docker info
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 0
Server Version: 17.03.0-ce
...

Инициализируем Swarm-менеджер:

setevoy@jm-sw-arseny-test-1-master:~$ docker swarm init
Swarm initialized: current node (w4md2hvsyj8sqez8gutv4m8dz) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join \
--token SWMTKN-1-259al7lgdwymdbr3ciyfixphxtxngwbwxhcsfwn7eceh8rg9se-bgrklm5tm0aqrw71l592x1bpu \
172.16.1.4:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

Тут Docker:

  • переключает текущую нодув редим swarm mode;
  • создаёт ферму с именем default.
  • устанавливает текущую ноду как управляющий менеджер для всей фермы;
  • задаёт ноде имя хоста;
  • настраивает менеджер на прослушиваение порта 2377;
  • устанавливает ноде режим Active, что бы она могла принимать задачи от планирощика;
  • создаёт самоподписанный roto CA для фермы;
  • создаёт токены для воркеров и других менеджер-нод;
  • создаёт overlay-сеть с именем ingress для маппинга портов сервисов.

Проверяем порт 2377 — на него Swarm-master будет принимать запросы от нод:

setevoy@jm-sw-arseny-test-1-master:~$ sudo netstat -anp | grep 2377
tcp        0      0 127.0.0.1:37066         127.0.0.1:2377          ESTABLISHED 5417/dockerd
tcp6       0      0 :::2377                 :::*                    LISTEN      5417/dockerd
tcp6       0      0 127.0.0.1:2377          127.0.0.1:37066         ESTABLISHED 5417/dockerd

Node

Про ноды — читать тут>>>.

Подготавливаем, как и мастер:

16:29:59 [setevoy@setevoy-arch-work ~]  $ ssh setevoy@40.68.220.180
setevoy@jm-sw-arseny-test-1-node:~$ sudo curl https://get.docker.com/ | sudo bash
setevoy@jm-sw-arseny-test-1-node:~$ sudo usermod -aG docker your-user

На мастере — вызываем join-token worker, что бы получить ключ авторизации:

setevoy@jm-sw-arseny-test-1-master:~$ docker swarm join-token worker
To add a worker to this swarm, run the following command:
docker swarm join \
--token SWMTKN-1-3q5vffsb4b8c168q9m7x93z8cmbcrccpknx69nc87c8c3u0xn9-dksfajolcnqrccapmb2bp6qlf \
172.16.1.4:2377

На ноде — выполняем подключение:

setevoy@jm-sw-arseny-test-1-node:~$ docker swarm join \
>     --token SWMTKN-1-3q5vffsb4b8c168q9m7x93z8cmbcrccpknx69nc87c8c3u0xn9-dksfajolcnqrccapmb2bp6qlf \
>     172.16.1.4:2377
This node joined a swarm as a worker.

С помощью node — проверяем машины в ферме:

setevoy@jm-sw-arseny-test-1-master:~$ docker node ls
ID                           HOSTNAME                    STATUS  AVAILABILITY  MANAGER STATUS
96xrngmjobhuatin7qbwib1j3    jm-sw-arseny-test-1-node    Ready   Active
q35n6wiqw8fnsvxhzskb2uavp *  jm-sw-arseny-test-1-master  Ready   Active        Leader

Получить детали о ноде — inspect:

setevoy@jm-sw-arseny-test-1-master:~$ docker node inspect 96xrngmjobhuatin7qbwib1j3
[
{
"ID": "96xrngmjobhuatin7qbwib1j3",
"Version": {
"Index": 15
},
"CreatedAt": "2017-03-10T16:12:34.463028369Z",
"UpdatedAt": "2017-03-10T16:12:34.616122003Z",
"Spec": {
"Role": "worker",
"Availability": "active"
},
"Description": {
"Hostname": "jm-sw-arseny-test-1-node",
"Platform": {
"Architecture": "x86_64",
"OS": "linux"
},
...

Добавление сервиса

Читать тут>>>.

Для запуска любого сервиса — достаточно выполнить service create, например:

setevoy@jm-sw-arseny-test-1-master:~$ docker service create --name lb_nginx nginx
tigighh2xhv1etvcgtkjkweq8

Проверяем:

setevoy@jm-sw-arseny-test-1-master:~$ docker service ls
ID            NAME      MODE        REPLICAS  IMAGE
tigighh2xhv1  lb_nginx  replicated  1/1       nginx:latest

Состояние нод:

setevoy@jm-sw-arseny-test-1-master:~$ docker node ps
ID            NAME        IMAGE         NODE                        DESIRED STATE  CURRENT STATE           ERROR  PORTS
q0ephywt8ek6  lb_nginx.1  nginx:latest  jm-sw-arseny-test-1-master  Running        Running 27 seconds ago

Сервис запущен на одной ноде.

Для того, что бы Swarm замасштабировал сервис на другие ноды — используем service scale:

setevoy@jm-sw-arseny-test-1-master:~$ docker service scale tigighh2xhv1=2
tigighh2xhv1 scaled to 2

Где tigighh2xhv1 — ID из результатов docker service ls.

Проверяем:

setevoy@jm-sw-arseny-test-1-master:~$ docker service ls
ID            NAME      MODE        REPLICAS  IMAGE
tigighh2xhv1  lb_nginx  replicated  2/2       nginx:latest

Проверяем на второй ноде. Находим ID ноды:

setevoy@jm-sw-arseny-test-1-master:~$ docker node ls
ID                           HOSTNAME                    STATUS  AVAILABILITY  MANAGER STATUS
96xrngmjobhuatin7qbwib1j3    jm-sw-arseny-test-1-node    Ready   Active
q35n6wiqw8fnsvxhzskb2uavp *  jm-sw-arseny-test-1-master  Ready   Active        Leader

Проверяем процессы на ней:

setevoy@jm-sw-arseny-test-1-master:~$ docker node ps 96xrngmjobhuatin7qbwib1j3
ID            NAME        IMAGE         NODE                      DESIRED STATE  CURRENT STATE               ERROR  PORTS
1z7sblrovq51  lb_nginx.2  nginx:latest  jm-sw-arseny-test-1-node  Running        Running about a minute ago

И он же — на мастере:

setevoy@jm-sw-arseny-test-1-master:~$ docker node ps q35n6wiqw8fnsvxhzskb2uavp
ID            NAME        IMAGE         NODE                        DESIRED STATE  CURRENT STATE          ERROR  PORTS
q0ephywt8ek6  lb_nginx.1  nginx:latest  jm-sw-arseny-test-1-master  Running        Running 5 minutes ago

Настройки нод

Сейчас контейнер с NGINX не принимает никаких соединений — порты закрыты.

Что бы открыть порты во время создания сервиса — используем опцию --publish:

setevoy@jm-sw-arseny-test-1-master:~$ docker service create --name lb_nginx_80 --publish 80:80 --replicas 2 nginx
ht0vp3go1cm5yip2gl7g7dcc7

--replicas 2 — запустить сервис сразу на обеих нодах.

Проверяем:

setevoy@jm-sw-arseny-test-1-master:~$ curl localhost
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...

Сервисы на нодах:

setevoy@jm-sw-arseny-test-1-master:~$ docker node ls
ID                           HOSTNAME                    STATUS  AVAILABILITY  MANAGER STATUS
96xrngmjobhuatin7qbwib1j3    jm-sw-arseny-test-1-node    Ready   Active
q35n6wiqw8fnsvxhzskb2uavp *  jm-sw-arseny-test-1-master  Ready   Active        Leader

setevoy@jm-sw-arseny-test-1-master:~$ docker node ps q35n6wiqw8fnsvxhzskb2uavp
ID            NAME           IMAGE         NODE                        DESIRED STATE  CURRENT STATE           ERROR  PORTS
q0ephywt8ek6  lb_nginx.1     nginx:latest  jm-sw-arseny-test-1-master  Running        Running 11 minutes ago
n7wr3fpgtx2v  lb_nginx_80.2  nginx:latest  jm-sw-arseny-test-1-master  Running        Running 52 seconds ago

setevoy@jm-sw-arseny-test-1-master:~$ docker node ps q35n6wiqw8fnsvxhzskb2uavp
ID            NAME           IMAGE         NODE                        DESIRED STATE  CURRENT STATE               ERROR  PORTS
q0ephywt8ek6  lb_nginx.1     nginx:latest  jm-sw-arseny-test-1-master  Running        Running 11 minutes ago
n7wr3fpgtx2v  lb_nginx_80.2  nginx:latest  jm-sw-arseny-test-1-master  Running        Running about a minute ago

И останавливаем первый запущенный сервис:

setevoy@jm-sw-arseny-test-1-master:~$ docker service rm tigighh2xhv1
tigighh2xhv1

Проверяем:

setevoy@jm-sw-arseny-test-1-master:~$ docker service ls
ID            NAME         MODE        REPLICAS  IMAGE
ht0vp3go1cm5  lb_nginx_80  replicated  2/2       nginx:latest

Масшабирование с Docker Compose

Устанавливаем Docker Compose:

root@jm-sw-arseny-test-1-master:~# curl -L https://github.com/docker/compose/releases/download/1.11.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
root@jm-sw-arseny-test-1-master:~# chmod +x /usr/local/bin/docker-compose
root@jm-sw-arseny-test-1-master:~# /usr/local/bin/docker-compose -v
docker-compose version 1.11.2, build dfed245

Создадим простой compose-файл:

version: '3'
services:
  web:
    image: "nginx"
    ports:
     - "80:80"

Обратите внимание на версию:

version: ‘3’

Потребуется для docker stack deploy ниже.

Запускаем:

setevoy@jm-sw-arseny-test-1-master:~$ docker-compose up -d
WARNING: The Docker Engine you're using is running in swarm mode.
Compose does not use swarm mode to deploy services to multiple nodes in a swarm. All containers will be scheduled on the current node.
To deploy your application across the swarm, use `docker stack deploy`.
Starting setevoy_web_1

Проверяем:

setevoy@jm-sw-arseny-test-1-master:~$ docker-compose ps
Name              Command          State              Ports
--------------------------------------------------------------------------
setevoy_web_1   nginx -g daemon off;   Up      443/tcp, 0.0.0.0:80->80/tcp

На нодах Swarm-а — сервисы не запущены:

setevoy@jm-sw-arseny-test-1-master:~$ docker node ps q35n6wiqw8fnsvxhzskb2uavp
ID  NAME  IMAGE  NODE  DESIRED STATE  CURRENT STATE  ERROR  PORTS
setevoy@jm-sw-arseny-test-1-master:~$ docker node ps 96xrngmjobhuatin7qbwib1j3
ID  NAME  IMAGE  NODE  DESIRED STATE  CURRENT STATE  ERROR  PORTS

Стопаем compose:

setevoy@jm-sw-arseny-test-1-master:~$ docker-compose down
Stopping setevoy_web_1 ... done
Removing setevoy_web_1 ... done
Removing network setevoy_default

С помощью docker stack deploy — деплоим сервис:

setevoy@jm-sw-arseny-test-1-master:~$ docker stack deploy -c docker-compose.yml lb_nginx
Creating network lb_nginx_default
Creating service lb_nginx_web

Проверяем:

setevoy@jm-sw-arseny-test-1-master:~$ docker stack services lb_nginx
ID            NAME          MODE        REPLICAS  IMAGE
wpe7whxqnods  lb_nginx_web  replicated  1/1       nginx:latest

Обратите внимание, что REPLICAS 1/1, сервис запущен только на мастере:

setevoy@jm-sw-arseny-test-1-master:~$ docker node ps q35n6wiqw8fnsvxhzskb2uavp
ID            NAME            IMAGE         NODE                        DESIRED STATE  CURRENT STATE           ERROR  PORTS
ksthn3r0yu3v  lb_nginx_web.1  nginx:latest  jm-sw-arseny-test-1-master  Running        Running 28 seconds ago

Но на второй ноде — ничего:

setevoy@jm-sw-arseny-test-1-master:~$ docker node ps 96xrngmjobhuatin7qbwib1j3
ID  NAME  IMAGE  NODE  DESIRED STATE  CURRENT STATE  ERROR  PORTS

Скейлим сервис:

setevoy@jm-sw-arseny-test-1-master:~$ docker service scale lb_nginx_web=2
lb_nginx_web scaled to 2

Проверяем ноды:

setevoy@jm-sw-arseny-test-1-master:~$ docker service ps lb_nginx_web
ID            NAME            IMAGE         NODE                        DESIRED STATE  CURRENT STATE               ERROR  PORTS
ksthn3r0yu3v  lb_nginx_web.1  nginx:latest  jm-sw-arseny-test-1-master  Running        Running 2 minutes ago
tj0dmku1r8di  lb_nginx_web.2  nginx:latest  jm-sw-arseny-test-1-node    Running        Running about a minute ago

Последнее, что стоит показать — использование мастер-ноды в роли только менеджера, без запуска сервисов на нём.

Сейчас обе ноды могут запускать новые контейнеры.

Добавим ещё одну ноду, и переведём Мастер в режим только менеджера.

Заводим ещё одну машину:

Сетапим её:

ssh setevoy@52.166.4.130
...
setevoy@jm-sw-arseny-test-2-node:~$ sudo curl https://get.docker.com/ | sudo bash
...
setevoy@jm-sw-arseny-test-2-node:~$ sudo usermod -aG docker setevoy

На местере получаем токен:

setevoy@jm-sw-arseny-test-1-master:~$ docker swarm join-token worker
To add a worker to this swarm, run the following command:
docker swarm join \
--token SWMTKN-1-3q5vffsb4b8c168q9m7x93z8cmbcrccpknx69nc87c8c3u0xn9-dksfajolcnqrccapmb2bp6qlf \
172.16.1.4:2377

На новой ноде — подключаемся:

setevoy@jm-sw-arseny-test-2-node:~$ docker swarm join --token SWMTKN-1-3q5vffsb4b8c168q9m7x93z8cmbcrccpknx69nc87c8c3u0xn9-dksfajolcnqrccapmb2bp6qlf 172.16.1.4:2377
This node joined a swarm as a worker.

На мастере проверяем:

setevoy@jm-sw-arseny-test-1-master:~$ docker node ls
ID                           HOSTNAME                    STATUS  AVAILABILITY  MANAGER STATUS
96xrngmjobhuatin7qbwib1j3    jm-sw-arseny-test-1-node    Ready   Active
q35n6wiqw8fnsvxhzskb2uavp *  jm-sw-arseny-test-1-master  Ready   Active        Leader
zdz4mni0bndah9aq0phdazibb    jm-sw-arseny-test-2-node    Ready   Active

Стопаем сервис:

setevoy@jm-sw-arseny-test-1-master:~$ docker service ls
ID            NAME          MODE        REPLICAS  IMAGE
wpe7whxqnods  lb_nginx_web  replicated  4/4       nginx:latest

setevoy@jm-sw-arseny-test-1-master:~$ docker service rm lb_nginx_web
lb_nginx_web

Устанавливаем для мастера availability drain:

setevoy@jm-sw-arseny-test-1-master:~$ docker node update --help
Usage:  docker node update [OPTIONS] NODE
Update a node
Options:
--availability string   Availability of the node (active/pause/drain)
--help                  Print usage
--label-add list        Add or update a node label (key=value) (default [])
--label-rm list         Remove a node label if exists (default [])
--role string           Role of the node (worker/manager)

setevoy@jm-sw-arseny-test-1-master:~$ docker node update --availability drain q35n6wiqw8fnsvxhzskb2uavp
q35n6wiqw8fnsvxhzskb2uavp

Проверяем (колонка AVAILABILITY):

setevoy@jm-sw-arseny-test-1-master:~$ docker node ls
ID                           HOSTNAME                    STATUS  AVAILABILITY  MANAGER STATUS
96xrngmjobhuatin7qbwib1j3    jm-sw-arseny-test-1-node    Ready   Active
q35n6wiqw8fnsvxhzskb2uavp *  jm-sw-arseny-test-1-master  Ready   Drain         Leader
zdz4mni0bndah9aq0phdazibb    jm-sw-arseny-test-2-node    Ready   Active

Запускаем сервис:

setevoy@jm-sw-arseny-test-1-master:~$ docker stack deploy -c docker-compose.yml lb_nginx
Creating service lb_nginx_web

Проверяем:

setevoy@jm-sw-arseny-test-1-master:~$ docker service ls
ID            NAME          MODE        REPLICAS  IMAGE
y64pm6gpjwhn  lb_nginx_web  replicated  1/1       nginx:latest

setevoy@jm-sw-arseny-test-1-master:~$ docker service ps lb_nginx_web
ID            NAME            IMAGE         NODE                      DESIRED STATE  CURRENT STATE               ERROR  PORTS
l8eb99wz4nzo  lb_nginx_web.1  nginx:latest  jm-sw-arseny-test-1-node  Running        Running about a minute ago

Запущен только на ноде1. Масштабируем севрис:

setevoy@jm-sw-arseny-test-1-master:~$ docker service scale lb_nginx_web=2
lb_nginx_web scaled to 2

Проверяем:

docker service ps lb_nginx_web
ID            NAME            IMAGE         NODE                      DESIRED STATE  CURRENT STATE            ERROR  PORTS
l8eb99wz4nzo  lb_nginx_web.1  nginx:latest  jm-sw-arseny-test-1-node  Running        Running 2 minutes ago
ieh41le96ix1  lb_nginx_web.2  nginx:latest  jm-sw-arseny-test-2-node  Running        Preparing 2 seconds ago

Другой способ запускать сервисы сразу на нескольких нодах — указать желаемое кол-во репликаций в compose-файле.

Стопаем сервис:

setevoy@jm-sw-arseny-test-1-master:~$ docker service rm lb_nginx_web
lb_nginx_web

Редактируем docker-compose.yml, и добавляем replicas:

version: '3'
services:
  web:
    image: "nginx"
    ports:
     - "80:80"
    deploy:
      mode: replicated
      replicas: 2

Запускаем:

setevoy@jm-sw-arseny-test-1-master:~$ docker stack deploy -c docker-compose.yml lb_nginx
Creating service lb_nginx_web

Проверяем:

setevoy@jm-sw-arseny-test-1-master:~$ docker service ps lb_nginx_web
ID            NAME            IMAGE         NODE                      DESIRED STATE  CURRENT STATE          ERROR  PORTS
xgctl5unz6ce  lb_nginx_web.1  nginx:latest  jm-sw-arseny-test-2-node  Running        Running 2 seconds ago
vv0eka00whg0  lb_nginx_web.2  nginx:latest  jm-sw-arseny-test-1-node  Running        Running 3 seconds ago

Собственно, на этом всё.

P.S. Docker Swarm и авторизация в приватных репозиториях. Добавьте —with-registry-auth :

setevoy@jm-sw-arseny-test-1-master:~$ docker stack deploy -c docker-compose.yml jm-website --with-registry-auth 

Updating service jm-website_web_preview (id: ozkh2himygik03jj0e6xxgxnx)
Updating service jm-website_transform (id: f19hyqrsdw762rp2c901ls7g3)
Updating service jm-website_transform_preview (id: s0uuw1zhurhq2j3lcn4mc5boz)
Updating service jm-website_web (id: omkkmp3or5hfdd51np3sm7xw1)

Почитать по Swarm

Swarm mode key concepts

How nodes work

How services work

Administer and maintain a swarm of Docker Engines

Introduction to Docker Swarm Mode and Multi-Host Networking

По Compose

Compose file version 3 reference

Docker compose v3 example