Verwendung von Traefik als Reverse Proxy für Docker-Container unter Debian 9

Der Autor hat Girls Who Code ausgewählt, um eine Spende im Rahmen des Programms Write for DOnations zu erhalten .

Einführung

https://www.docker.com [Docker] kann eine effiziente Methode zum Ausführen von Webanwendungen in der Produktion sein. Möglicherweise möchten Sie jedoch mehrere Anwendungen auf demselben Docker-Host ausführen. In dieser Situation müssen Sie einen Reverse-Proxy einrichten, da Sie nur die Ports "+ 80 " und " 443 +" für den Rest der Welt verfügbar machen möchten.

https://traefik.io [Traefik] ist ein Docker-fähiger Reverse-Proxy, der ein eigenes Überwachungs-Dashboard enthält. In diesem Lernprogramm leiten Sie mithilfe von Traefik Anforderungen an zwei verschiedene Webanwendungscontainer weiter: einen Container http://wordpress.org [Wordpress] und einen Container Adminer zu einer MySQL Datenbank. Sie konfigurieren Traefik so, dass alles über HTTPS mit Let’s Encrypt bereitgestellt wird.

Voraussetzungen

Um diesem Tutorial folgen zu können, benötigen Sie Folgendes:

Schritt 1 - Konfigurieren und Ausführen von Traefik

Das Traefik-Projekt verfügt über ein official Docker-Image, sodass Traefik in einem Docker-Container ausgeführt wird.

Bevor wir unseren Traefik-Container in Betrieb nehmen können, müssen wir jedoch eine Konfigurationsdatei erstellen und ein verschlüsseltes Kennwort einrichten, um auf das Überwachungs-Dashboard zugreifen zu können.

Wir werden das Hilfsprogramm "+ htpasswd " verwenden, um dieses verschlüsselte Passwort zu erstellen. Installieren Sie zuerst das Dienstprogramm, das im Paket ` apache2-utils +` enthalten ist:

sudo apt install apache2-utils

Dann generieren Sie das Passwort mit + htpasswd +. Ersetzen Sie "++" durch das Passwort, das Sie für den Traefik-Administrator verwenden möchten:

htpasswd -nb admin

Die Ausgabe des Programms sieht folgendermaßen aus:

Outputadmin:

Sie werden diese Ausgabe in der Traefik-Konfigurationsdatei verwenden, um die HTTP-Basisauthentifizierung für das Traefik-Dashboard für Integritätsprüfung und Überwachung einzurichten. Kopieren Sie die gesamte Ausgabezeile, damit Sie sie später einfügen können.

Um den Traefik-Server zu konfigurieren, erstellen wir eine neue Konfigurationsdatei mit dem Namen "+ traefik.toml " im TOML-Format. https://github.com/toml-lang/toml[TOML] ist eine Konfigurationssprache, die INI-Dateien ähnelt, jedoch standardisiert ist. Mit dieser Datei können wir den Traefik-Server und verschiedene Integrationen oder Anbieter konfigurieren, die wir verwenden möchten. In diesem Tutorial werden drei von Traefik verfügbare Anbieter verwendet: " api", "+ docker" und "+ acme", die zur Unterstützung von TLS mit Let’s Encrypt verwendet werden.

Öffnen Sie Ihre neue Datei in + nano + oder Ihrem bevorzugten Texteditor:

nano traefik.toml

Fügen Sie zunächst zwei benannte Einstiegspunkte hinzu, "+ http " und " https +", auf die alle Backends standardmäßig zugreifen können:

traefik.toml

defaultEntryPoints = ["http", "https"]

Die Einstiegspunkte "+ http " und " https +" werden später in dieser Datei konfiguriert.

Konfigurieren Sie als nächstes den "+ api" -Anbieter, über den Sie auf eine Dashboard-Oberfläche zugreifen können. Hier fügen Sie die Ausgabe des Befehls "+ htpasswd +" ein:

traefik.toml

...
[entryPoints]
 [entryPoints.dashboard]
   address = ":8080"
   [entryPoints.dashboard.auth]
     [entryPoints.dashboard.auth.basic]
       users = [""]

[api]
entrypoint="dashboard"

