Verbinden von Nginx in Docker mit Localhost MySQL auf dem Host-Computer

Verbinden von Nginx in Docker mit Localhost MySQL auf dem Host-Computer
Shell

Zugriff auf Localhost-Dienste über Docker-Container

Das Ausführen von Nginx in einem Docker-Container, während eine Verbindung zu einer MySQL-Instanz auf dem Host-Computer hergestellt werden muss, kann eine Herausforderung sein, insbesondere wenn MySQL nur an localhost gebunden ist. Dieses Setup verhindert, dass der Container über Standard-Netzwerkmethoden direkt auf den MySQL-Dienst zugreift.

In diesem Artikel werden verschiedene Lösungen untersucht, um diese Lücke zu schließen und eine nahtlose Konnektivität zwischen Docker-Containern und Diensten zu ermöglichen, die auf dem Localhost des Hosts ausgeführt werden. Wir diskutieren, warum gängige Methoden möglicherweise nicht ausreichen, und bieten praktische Schritte zum Erreichen der gewünschten Konnektivität.

Befehl Beschreibung
docker network create --driver bridge hostnetwork Erstellt ein benutzerdefiniertes Docker-Netzwerk mit einem Bridge-Treiber, der es Containern ermöglicht, innerhalb desselben Netzwerks zu kommunizieren.
host_ip=$(ip -4 addr show docker0 | grep -oP '(? Extrahiert die IP-Adresse der Docker0-Schnittstelle des Hosts, die für die Verbindung vom Container zu den Hostdiensten verwendet wird.
docker exec -it nginx-container bash Führt eine interaktive Bash-Shell im laufenden Nginx-Container für direkten Befehlszeilenzugriff aus.
mysql -h $host_ip -u root -p Befehl, der im Nginx-Container verwendet wird, um mithilfe der extrahierten IP-Adresse eine Verbindung zum MySQL-Server herzustellen, der auf dem Hostcomputer ausgeführt wird.
networks: hostnetwork: external: true Konfiguration in Docker Compose zur Verwendung eines extern erstellten Docker-Netzwerks.
echo "server { listen 80; location / { proxy_pass http://host.docker.internal:3306; } }" >echo "server { listen 80; location / { proxy_pass http://host.docker.internal:3306; } }" > /etc/nginx/conf.d/default.conf Schreibt eine neue Nginx-Konfiguration, um MySQL-Anfragen an den Host-Computer weiterzuleiten.
nginx -s reload Lädt den Nginx-Dienst neu, um die neuen Konfigurationsänderungen anzuwenden.

Konfigurieren von Docker und Nginx für den Zugriff auf Host-Dienste

Um einen Nginx-Container mit einer auf dem Host laufenden MySQL-Instanz zu verbinden, müssen wir zunächst eine Netzwerkbrücke einrichten. Der Befehl docker network create --driver bridge hostnetwork erstellt dieses benutzerdefinierte Netzwerk und ermöglicht die Kommunikation zwischen Containern im selben Netzwerk. Anschließend starten wir MySQL- und Nginx-Container in diesem Netzwerk mit docker run --name mysql-container --network hostnetwork -e MYSQL_ROOT_PASSWORD=root -d mysql:latest Und docker run --name nginx-container --network hostnetwork -d nginx:latest, jeweils. Dieses Setup ermöglicht es den Containern, einander zu erkennen und miteinander zu kommunizieren. Um von Nginx aus eine Verbindung zu MySQL herzustellen, benötigen wir die IP-Adresse des Hosts, die mit abgerufen werden kann host_ip=$(ip -4 addr show docker0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}'). Dieser Befehl erfasst die IP-Adresse der Docker0-Schnittstelle auf dem Host.

Als nächstes verwenden wir docker exec -it nginx-container bash um eine interaktive Shell im Nginx-Container zu öffnen. Von hier aus können wir eine MySQL-Verbindung mit initiieren mysql -h $host_ip -u root -p, Wo $host_ip ist die IP-Adresse des Hosts. Alternativ vereinfacht die Verwendung von Docker Compose den Prozess, indem Dienste und Netzwerke in einer YAML-Datei definiert werden. Der networks: hostnetwork: external: true Durch die Konfiguration wird sichergestellt, dass die Dienste ein extern erstelltes Netzwerk nutzen. Um Nginx schließlich als Proxy für MySQL-Anfragen zu konfigurieren, aktualisieren wir seine Konfigurationsdatei mit echo "server { listen 80; location / { proxy_pass http://host.docker.internal:3306; } }" > /etc/nginx/conf.d/default.conf und Nginx mit neu laden nginx -s reload. Dieses Setup ermöglicht es Nginx, Anfragen an die MySQL-Instanz weiterzuleiten, die auf dem Host ausgeführt wird.

Docker-Container über Network Bridge mit MySQL des Hosts verbinden

Shell-Skript für die Docker-Netzwerkeinrichtung

# Create a Docker network
docker network create --driver bridge hostnetwork

# Run MySQL container with the created network
docker run --name mysql-container --network hostnetwork -e MYSQL_ROOT_PASSWORD=root -d mysql:latest

# Run Nginx container with the created network
docker run --name nginx-container --network hostnetwork -d nginx:latest

# Get the host machine's IP address
host_ip=$(ip -4 addr show docker0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}')

# Connect to MySQL from within the Nginx container
docker exec -it nginx-container bash
mysql -h $host_ip -u root -p

Verwenden von Docker Compose, um Nginx und MySQL des Hosts zu verknüpfen

Docker Compose YAML-Konfiguration

version: '3.8'

services:
  nginx:
    image: nginx:latest
    container_name: nginx-container
    networks:
      - hostnetwork

  mysql:
    image: mysql:latest
    container_name: mysql-container
    environment:
      MYSQL_ROOT_PASSWORD: root
    networks:
      - hostnetwork

networks:
  hostnetwork:
    external: true

Konfigurieren von Nginx für die Verbindung mit Host MySQL über das Docker-Netzwerk

Nginx-Konfiguration und Docker-Netzwerkbefehl

# Create a bridge network
docker network create bridge-network

# Run Nginx container with bridge network
docker run --name nginx-container --network bridge-network -d nginx:latest

# Run MySQL container on the host network
docker run --name mysql-container --network host -e MYSQL_ROOT_PASSWORD=root -d mysql:latest

# Update Nginx configuration to point to MySQL host
docker exec -it nginx-container bash
echo "server { listen 80; location / { proxy_pass http://host.docker.internal:3306; } }" > /etc/nginx/conf.d/default.conf
nginx -s reload

Docker-Container mit lokalen Host-Diensten verbinden

Beim Ausführen von Anwendungen in Docker-Containern kann der Zugriff auf Dienste, die an den Localhost des Hosts gebunden sind, aufgrund der Netzwerkisolation eine Herausforderung darstellen. Ein effektiver Ansatz ist die Verwendung des Host-Netzwerkmodus von Docker. Durch Starten eines Containers mit dem --network host Bei dieser Option teilt der Container den Netzwerkstapel des Hosts, sodass dieser direkt auf lokale Host-gebundene Dienste zugreifen kann. Allerdings ist dieser Modus weniger portierbar und funktioniert möglicherweise nicht in allen Umgebungen, wie etwa Docker Swarm oder Kubernetes.

Ein anderer Ansatz besteht darin, den integrierten DNS-Resolver von Docker zu verwenden. host.docker.internal. Dieser spezielle DNS-Name wird in die IP-Adresse des Hosts aufgelöst, sodass Container mit Diensten auf dem Host kommunizieren können. Diese Methode ist unkompliziert und vermeidet die Komplexität der Netzwerkverwaltung. Allerdings ist es nur auf Docker für Windows und Mac verfügbar, nicht auf Linux. Für Linux-Benutzer ist die Erstellung eines benutzerdefinierten Bridge-Netzwerks und die manuelle Konfiguration von Routing-Regeln eine praktikable Lösung. Dies beinhaltet die Verwendung der ip Und iptables Befehle zum Weiterleiten des Datenverkehrs vom Containernetzwerk zur Localhost-Schnittstelle des Hosts.

Häufige Fragen zum Verbinden von Docker-Containern mit Host-Diensten

  1. Wie verwende ich die --network host Option in Docker?
  2. Führen Sie Ihren Container mit aus docker run --network host um den Netzwerk-Stack des Hosts freizugeben.
  3. Was ist host.docker.internal?
  4. Es handelt sich um einen speziellen DNS-Namen, der in die IP-Adresse des Hosts aufgelöst wird und auf Docker für Windows und Mac verfügbar ist.
  5. Kann ich benutzen host.docker.internal unter Linux?
  6. Nein, diese Funktion ist auf Docker für Linux nicht verfügbar.
  7. Wie kann ich ein benutzerdefiniertes Bridge-Netzwerk erstellen?
  8. Verwenden docker network create --driver bridge my-bridge-network um ein benutzerdefiniertes Brückennetzwerk zu erstellen.
  9. Was ist der Zweck des iptables Befehl?
  10. Es verwaltet Netzwerkpaketfilter- und Routingregeln auf Linux-Systemen.
  11. Wie verbinde ich mich von einem Docker-Container aus mit einer MySQL-Instanz auf dem Host?
  12. Verwenden mysql -h host.docker.internal -u root -p für Docker unter Windows/Mac oder konfigurieren Sie das Routing für Linux.
  13. Welche Einschränkungen gibt es bei der Verwendung? --network host?
  14. Dies kann die Portabilität beeinträchtigen und ist mit einigen Orchestratoren wie Kubernetes nicht kompatibel.
  15. Kann ich neben MySQL auch auf andere Dienste auf dem Host zugreifen?
  16. Ja, mit denselben Methoden können Sie eine Verbindung zu jedem Dienst herstellen, der auf dem Host ausgeführt wird.

Abschließende Gedanken zum Zugriff auf Host-Dienste von Docker

Das Herstellen einer Verbindung zu einer MySQL-Instanz auf dem Host von einem Nginx-Container aus erfordert verschiedene Methoden, von denen jede ihre eigenen Vorteile und Einschränkungen hat. Der Einsatz von Host-Netzwerken, speziellen DNS-Namen oder benutzerdefinierten Netzwerkbrücken kann diese Lücke effektiv schließen und eine reibungslose Kommunikation zwischen Docker-Containern und Host-Diensten gewährleisten. Durch das Verständnis und die Umsetzung dieser Strategien können Sie die Herausforderungen der Netzwerkisolation überwinden und robuste Verbindungen in Ihrer Docker-Umgebung aufrechterhalten.