Escala Docker com ligação de porta determinística

14

Eu gostaria de escalar um wildflycontêiner que tenha exposto várias portas com resultados determinísticos.

docker-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}/

Comando para iniciar

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

Quase funciona como eu quero, mas há alguma discrepância de porta. Ao criar os contêineres, quero que eles tenham portas incrementais para cada contêiner a ser exposto da seguinte maneira:

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

Mas o que recebo como resultado não é determinístico e fica assim:

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

O problema é que toda vez que executo o comando de composição, as portas são diferentes para cada contêiner.

Exemplo de saída:

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

Questão

Existe alguma maneira de tornar a distribuição de portas determinística? Como desativar a execução paralela para ter verificações seriais nas portas disponíveis ou qualquer outro método? A única alternativa que encontrei é ter um yml modelo e gerar todos os arquivos necessários (como 10 se precisar de 10 contêineres etc.). Existem soluções alternativas?

Cerquilha
fonte
se você usar o servidor de CI como Jenkins você pode handel que simplesmente
LinPy
O ambiente não é fixo. O objetivo é basicamente exibi-lo em qualquer lugar quantas instâncias forem necessárias. Posso resolvê-lo com o ymlmodelo mencionado com diferentes variáveis ​​de ambiente, mas estou interessado em saber se existe alguma maneira de usá --scale-lo.
Hash,
existe alguma razão para impedir que você use o modo Swarm?
eez0
Como você utilizaria o modo enxame para criar várias instâncias com portas sequenciais e com ligação determinística de portas?
Hash
Você deseja executar várias instâncias. Quando você envia uma solicitação, ela será direcionada para uma das instâncias disponíveis. Esse é o comportamento que você deseja?
Keaz

Respostas:

3

Não, atualmente não é possível (14/10/19) tornar a seleção de porta determinística no arquivo de composição de encaixe. Esse comportamento foi solicitado nas edições 722 e 1247 do Github , mas essas questões foram encerradas sem a implementação do problema.

Se você quiser dimensionar semi-dinamicamente um aplicativo como parece, você precisará resolver isso de outra maneira. Sua .ymlideia de modelo parece a solução mais limpa da IMO.

Você tem certeza de que precisa que as portas sejam determinísticas? Se você usar um proxy reverso como o nginx, que escuta em uma porta do host e equilibra a carga entre todos os contêineres do docker, isso funcionaria no seu caso de uso? A configuração de um balanceador de carga nginx em um contêiner de docker é bastante simples. Sugiro que você analise isso e, se ainda precisar de uma maneira determinista para que um chamador conheça a porta do serviço, para que ele possa enviar uma solicitação para um servidor específico repetidamente, siga sua .ymlsolução de modelo ou algum tipo de processo de descoberta de serviço separado de a configuração do docker-compose.

Brendan Goggin
fonte
Obrigado pelos links, estou um pouco decepcionado por eles nem abordarem o problema ... Quero dimensionar totalmente automaticamente. :) Preciso de portas determinísticas para gerar alguns arquivos antes que os contêineres sejam abertos (cada porta deve ser para um usuário diferente, como comentei antes de o balanceamento de carga não ser uma opção). Portanto, as informações que você compartilhou são mais como um comentário, não uma resposta.
Hash
Portanto, nesse caso, você não está realmente "escalando dinamicamente" de uma maneira que o docker-componha e o docker estejam equipados para lidar. Eles esperam que as instâncias do seu serviço sejam totalmente intercambiáveis ​​e, no seu caso, não são ... você precisa de algum tipo de mecanismo de descoberta de serviço ou atribuição determinística de portas, e acho que sua .ymlabordagem de modelagem é a mais rápida, fácil. solução. E, a propósito, eu tecnicamente respondi à sua pergunta de "Existe alguma maneira de tornar a distribuição de portas determinística?" :) mas peço desculpas por não poder sugerir uma solução mais útil.
Brendan Goggin