Docker-Skala mit deterministischer Portbindung

14

Ich möchte einen wildflyContainer skalieren , der mehrere Ports mit deterministischen Ergebnissen freigelegt hat.

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

Befehl zum Starten

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

Es funktioniert fast so, wie ich es möchte, aber es gibt einige Port-Diskrepanzen. Wenn ich die Container erstelle, möchte ich, dass sie inkrementelle Ports für jeden Container haben, die wie folgt verfügbar gemacht werden sollen:

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

Aber was ich als Ergebnis bekomme, ist nicht deterministisch und sieht so aus:

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

Das Problem ist, dass jedes Mal, wenn ich den Befehl compose up ausführe, die Ports für jeden Container unterschiedlich sind.

Beispielausgabe:

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

Frage

Gibt es eine Möglichkeit, die Portverteilung deterministisch zu machen? Möchten Sie die parallele Ausführung deaktivieren, um serielle Überprüfungen der verfügbaren Ports oder eine andere Methode durchzuführen? Die einzige Alternative, die ich gefunden habe, besteht darin, eine yml Vorlage zu haben und alle erforderlichen Dateien zu generieren (z. B. 10, wenn ich 10 Container usw. benötige). Gibt es alternative Lösungen?

Hash
quelle
Wenn Sie CI-Server wie Jenkins verwenden, können Sie dies einfach
handhaben
Die Umgebung ist nicht fest. Das Ziel ist im Grunde, es überall so viele Instanzen wie nötig zu öffnen. Ich kann es mit der genannten ymlVorlage mit verschiedenen Umgebungsvariablen lösen , bin aber interessiert, ob es eine Möglichkeit gibt, dies zu verwenden --scale.
Hash
Gibt es einen Grund, der Sie daran hindert, den Schwarmmodus zu verwenden?
eez0
Wie würden Sie den Schwarmmodus verwenden, um mehrere Instanzen mit sequentiellen Ports und deterministischer Portbindung zu erstellen?
Hash
Sie möchten mehrere Instanzen ausführen. Wenn Sie eine Anforderung senden, wird diese an eine der verfügbaren Instanzen gesendet. Ist das das Verhalten, das Sie wollen?
Keaz

Antworten:

3

Nein, Sie können die Portauswahl derzeit (14.10.19) nicht deterministisch in der Docker-Compose-Datei festlegen. Dieses Verhalten wurde in den Github-Problemen Nr. 722 und Nr. 1247 angefordert , aber diese Probleme wurden geschlossen, ohne dass das Problem implementiert wurde.

Wenn Sie eine Anwendung semidynamisch skalieren möchten, wie es sich anhört, müssen Sie dies auf andere Weise lösen. Ihre .ymlVorlagenidee klingt nach der saubersten Lösung IMO.

Sind Sie sicher, dass die Ports deterministisch sein müssen? Wenn Sie einen Reverse-Proxy wie nginx verwenden, der einen Host-Port überwacht und die Last zwischen all Ihren Docker-Containern verteilt, würde dies für Ihren Anwendungsfall funktionieren? Das Einrichten eines Nginx Load Balancers in einem Docker-Container ist ziemlich einfach. Ich schlage vor, Sie prüfen dies. Wenn Sie immer noch eine deterministische Methode benötigen, damit ein Anrufer den Port des Dienstes kennt, damit er wiederholt eine Anfrage an einen bestimmten Server senden kann, gehen Sie zu Ihrer .ymlVorlagenlösung oder einem anderen Diensterkennungsprozess, der von diesem getrennt ist die Docker-Compose-Konfiguration.

Brendan Goggin
quelle
Vielen Dank für die Links, ich bin ein bisschen enttäuscht, dass sie das Problem nicht einmal angesprochen haben ... Ich möchte vollautomatisch skalieren. :) Ich benötige deterministische Ports, um einige Dateien zu generieren, bevor die Container aktiv sind (jeder Port sollte für einen anderen Benutzer sein, wie ich vor dem Lastenausgleich kommentiert habe, ist keine Option). Die Informationen, die Sie geteilt haben, sind also eher ein Kommentar als eine Antwort.
Hash
In diesem Fall skalieren Sie also nicht wirklich "dynamisch" auf eine Weise, für die Docker-Compose und Docker gerüstet sind. Sie erwarten, dass die Instanzen Ihres Dienstes vollständig austauschbar sind, und in Ihrem Fall sind sie nicht ... Sie benötigen entweder einen Mechanismus zur Diensterkennung oder eine deterministische Zuweisung von Ports, und ich denke, Ihr .ymlTemplate-Ansatz ist der schnellste und einfachste Lösung. Übrigens habe ich Ihre Frage "Gibt es eine Möglichkeit, die Portverteilung deterministisch zu machen?" Technisch beantwortet. :) aber ich entschuldige mich, dass ich keine hilfreichere Lösung vorschlagen konnte.
Brendan Goggin