Шкала Docker с детерминированной привязкой порта

14

Я хотел бы масштабировать wildflyконтейнер, выставив несколько портов с детерминированными результатами.

докер-compose.yml

version: '3'
services:
  wildfly-server:
    build:
      context: .
      dockerfile: Dockerfile
      args:
        admin_user: admin
        admin_password: admin
    deploy:
      resources:
          limits:
            memory: 1.5G
            cpus: "1.5"
    restart: always
    ports:
      - "8000-8099:8080"
      - "8100-8199:9990"
      - "8200-8299:8787"
    expose:
      - "8080"
      - "9990"
      - "8787"

Dockerfile

FROM jboss/wildfly:16.0.0.Final

# DOCKER ENV VARIABLES
ENV WILDFLY_HOME /opt/jboss/wildfly
ENV STANDALONE_DIR ${WILDFLY_HOME}/standalone
ENV DEPLOYMENT_DIR ${STANDALONE_DIR}/deployments
ENV CONFIGURATION_DIR ${STANDALONE_DIR}/configuration

RUN ${WILDFLY_HOME}/bin/add-user.sh ${admin_user} ${admin_password} --silent

# OPENING DEBUG PORT
RUN rm ${WILDFLY_HOME}/bin/standalone.conf
ADD standalone.conf ${WILDFLY_HOME}/bin/

# SET JAVA ENV VARS
RUN rm ${CONFIGURATION_DIR}/standalone.xml
ADD standalone.xml ${CONFIGURATION_DIR}/

Команда для запуска

docker-compose up --build --force-recreate --scale wildfly-server=10

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

machine_1 8001, 8101, 82001
machine_2 8002, 8102, 82002
machine_3 8003, 8103, 82003 

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

machine_1 8001, 8102, 82003
machine_2 8002, 8101, 82001
machine_3 8003, 8103, 82002 

Проблема в том, что каждый раз, когда я запускаю команду compose up, порты различны для каждого контейнера.

Пример вывода:

CONTAINER ID  COMMAND                  CREATED             STATUS              PORTS                                                                    NAMES
0232f24fbca4  "/opt/jboss/wildfly/…"   5 minutes ago       Up 5 minutes        0.0.0.0:8028->8080/tcp, 0.0.0.0:8231->8787/tcp, 0.0.0.0:8126->9990/tcp   wildfly-server_7
13a6a365a552  "/opt/jboss/wildfly/…"   5 minutes ago       Up 5 minutes        0.0.0.0:8031->8080/tcp, 0.0.0.0:8230->8787/tcp, 0.0.0.0:8131->9990/tcp   wildfly-server_10
bf8260d9874d  "/opt/jboss/wildfly/…"   5 minutes ago       Up 5 minutes        0.0.0.0:8029->8080/tcp, 0.0.0.0:8228->8787/tcp, 0.0.0.0:8129->9990/tcp   wildfly-server_6
3d58f2e9bdfe  "/opt/jboss/wildfly/…"   5 minutes ago       Up 5 minutes        0.0.0.0:8030->8080/tcp, 0.0.0.0:8229->8787/tcp, 0.0.0.0:8130->9990/tcp   wildfly-server_9
7824a73a09f5  "/opt/jboss/wildfly/…"   5 minutes ago       Up 5 minutes        0.0.0.0:8027->8080/tcp, 0.0.0.0:8227->8787/tcp, 0.0.0.0:8128->9990/tcp   wildfly-server_3
85425462259d  "/opt/jboss/wildfly/…"   5 minutes ago       Up 5 minutes        0.0.0.0:8024->8080/tcp, 0.0.0.0:8224->8787/tcp, 0.0.0.0:8124->9990/tcp   wildfly-server_2
5be5bbe8e577  "/opt/jboss/wildfly/…"   5 minutes ago       Up 5 minutes        0.0.0.0:8026->8080/tcp, 0.0.0.0:8226->8787/tcp, 0.0.0.0:8127->9990/tcp   wildfly-server_8
2512fc0643a3  "/opt/jboss/wildfly/…"   5 minutes ago       Up 5 minutes        0.0.0.0:8023->8080/tcp, 0.0.0.0:8223->8787/tcp, 0.0.0.0:8123->9990/tcp   wildfly-server_5
b156de688dcb  "/opt/jboss/wildfly/…"   5 minutes ago       Up 5 minutes        0.0.0.0:8025->8080/tcp, 0.0.0.0:8225->8787/tcp, 0.0.0.0:8125->9990/tcp   wildfly-server_4
3e9401552b0a  "/opt/jboss/wildfly/…"   5 minutes ago       Up 5 minutes        0.0.0.0:8022->8080/tcp, 0.0.0.0:8222->8787/tcp, 0.0.0.0:8122->9990/tcp   wildfly-server_1

