Dynamisches Hinzufügen von Portweiterleitungen zu laufenden Docker-Containern

Dynamisches Hinzufügen von Portweiterleitungen zu laufenden Docker-Containern

Die Portweiterleitung ist ein entscheidender Aspekt bei der Entwicklung und Bereitstellung von containerisierten Anwendungen. Normalerweise stellen wir beim Erstellen eines Containers eine Verbindung zwischen einem internen Port des Containers und einem Port auf dem Host-Rechner her. Es gibt jedoch Situationen, in wir dynamisch neue Portweiterleitungen zu einem bereits laufenden Container hinzufügen müssen. Dies kann besonders während der Entwicklung, beim Debugging oder bei der vorübergehenden Freigabe neuer Service-Endpunkte nützlich sein. Dieser Artikel erklärt detailliert, wie man einem Container dynamisch Portweiterleitungen hinzufügt, ohne ihn anhalten zu müssen.

1. Hintergrundwissen

Grundprinzipien der Container-Portweiterleitung

In Docker wird die Verbindung zwischen einem internen Port eines Containers und dem Port des Host-Rechners über die Portweiterleitung hergestellt. Normalerweise geben wir die Portweiterleitungen beim Starten eines Containers mit den Parametern -p oder --publish an, wie unten dargestellt:

docker run -d -p 8080:80 nginx

Der obige Befehl bildet Port 8080 des Host-Rechners auf Port 80 im Container ab. Dadurch können externe Benutzer den im Container laufenden Webdienst über Port 8080 des Hosts erreichen.

Herausforderungen beim dynamischen Hinzufügen von Portweiterleitungen

Sobald ein Container gestartet ist, unterstützt Docker normalerweise nicht das dynamische Hinzufügen neuer Portweiterleitungen. Mit anderen Worten, die anfänglichen Portweiterleitungen bleiben während des gesamten Lebenszyklus des Containers fest. Wenn zusätzliche Portweiterleitungen erforderlich sind, besteht der traditionelle Ansatz darin, den Container anzuhalten und neu zu starten, was Dienste unterbrechen kann und in Produktionsumgebungen inakzeptabel ist.

2. Implementierungslösungen

Um einem laufenden Container dynamisch Portweiterleitungen hinzuzufügen, können verschiedene Methoden angewendet werden:

2.1 Erstellen eines Proxy-Containers mit docker network

Ein neuer Proxy-Container kann im selben Netzwerk wie der ursprüngliche Container erstellt werden, und die neuen Portweiterleitungen können dem Proxy-Container hinzugefügt werden. Die genauen Schritte sind wie folgt: Erstellen Sie zunächst einen Proxy-Container im selben Netzwerk wie der ursprüngliche Container:

docker run -d --name proxy-container --net container:your-container nginx

Fügen Sie dann die gewünschte Portweiterleitung zum Proxy-Container hinzu:

docker run -d -p 8081:81 --net container:your-container nginx

Vorsicht bei der Verwendung des Codes. Diese Methode ermöglicht das Hinzufügen neuer Portweiterleitungen, ohne den ursprünglichen Container zu ändern, führt jedoch eine zusätzliche Containerinstanz ein und ist möglicherweise nicht für alle Szenarien geeignet.

2.2 Manuelles Hinzufügen von Portweiterleitungsregeln mit iptables

Durch Ändern von iptables können Sie Anfragen von einem bestimmten Port des Host-Rechners an den internen Port des laufenden Docker-Containers weiterleiten. Um beispielsweise Port 8081 des Hosts auf Port 81 im Container abzubilden, verwenden Sie den folgenden Befehl:

iptables -t nat -A DOCKER -p tcp --dport 8081 -j DNAT --to-destination <container_ip>:81

Wobei <container_ip> die interne IP-Adresse des Containers ist, die mit dem Befehl docker inspect ermittelt werden kann. Diese Methode bietet volle Flexibilität beim Hinzufügen von Portweiterleitungen, erfordert jedoch ein gutes Verständnis von iptables und wird aufgrund ihrer Komplexität nicht für den häufigen Einsatz in Produktionsumgebungen empfohlen.

