Использование Compose и Swarm

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

Фактическая степень интеграции зависит от того какую версию формата Compose файла вы используете:

  1. Если вы используете 1 версию вместе с links, ваше приложение будет работать, но Swarm будет размещать все контейнеры на одном хосте, по тому что ссылки между контейнерами не работают через хосты со старой системой сети.

  2. Если вы используете версию 2, ваше приложение будет работать без изменений:

    • с учетом ограничений описанных ниже,

    • с момента настройки Swarm кластера используйте драйвер наложения, или кастомный драйвер поддерживающий работу между хостами.

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

$ eval "$(docker-machine env --swarm <name of swarm master machine>)"
$ docker-compose up

Ограничения

Сборка образов

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

Если вы хотите использовать Compose для масштабирования сервиса на нескольких узлах, вы должны самостоятельно собрать образ, выложить его в реестр (например Docker Hub) и прописать в docker-compose.yml:

$ docker build -t myusername/web .
$ docker push myusername/web

$ cat docker-compose.yml
web:
  image: myusername/web

$ docker-compose up -d
$ docker-compose scale web=3

Множественные зависимости

Если сервис имеет несколько зависимостей, типа требующего совместного размещения (читайте про автоматическое размещение ниже), возможно что Swarm разместит зависимости на разных нодах, делая невозможным размещение зависимого сервиса. Например, foo должен быть размещен совместно с bar и baz:

version: "2"
services:
  foo:
    image: foo
    volumes_from: ["bar"]
    network_mode: "service:baz"
  bar:
    image: bar
  baz:
    image: baz

The problem is that Swarm might first schedule bar и baz на различных нодах (since they’re not dependent on one another), making it impossible to pick an appropriate node for foo.

ручное размещение для того чтобы быть уверенным что все три сервиса размещены на одной ноде:

version: "2"
services:
  foo:
    image: foo
    volumes_from: ["bar"]
    network_mode: "service:baz"
    environment:
      - "constraint:node==node-1"
  bar:
    image: bar
    environment:
      - "constraint:node==node-1"
  baz:
    image: baz
    environment:
      - "constraint:node==node-1"

Порты хоста и пересоздание контейнеров

Если сервис сопоставляет порт с хостом, например 80:8000, то при выполнении команды docker-compose up во второй раз вы можете получить ошибку похожую на эту:

docker: Error response from daemon: unable to find a node that satisfies
container==6ab2dfe36615ae786ef3fc35d641a260e3ea9663d6e69c5b70ce0ca6cb373c02.

Как правило причиной данной ошибки является то что контейнер имеет том данных (заданный в образе или файле Compose) без явного отображения, по этому что бы сохранить данные, Compose дает указание Swarm разместить новый контейнер на той же ноде где был старый контейнер. Это приводит к конфликту порта.

Существует два пути решения данной проблемы:

  • Задать именованный том данных и использовать драйвер тома который способен монтировать том в контейнер вне зависимости от того на какой ноде он размещен.

    Compose не передает Swarm каких либо специальных инструкций размещения если сервис использует только именованные тома.

    version: "2"
    
    services:
      web:
        build: .
        ports:
          - "80:8000"
        volumes:
          - web-logs:/var/log/web
    
    volumes:
      web-logs:
        driver: custom-volume-driver
    
  • Удалить старый контейнер перед созданием нового.Вы потеряете все данные в томе.

    $ docker-compose stop web
    $ docker-compose rm -f web
    $ docker-compose up web
    

Размещение контейнеров

Автоматическое размещение

Некоторые параметры конфигурации приводят к тому что для корректной работы контейнеры автоматически размещаются на одной Swarm ноде. Вот они:

  • network_mode: "service:..." и network_mode: "container:..."net: "container:..."в 1 версии формата файла docker-compose.yml).

  • volumes_from

  • links

Ручное размещение

Swarm предлагает богатый набор возможностей по управлению размещением контейнеров. Они задаются в переменных окружения контейнера, так что вы можете использовать в Compose опцию environment.

# Schedule containers on a specific node
environment:
  - "constraint:node==node-1"

# Schedule containers on a node that has the 'storage' label set to 'ssd'
environment:
  - "constraint:storage==ssd"

# Schedule containers where the 'redis' image is already pulled
environment:
  - "affinity:image==redis"

Полный набор доступных фильтров и выражений можно найти в документации по Swarm.


Комментарии:

Комментариев нет, желаете стать первым?

Пожалуйста, авторизуйтесь что бы оставлять комментарии.