Вопрос

Есть ли способ сделать распределение портов детерминированным? Как отключить параллельный запуск для проверки последовательных портов на доступных портах или каким-либо другим способом? Единственная альтернатива, которую я нашел, - это иметь yml шаблон и генерировать все необходимые файлы (например, 10, если мне нужно 10 контейнеров и т. Д.). Есть ли альтернативные решения?

гашиш
источник
если вы используете CI-сервер, такой как jenkins, вы можете просто
изменить
Среда не является фиксированной. Цель в основном состоит в том, чтобы вытащить его в любое количество экземпляров по мере необходимости. Я могу решить эту проблему с помощью упомянутого ymlшаблона с различными переменными окружения, но мне интересно, есть ли способ использовать --scaleдля этого.
хэш
есть ли какая-то причина, мешающая вам использовать режим Swarm?
eez0
Как бы вы использовали режим роя для создания нескольких экземпляров с последовательными портами и с детерминированной привязкой портов?
хэш
Вы хотите запустить несколько экземпляров, когда вы отправляете запрос, он переходит к одному из доступных экземпляров. Это поведение, которое вы хотите?
Keaz

Ответы:

3

Нет, вы не можете (14.10.19) сделать выбор порта детерминированным в файле docker-compose. Такое поведение было запрошено в проблемах Github № 722 и № 1247 , но эти проблемы были закрыты, но проблема не была реализована.

Если вы хотите полудинамически масштабировать приложение так, как оно звучит, то вам нужно решить эту проблему другим способом. Ваша .ymlшаблонная идея звучит как самое чистое решение IMO.

Вы уверены, что порты должны быть детерминированными? Если вы используете обратный прокси-сервер, такой как nginx, который прослушивает один порт хоста и балансирует нагрузку между всеми вашими док-контейнерами, подойдет ли это для вашего варианта использования? Настроить балансировщик нагрузки nginx в контейнере Docker довольно просто. Я предлагаю вам разобраться в этом, и если вам все еще нужен детерминистический способ для того, чтобы вызывающий абонент знал порт службы, чтобы он мог повторно отправлять запрос на определенный сервер, тогда используйте свое .ymlшаблонное решение или какой-то другой процесс обнаружения службы, отличный от конфигурация docker-compose.

Брендан Гоггин
источник
Спасибо за ссылки, я немного разочарован, что они даже не решили проблему ... Я хочу, чтобы масштабировать полностью автоматически. :) Мне нужны детерминированные порты для генерации некоторых файлов до того, как контейнеры будут запущены (каждый порт должен быть для другого пользователя, так как я прокомментировал, что до балансировки нагрузки это не вариант). Таким образом, информация, которой вы поделились, больше похожа на комментарий, а не на ответ.
хэш
Таким образом, в этом случае вы на самом деле не «динамически масштабируете» таким способом, которым могут управлять docker-compose и docker. Они ожидают, что экземпляры вашего сервиса будут полностью взаимозаменяемыми, а в вашем случае это не так ... вам нужен какой-то механизм обнаружения сервисов или детерминированное назначение портов, и я думаю, что ваш .ymlшаблонный подход самый быстрый и простой решение. И между прочим, я технически ответил на ваш вопрос "Есть ли способ сделать детерминированное распределение портов?" :) но я извиняюсь, что не смог предложить более полезное решение.
Брендан Гоггин