Das Dashboard ist eine separate Webanwendung, die im Traefik-Container ausgeführt wird. Wir haben das Dashboard so eingestellt, dass es auf Port "+ 8080 +" ausgeführt wird.

Im Abschnitt "+ entrypoints.dashboard " wird konfiguriert, wie die Verbindung zum " api " - Anbieter hergestellt wird. Im Abschnitt " entrypoints.dashboard.auth.basic " wird die HTTP-Basisauthentifizierung für das Dashboard konfiguriert. Verwenden Sie die Ausgabe des Befehls " htpasswd ", die Sie gerade für den Wert des Eintrags " users +" ausgeführt haben. Sie können zusätzliche Anmeldungen angeben, indem Sie sie durch Kommas trennen.

Wir haben unseren ersten "+ entryPoint " definiert, müssen jedoch andere für die standardmäßige HTTP- und HTTPS-Kommunikation definieren, die nicht an den " api " - Anbieter gerichtet ist. Der Abschnitt " entryPoints " konfiguriert die Adressen, die Traefik und die Proxy-Container abhören können. Fügen Sie diese Zeilen der Datei unter der Überschrift ` entryPoints +` hinzu:

traefik.toml

...
 [entryPoints.http]
   address = ":80"
     [entryPoints.http.redirect]
       entryPoint = "https"
 [entryPoints.https]
   address = ":443"
     [entryPoints.https.tls]
...

Der Einstiegspunkt "+ http " verarbeitet den Port " 80 ", während der Einstiegspunkt " https " den Port " 443 " für TLS / SSL verwendet. Wir leiten den gesamten Datenverkehr auf Port " 80 " automatisch zum " https +" - Einstiegspunkt um, um sichere Verbindungen für alle Anforderungen zu erzwingen.

Fügen Sie als Nächstes diesen Abschnitt hinzu, um die Unterstützung für Let’s Encrypt-Zertifikate für Traefik zu konfigurieren:

traefik.toml

...
[acme]
email = ""
storage = "acme.json"
entryPoint = "https"
onHostRule = true
 [acme.httpChallenge]
 entryPoint = "http"

Dieser Abschnitt heißt "+ acme ", da "https://github.com/ietf-wg-acme/acme/[ACME" der Name des Protokolls ist, das zur Kommunikation mit "Let's Encrypt" zur Verwaltung von Zertifikaten verwendet wird. Der Let’s Encrypt-Dienst erfordert die Registrierung mit einer gültigen E-Mail-Adresse. Damit Traefik Zertifikate für unsere Hosts generiert, setzen Sie den " email " - Schlüssel auf Ihre E-Mail-Adresse. Wir geben dann an, dass wir die Informationen, die wir von Let’s Encrypt erhalten, in einer JSON-Datei mit dem Namen " acme.json " speichern. Der Schlüssel " entryPoint " muss auf den Einstiegspunkt verweisen, der den Port " 443 " behandelt, der in unserem Fall der " https +" - Einstiegspunkt ist.

Der Schlüssel "+ onHostRule " bestimmt, wie Traefik Zertifikate generieren soll. Wir möchten unsere Zertifikate abrufen, sobald unsere Container mit den angegebenen Hostnamen erstellt wurden. Dies geschieht mit der Einstellung " onHostRule +".

Im Abschnitt "+ acme.httpChallenge " können wir angeben, wie Let's Encrypt überprüfen kann, ob das Zertifikat generiert werden soll. Wir konfigurieren es so, dass eine Datei im Rahmen der Herausforderung über den Eintrittspunkt " http +" bereitgestellt wird.

Zuletzt konfigurieren wir den "+ docker +" - Anbieter, indem wir der Datei folgende Zeilen hinzufügen:

traefik.toml

...
[docker]
domain = ""
watch = true
network = "web"

Der Anbieter "+ docker " ermöglicht es Traefik, als Proxy vor Docker-Containern zu agieren. Wir haben den Provider so konfiguriert, dass er nach neuen Containern im Web-Netzwerk sucht (die wir bald erstellen werden) und sie als Subdomains von "+" verfügbar macht.

Zu diesem Zeitpunkt sollte + traefik.toml + den folgenden Inhalt haben:

traefik.toml

defaultEntryPoints = ["http", "https"]

