Развертывание реплик в определенных портах и имени хоста

#docker #docker-compose #docker-swarm

#docker #docker-создать #docker-swarm

Вопрос:

Мне нужно развернуть контейнер docker в рое. Я хочу развернуть 4 копии контейнера docker. Я хочу установить порт, на котором будет работать каждый контейнер, и мне нужно знать их имя хоста.

Я бы хотел отобедать 4 репликами.

  • Реплика 1 должна прослушивать порт 3001 и имя хоста slave1.
  • Реплика 2 должна прослушивать порт 3002 и имя хоста slave2.
  • Реплика 3 должна прослушивать порт 3003 и имя хоста slave3.
  • Реплика 4 должна прослушивать порт 3004 и имя хоста slave4.

Каждая реплика имеет один и тот же файл Dockerfile (потому что процесс, который я хочу запустить, один и тот же). В Dockerfile я предоставляю все 4 порта, используя стандартную команду: ВЫСТАВИТЬ 3001 3002 3003 3004

Я попробовал этот файл docker-compose, в котором я использую 4 порта и развертываю с помощью «mode: replicated»

 services:
  slave:
    image: "DOCKER_REPO_NAME"
    deploy:
      mode: replicated
      replicas: 4
      restart_policy: 
        condition: on-failure
    networks:
      - my_net
    ports:
      - "3001:3001"
      - "3002:3002"
      - "3003:3003"
      - "3004:3004"

networks:
  my_net:
    external: true 
  

но это работает не так, как я хотел бы, и как описано выше.

Надеюсь, описание проблемы имеет смысл. Пожалуйста, дайте мне знать.

Ответ №1:

Я думаю, вы неправильно понимаете режим docker swarm соответственно тому, как он должен работать. Режим Swarm не работает на уровне контейнера / узла, но он на один уровень абстракции выше — он работает со службами.

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

Большим преимуществом режима swarm является то, что вам не нужно ничего знать об инфраструктуре swarm. Вам все равно, какие узлы есть и какой контейнер запущен на каком узле.

Вместо этого вы просто сообщаете swarm, с какой службой вы хотите связаться, и режим swarm решит, в какой контейнер на каком узле он отправит ваш запрос.

Итак, в вашем примере, если ваша служба запущена на порту 3001 и, допустим, есть конечная точка api GET /hello , которую вы бы запросили http://slave:3001/hello . Здесь вступает в игру режим роя, и поскольку он знает, какие контейнеры запущены на каких узлах, он решит, куда будет перенаправлен ваш запрос.

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

 services:
  slave1:
    image: "DOCKER_REPO_NAME"
    deploy:
      mode: replicated
      replicas: 1
      placement:
        constraints:
          - node.labels.type == slave1
      restart_policy: 
        condition: on-failure
    networks:
      - my_net
    ports:
      - "3001:3001"
  slave2:
    image: "DOCKER_REPO_NAME"
    deploy:
      mode: replicated
      replicas: 1
      placement:
        constraints:
          - node.labels.type == slave2
      restart_policy: 
        condition: on-failure
    networks:
      - my_net
    ports:
      - "3002:3001"
  slave3:
    image: "DOCKER_REPO_NAME"
    deploy:
      mode: replicated
      replicas: 1
      placement:
        constraints:
          - node.labels.type == slave3
      restart_policy: 
        condition: on-failure
    networks:
      - my_net
    ports:
      - "3003:3001"
  slave4:
    image: "DOCKER_REPO_NAME"
    deploy:
      mode: replicated
      replicas: 1
      placement:
        constraints:
          - node.labels.type == slave4
      restart_policy: 
        condition: on-failure
    networks:
      - my_net
    ports:
      - "3004:3001"

networks:
  my_net:
    external: true 
  

Но имейте в виду тот факт, что это сводит на нет большую часть преимуществ swarm.

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

1. Я понимаю ваше замечание и спасибо. Я читал статью о «docker service scale», мне непонятно, в чем разница между этой командой и реплицируемым режимом развертывания. Как вы думаете, «масштабирование службы docker» может решить мою проблему?

2. Вы правы — разницы нет. docker service scale myservice=10 такой же, как если бы вы использовали mode: replicated и replicas: 10 . И то, и другое просто влияет на количество запущенных контейнеров для каждой определенной службы.