2.3 Verwenden von socat zur Erstellung einer Portweiterleitung

socat ist ein vielseitiges Netzwerktool, das eine Portweiterleitung zwischen dem Host-Rechner und einem Container einrichten kann. Sie können den folgenden Befehl ausführen, um einen bestimmten Port des Host-Rechners an einen bestimmten Port im Container weiterzuleiten:

socat TCP-LISTEN:8081,fork TCP:<container_ip>:81

Vorsicht bei der Verwendung des Codes. Der Vorteil dieser Methode besteht darin, dass der Container nicht angehalten werden muss. Da socat jedoch ein zusätzlicher Prozess ist, sollten Sie auf seine Leistung und Stabilität achten. Andere Portweiterleitungswerkzeuge können ähnliche Ergebnisse erzielen.

2.4 Dynamisches Aktualisieren von Diensten mit Docker Compose

Wenn Ihre Anwendung Docker Compose zur Verwaltung von Containern verwendet, können Sie neue Portweiterleitungen hinzufügen, indem Sie die Datei docker-compose.yml aktualisieren und dann docker-compose up ausführen. Diese Methode ist bequem und bietet eine einheitliche Verwaltung, erfordert jedoch bei jeder Aktualisierung ein erneutes Anwenden der Compose-Datei, was zu vorübergehenden Dienstunterbrechungen führen kann.

2.5 Erzwungenes Ändern der Container-Konfigurationsdatei

Ändern Sie zunächst direkt die Datei /var/lib/docker/containers/<container_id>/config.v2.json und fügen Sie die Zuordnung von HostPort 8081 zu Port 81 im Container hinzu. Beachten Sie, dass Sie zwei Abschnitte ändern müssen. In einem Abschnitt müssen Sie nur HostPort 8081 hinzufügen:

    "ExposedPorts": {
      "8080/tcp": {}
      "8081/tcp": {}
    },

Im anderen Abschnitt müssen Sie die vollständige Zuordnungsbeziehung hinzufügen:

   "Ports": {
      "80/tcp": [
        {
          "HostIp": "0.0.0.0",
          "HostPort": "8080"
        },
      ],
      "81/tcp": [
        {
          "HostIp": "0.0.0.0",
          "HostPort": "8081"
        },
      ]
    },

Zusätzlich müssen Sie auch /var/lib/docker/containers/<container_id>/hostconfig.json ändern und die neue Zuordnung hinzufügen:

  "PortBindings": {
    "80/tcp": [
      {
        "HostIp": "",
        "HostPort": "8080"
      },
     "81/tcp": [
      {
        "HostIp": "",
        "HostPort": "8081"
      }
    ]
  },

Abschließend müssen Sie dockerd neu starten:

sudo systemctl restart docker

Diese Methode kann dauerhaft Portweiterleitungen zum Container hinzufügen, hat jedoch den Nebeneffekt, dass aufgrund des Neustarts von dockerd alle Container auf dem Host-Rechner angehalten werden. Wenn die Container nicht für den automatischen Start konfiguriert sind, starten sie auch nach einem Neustart von dockerd nicht automatisch. Obwohl diese Methode effektiv ist, kann sie erhebliche Auswirkungen auf laufende Container haben und wird in Produktionsumgebungen nicht empfohlen.

3. Fazit

Obwohl das dynamische Hinzufügen von Portweiterleitungen zu Containern keine nativ unterstützte Funktion in Docker ist, können die oben beschriebenen Methoden dies bis zu einem gewissen Grad erreichen. Jede Methode hat ihre Vor- und Nachteile, und Entwickler können die am besten geeignete basierend auf ihren spezifischen Anforderungen auswählen. In Produktionsumgebungen wird die Verwendung von Proxy-Containern oder Docker Compose empfohlen, da sie relativ einfach und risikoarm sind. Für Anwendungen, die häufige Änderungen an Portweiterleitungen erfordern, ist es ratsam, während der Entwurfsphase eine flexible Netzwerkarchitektur in Betracht zu ziehen, um häufige Änderungen an Portweiterleitungen bei laufendem Container zu vermeiden und so Dienstunterbrechungen zu minimieren.

Sie können Novita AI besuchen.