[entryPoints]
 [entryPoints.dashboard]
   address = ":8080"
   [entryPoints.dashboard.auth]
     [entryPoints.dashboard.auth.basic]
       users = [""]
 [entryPoints.http]
   address = ":80"
     [entryPoints.http.redirect]
       entryPoint = "https"
 [entryPoints.https]
   address = ":443"
     [entryPoints.https.tls]

[api]
entrypoint="dashboard"

[acme]
email = ""
storage = "acme.json"
entryPoint = "https"
onHostRule = true
 [acme.httpChallenge]
 entryPoint = "http"

[docker]
domain = ""
watch = true
network = "web"

Speichern Sie die Datei und beenden Sie den Editor. Mit all dieser Konfiguration können wir Traefik starten.

Schritt 2 - Ausführen des Traefik-Containers

Erstellen Sie als Nächstes ein Docker-Netzwerk, das der Proxy für Container freigibt. Das Docker-Netzwerk ist erforderlich, damit wir es mit Anwendungen verwenden können, die mit Docker Compose ausgeführt werden. Nennen wir dieses Netzwerk "+ Web".

docker network create

Wenn der Traefik-Container gestartet wird, werden wir ihn zu diesem Netzwerk hinzufügen. Dann können wir später weitere Container zu diesem Netzwerk hinzufügen, zu denen Traefik einen Proxy erstellen kann.

Erstellen Sie als Nächstes eine leere Datei, die die Informationen zu Let’s Encrypt enthält. Wir geben dies in den Container weiter, damit Traefik es verwenden kann:

touch

Traefik kann diese Datei nur verwenden, wenn der Root-Benutzer im Container einen eindeutigen Lese- und Schreibzugriff darauf hat. Sperren Sie dazu die Berechtigungen für "+ acme.json +", sodass nur der Eigentümer der Datei über Lese- und Schreibrechte verfügt.

chmod 600

Sobald die Datei an Docker übergeben wurde, wechselt der Eigentümer automatisch zum Benutzer * root * im Container.

Erstellen Sie schließlich den Traefik-Container mit diesem Befehl:

docker run -d \
 -v /var/run/docker.sock:/var/run/docker.sock \
 -v $PWD/traefik.toml:/traefik.toml \
 -v $PWD/acme.json:/acme.json \
 -p 80:80 \
 -p 443:443 \
 -l traefik.frontend.rule=Host:monitor. \
 -l traefik.port=8080 \
 --network web \
 --name traefik \
 traefik:1.7.6-alpine

Der Befehl ist etwas lang.

Wir benutzen das + -d + Flag, um den Container im Hintergrund als Daemon auszuführen. Wir geben dann unsere Datei "+ docker.sock " im Container frei, damit der Traefik-Prozess auf Änderungen an Containern achten kann. Wir teilen auch die Konfigurationsdatei " traefik.toml " und die von uns erstellte Datei " acme.json +" mit dem Container.

Als Nächstes ordnen wir die Ports "+ 80 " und " 443 +" unseres Docker-Hosts denselben Ports im Traefik-Container zu, sodass Traefik den gesamten HTTP- und HTTPS-Verkehr zum Server empfängt.

Anschließend richten wir zwei Docker-Labels ein, die Traefik anweisen, den Datenverkehr an den Hostnamen "+ monitor. " Zu leiten, um " 8080 +" innerhalb des Traefik-Containers zu portieren, wodurch das Überwachungs-Dashboard angezeigt wird.

Wir setzen das Netzwerk des Containers auf "+ web " und benennen den Container " traefik +".

Schließlich verwenden wir für diesen Container das "+ traefik: 1.7.6-alpine +" - Bild, da es klein ist.

Ein Docker-Image "+ ENTRYPOINT" ist ein Befehl, der immer ausgeführt wird, wenn ein Container aus dem Image erstellt wird. In diesem Fall ist der Befehl die + traefik + Binärdatei innerhalb des Containers. Sie können diesem Befehl zusätzliche Argumente übergeben, wenn Sie den Container starten, aber wir haben alle unsere Einstellungen in der Datei "+ traefik.toml +" konfiguriert.

Nachdem der Container gestartet wurde, haben Sie jetzt ein Dashboard, auf das Sie zugreifen können, um den Zustand Ihrer Container anzuzeigen. Sie können dieses Dashboard auch verwenden, um die von Traefik registrierten Frontends und Backends anzuzeigen. Greifen Sie auf das Überwachungs-Dashboard zu, indem Sie Ihren Browser auf "+ https: // monitor. +" Zeigen. Sie werden aufgefordert, Ihren Benutzernamen und Ihr Passwort einzugeben. Diese sind * admin * und das Passwort, das Sie in Schritt 1 konfiguriert haben.

Sobald Sie angemeldet sind, sehen Sie eine ähnliche Oberfläche:

Es gibt noch nicht viel zu sehen, aber lassen Sie dieses Fenster geöffnet und Sie werden feststellen, dass sich der Inhalt ändert, wenn Sie Container hinzufügen, mit denen Traefik arbeiten soll.

Unser Traefik-Proxy wird jetzt ausgeführt, ist für die Arbeit mit Docker konfiguriert und kann andere Docker-Container überwachen. Beginnen wir mit einigen Containern, für die Traefik als Proxy fungieren soll.

Schritt 3 - Registrieren von Containern bei Traefik

Wenn der Traefik-Container ausgeführt wird, können Sie die dahinter stehenden Anwendungen ausführen. Lassen Sie uns die folgenden Container hinter Traefik starten:

  1. Ein Blog unter Verwendung des offiziellen Wordpress-Bildes.

  2. Ein Datenbankverwaltungsserver, der das official Adminer-Image verwendet.

Wir verwalten beide Anwendungen mit Docker Compose und verwenden dazu die Datei "+ docker-compose.yml ". Öffnen Sie die Datei ` docker-compose.yml +` in Ihrem Editor:

nano docker-compose.yml

Fügen Sie der Datei die folgenden Zeilen hinzu, um die Version und die zu verwendenden Netzwerke anzugeben:

docker-compose.yml

version: "3"

networks:
 web:
   external: true
 internal:
   external: false

Wir verwenden die Docker Compose-Version "+ 3 +", da dies die neueste Hauptversion des Compose-Dateiformats ist.

Damit Traefik unsere Anwendungen erkennt, müssen sie Teil desselben Netzwerks sein. Da wir das Netzwerk manuell erstellt haben, rufen wir es auf, indem wir den Netzwerknamen "+ web " angeben und " external " auf " true " setzen. Dann definieren wir ein anderes Netzwerk, damit wir unsere exponierten Container mit einem Datenbankcontainer verbinden können, den wir nicht über Traefik verfügbar machen. Wir nennen dieses Netzwerk " intern +".

Als nächstes definieren wir nacheinander jeden unserer "+ Dienste ". Beginnen wir mit dem Container " blog +", der auf dem offiziellen WordPress-Image basiert. Fügen Sie diese Konfiguration zur Datei hinzu:

docker-compose.yml

version: "3"
...

services:
 blog:
   image: wordpress:4.9.8-apache
   environment:
     WORDPRESS_DB_PASSWORD:
   labels:
     - traefik.backend=blog
     - traefik.frontend.rule=Host:blog.
     - traefik.docker.network=web
     - traefik.port=80
   networks:
     - internal
     - web
   depends_on:
     - mysql

Mit der Taste "+ Umgebung" können Sie Umgebungsvariablen angeben, die innerhalb des Containers festgelegt werden. Indem Sie für "+ WORDPRESS_DB_PASSWORD +" keinen Wert festlegen, weisen wir Docker Compose an, den Wert aus unserer Shell abzurufen und ihn beim Erstellen des Containers weiterzuleiten. Wir werden diese Umgebungsvariable in unserer Shell definieren, bevor wir die Container starten. Auf diese Weise geben wir keine Passwörter in die Konfigurationsdatei ein.

Im Abschnitt "+ labels +" geben Sie die Konfigurationswerte für Traefik an. Docker-Etiketten tun nichts für sich, aber Traefik liest diese, damit es weiß, wie Container zu behandeln sind. Die einzelnen Labels haben folgende Funktionen:

  • + traefik.backend + gibt den Namen des Backend-Dienstes in Traefik an (der auf den tatsächlichen + blog + Container verweist).

  • + traefik.frontend.rule = Host: blog. + Weist Traefik an, den angeforderten Host zu untersuchen und den Datenverkehr an den Container "+ blog " weiterzuleiten, wenn er mit dem Muster " blog" übereinstimmt.

  • + traefik.docker.network = web + gibt an, in welchem ​​Netzwerk Traefik nach der internen IP für diesen Container sucht. Da unser Traefik-Container Zugriff auf alle Docker-Informationen hat, würde er möglicherweise die IP für das interne Netzwerk übernehmen, wenn wir dies nicht angeben.

  • + traefik.port + gibt den exponierten Port an, den Traefik verwenden soll, um Verkehr zu diesem Container zu leiten.

Bei dieser Konfiguration wird der gesamte Datenverkehr, der an den Docker-Host-Port "+ 80 " gesendet wird, an den Container " blog +" weitergeleitet.

Wir weisen diesen Container zwei verschiedenen Netzwerken zu, damit Traefik ihn über das "+ web " - Netzwerk finden und über das " interne +" - Netzwerk mit dem Datenbankcontainer kommunizieren kann.

Zuletzt teilt die Taste + depend_on + Docker Compose mit, dass dieser Container nach der Ausführung seiner Abhängigkeiten _ gestartet werden muss. Da WordPress eine Datenbank benötigt, müssen wir unseren mysql-Container ausführen, bevor wir unseren blog-Container starten.

Konfigurieren Sie als Nächstes den MySQL-Dienst, indem Sie diese Konfiguration zu Ihrer Datei hinzufügen:

docker-compose.yml

services:
...
 mysql:
   image: mysql:5.7
   environment:
     MYSQL_ROOT_PASSWORD:
   networks:
     - internal
   labels:
     - traefik.enable=false

Für diesen Container verwenden wir das offizielle MySQL 5.7-Image. Sie werden feststellen, dass wir wieder ein "+ environment " - Element ohne Wert verwenden. Die Variablen ` MYSQL_ROOT_PASSWORD ` und ` WORDPRESS_DB_PASSWORD ` müssen auf denselben Wert gesetzt werden, um sicherzustellen, dass unser WordPress-Container mit MySQL kommunizieren kann. Wir möchten den " mysql" -Container nicht für Traefik oder die Außenwelt verfügbar machen, daher weisen wir diesen Container nur dem "+ internal" -Netzwerk zu. Da Traefik Zugriff auf den Docker-Socket hat, stellt der Prozess weiterhin standardmäßig ein Frontend für den Container "+ mysql " zur Verfügung. Fügen Sie daher die Bezeichnung " traefik.enable = false +" hinzu, um anzugeben, dass Traefik diesen Container nicht zur Verfügung stellen soll .

Fügen Sie abschließend diese Konfiguration hinzu, um den Container "+ adminer +" zu definieren:

docker-compose.yml

services:
...
 adminer:
   image: adminer:4.6.3-standalone
   labels:
     - traefik.backend=adminer
     - traefik.frontend.rule=Host:db-admin.
     - traefik.docker.network=web
     - traefik.port=8080
   networks:
     - internal
     - web
   depends_on:
     - mysql

Dieser Container basiert auf dem offiziellen Administrator-Image. Die Konfiguration von "+ network " und " depend_on " für diesen Container stimmt genau mit der Konfiguration überein, die wir für den Container " blog +" verwenden.

Da wir jedoch den gesamten Datenverkehr auf unserem Docker-Host an den Port "+ 80 " direkt an den Container " blog " weiterleiten, müssen wir diesen Container anders konfigurieren, damit der Datenverkehr an unseren " adminer " weitergeleitet wird `Container. Die Zeile ` traefik.frontend.rule = Host: db-admin. ` Weist Traefik an, den angeforderten Host zu untersuchen. Wenn es mit dem Muster " db-admin. " Übereinstimmt, leitet Traefik den Datenverkehr an den Container " adminer +" weiter.

Zu diesem Zeitpunkt sollte + docker-compose.yml + den folgenden Inhalt haben:

docker-compose.yml

version: "3"

networks:
 web:
   external: true
 internal:
   external: false

services:
 blog:
   image: wordpress:4.9.8-apache
   environment:
     WORDPRESS_DB_PASSWORD:
   labels:
     - traefik.backend=blog
     - traefik.frontend.rule=Host:blog.
     - traefik.docker.network=web
     - traefik.port=80
   networks:
     - internal
     - web
   depends_on:
     - mysql
 mysql:
   image: mysql:5.7
   environment:
     MYSQL_ROOT_PASSWORD:
   networks:
     - internal
   labels:
     - traefik.enable=false
 adminer:
   image: adminer:4.6.3-standalone
   labels:
     - traefik.backend=adminer
     - traefik.frontend.rule=Host:db-admin.
     - traefik.docker.network=web
     - traefik.port=8080
   networks:
     - internal
     - web
   depends_on:
     - mysql

Speichern Sie die Datei und beenden Sie den Texteditor.

Legen Sie als Nächstes in Ihrer Shell Werte für die Variablen + WORDPRESS_DB_PASSWORD + und + MYSQL_ROOT_PASSWORD + fest, bevor Sie Ihre Container starten:

export WORDPRESS_DB_PASSWORD=
export MYSQL_ROOT_PASSWORD=

Ersetzen Sie "+" durch Ihr gewünschtes Datenbankkennwort. Denken Sie daran, dass Sie für " WORDPRESS_DB_PASSWORD " und " MYSQL_ROOT_PASSWORD +" dasselbe Kennwort verwenden.

Führen Sie mit diesen Variablen die Container mit + docker-compose + aus:

docker-compose up -d

Schauen Sie sich jetzt das Traefik-Admin-Dashboard noch einmal an. Sie werden sehen, dass es jetzt ein "+ Backend " und ein " Frontend +" für die beiden exponierten Server gibt:

Navigieren Sie zu "+ blog. " Und ersetzen Sie " your_domain +" durch Ihre Domain. Sie werden zu einer TLS-Verbindung umgeleitet und können nun das Wordpress-Setup abschließen:

Greifen Sie jetzt auf den Administrator zu, indem Sie in Ihrem Browser "+ db-admin. " Aufrufen und " your_domain " durch Ihre Domain ersetzen. Der Container " mysql " ist nicht für die Außenwelt zugänglich, aber der Container " adminer " hat über das interne Docker-Netzwerk, das sie gemeinsam nutzen, Zugriff darauf, indem sie den Containernamen " mysql +" als Hostnamen verwenden.

Verwenden Sie im Administrator-Anmeldebildschirm den Benutzernamen * root *, den Benutzer + mysql für den * Server * und den Wert, den Sie für` + MYSQL_ROOT_PASSWORD` für das Kennwort festgelegt haben. Sobald Sie angemeldet sind, wird die Admin-Benutzeroberfläche angezeigt:

image: https://assets.digitalocean.com/articles/64873_Traefik/Adminer_MySQL_database.png [Administrator mit Verbindung zur MySQL-Datenbank]

Beide Sites funktionieren jetzt, und Sie können das Dashboard unter "+ monitor. +" Verwenden, um Ihre Anwendungen im Auge zu behalten.

Fazit

In diesem Lernprogramm haben Sie Traefik so konfiguriert, dass Anforderungen an andere Anwendungen in Docker-Containern weitergeleitet werden.

Die deklarative Konfiguration von Traefik auf der Ebene der Anwendungscontainer erleichtert die Konfiguration weiterer Dienste, und es ist nicht erforderlich, den "+ traefik +" - Container neu zu starten, wenn Sie dem Proxy-Verkehr neue Anwendungen hinzufügen, da Traefik die Änderungen sofort über die Docker-Socket-Datei bemerkt, die überwacht wird .

Weitere Informationen zu den Funktionen von Traefik finden Sie in der offiziellen Traefik documentation. Weitere Informationen zu Docker-Containern finden Sie unter https://www.digitalocean.com/community/tutorials/how-to-set-up-a-private-docker-registry-on-ubuntu-18-04 [Einrichten einer privaten Docker-Registrierung unter Ubuntu 18.04] oder https://www.digitalocean.com/community/tutorials/how-to-secure-a-containerized-node-js-application-with-nginx-let- s-encrypt-and-docker-compose [So sichern Sie eine containerisierte Node.js-Anwendung mit Nginx, Let’s Encrypt und Docker Compose].