Verwendung von Traefik als Reverse Proxy für Docker-Container unter Ubuntu 18.04

Der Autor hatGirls Who Code ausgewählt, um eine Spende im Rahmen desWrite for DOnations-Programms zu erhalten.

Einführung

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 Ports80 und443 für den Rest der Welt verfügbar machen möchten.

Traefik ist ein Docker-fähiger Reverse-Proxy, der ein eigenes Überwachungs-Dashboard enthält. In diesem Lernprogramm verwenden Sie Traefik, um Anforderungen an zwei verschiedene Webanwendungscontainer weiterzuleiten: einenWordpress-Container und einenAdminer-Container, die jeweils mit einerMySQL-Datenbank kommunizieren. Sie konfigurieren Traefik so, dass mitLet’s Encrypt alles über HTTPS bereitgestellt wird.

Voraussetzungen

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

[[Schritt-1 - Konfigurieren und Ausführen von Traefik]] == Schritt 1 - Konfigurieren und Ausführen von Traefik

Das Traefik-Projekt hat einofficial Docker image, daher werden wir dieses verwenden, um Traefik in einem Docker-Container auszuführen.

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

Wir werden das Dienstprogrammhtpasswdverwenden, um dieses verschlüsselte Passwort zu erstellen. Installieren Sie zunächst das Dienstprogramm, das im Paketapache2-utilsenthalten ist:

sudo apt-get install apache2-utils

Generieren Sie dann das Passwort mithtpasswd. Ersetzen Siesecure_password durch das Kennwort, das Sie für den Traefik-Administrator verwenden möchten:

htpasswd -nb admin secure_password

Die Ausgabe des Programms sieht folgendermaßen aus:

Outputadmin:$apr1$ruca84Hq$mbjdMZBAG.KWn7vfN/SNK/

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 Namentraefik.toml im TOML-Format. TOML ist eine Konfigurationssprache ähnlich wie INI-Dateien, jedoch standardisiert. Mit dieser Datei können wir den Traefik-Server und verschiedene Integrationen oderproviderskonfigurieren, die wir verwenden möchten. In diesem Tutorial werden drei der verfügbaren Traefik-Anbieter verwendet:api,docker undacme, mit denen TLS mithilfe von Let's Encrypt unterstützt wird.

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

nano traefik.toml

Fügen Sie zunächst zwei benannte Einstiegspunkte hinzu,http undhttps, auf die standardmäßig alle Backends Zugriff haben:

traefik.toml

defaultEntryPoints = ["http", "https"]

Wir werden die Einstiegspunktehttp undhttpspäter in dieser Datei konfigurieren.

Konfigurieren Sie als Nächstes den Anbieter vonapi, über den Sie auf eine Dashboard-Oberfläche zugreifen können. Hier fügen Sie die Ausgabe des Befehlshtpasswdein:

traefik.toml

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

[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 Port8080 ausgeführt wird.

Im Abschnittentrypoints.dashboardwird konfiguriert, wie wir uns mit dem Anbieter vonapiverbinden, und im Abschnittentrypoints.dashboard.auth.basicwird die HTTP-Basisauthentifizierung für das Dashboard konfiguriert. Verwenden Sie die Ausgabe des Befehlshtpasswd, den Sie gerade ausgeführt haben, für den Wert des Eintragsusers. Sie können zusätzliche Anmeldungen angeben, indem Sie sie durch Kommas trennen.

Wir haben unsere erstenentryPointdefiniert, aber wir müssen andere für die Standard-HTTP- und HTTPS-Kommunikation definieren, die nicht an denapi-Anbieter gerichtet ist. Der AbschnittentryPoints konfiguriert die Adressen, die Traefik und die Proxy-Container abhören können. Fügen Sie diese Zeilen der Datei unter der ÜberschriftentryPointshinzu:

traefik.toml

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

Der Einstiegspunkt vonhttpbehandelt Port80, während der Einstiegspunkt vonhttpsPort443 für TLS / SSL verwendet. Wir leiten den gesamten Datenverkehr auf Port80 automatisch zum Einstiegspunkt vonhttpsum, 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 = "your_email@your_domain"
storage = "acme.json"
entryPoint = "https"
onHostRule = true
  [acme.httpChallenge]
  entryPoint = "http"

Dieser Abschnitt heißtacme, daACME der Name des Protokolls ist, das für die Kommunikation mit Let's Encrypt zur Verwaltung von Zertifikaten verwendet wird. Für den Let's Encrypt-Dienst ist eine Registrierung mit einer gültigen E-Mail-Adresse erforderlich. Damit Traefik Zertifikate für unsere Hosts generieren kann, setzen Sie den Schlüsselemailauf Ihre E-Mail-Adresse. Anschließend geben wir an, dass wir die Informationen, die wir von Let's Encrypt erhalten, in einer JSON-Datei mit dem Namenacme.json speichern. Der SchlüsselentryPointmuss auf den Einstiegspunkt zeigen, der Port443 verarbeitet, in unserem Fall den Einstiegspunkthttps.

Der SchlüsselonHostRulebestimmt, wie Traefik Zertifikate generieren soll. Wir möchten unsere Zertifikate abrufen, sobald unsere Container mit den angegebenen Hostnamen erstellt wurden. Dies ist die Einstellung vononHostRule.

Im Abschnittacme.httpChallengekönnen Sie angeben, wie Let's Encrypt überprüfen kann, ob das Zertifikat generiert werden soll. Wir konfigurieren es so, dass eine Datei als Teil der Herausforderung über den Einstiegspunkt vonhttpbereitgestellt wird.

Zum Schluss konfigurieren wir dendocker-Anbieter, indem wir der Datei folgende Zeilen hinzufügen:

traefik.toml

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

Derdocker-Anbieter ermöglicht es Traefik, als Proxy vor Docker-Containern zu fungieren. Wir haben den Anbieter für neue Container imweb-Netzwerk (das wir bald erstellen werden) aufwatch konfiguriert und sie als Subdomänen vonyour_domain verfügbar gemacht.

Zu diesem Zeitpunkt solltetraefik.toml den folgenden Inhalt haben:

traefik.toml

defaultEntryPoints = ["http", "https"]

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

[api]
entrypoint="dashboard"

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

[docker]
domain = "your_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]] == 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 Netzwerkweb.

docker network create web

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 acme.json

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üracme.json, sodass nur der Eigentümer der Datei über Lese- und Schreibberechtigungen verfügt.

chmod 600 acme.json

Sobald die Datei an Docker übergeben wurde, wechselt der Eigentümer automatisch zum Benutzerrootim 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.your_domain \
  -l traefik.port=8080 \
  --network web \
  --name traefik \
  traefik:1.7.2-alpine

Der Befehl ist etwas lang.

Wir verwenden das Flag-d, um den Container im Hintergrund als Daemon auszuführen. Anschließend teilen wir unseredocker.sock-Datei mit dem Container, damit der Traefik-Prozess auf Änderungen an Containern warten kann. Wir teilen auch die Konfigurationsdatei vontraefik.tomlund die von uns erstellte Datei vonacme.jsonim 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 Hostnamenmonitor.your_domain an Port:8080 im Traefik-Container weiterzuleiten, wodurch das Überwachungs-Dashboard verfügbar gemacht wird.

Wir setzen das Netzwerk des Containers aufweb und nennen den Containertraefik.

Schließlich verwenden wir dastraefik:1.7.2-alpine-Bild für diesen Container, da er klein ist.

ENTRYPOINTeines Docker-Images ist ein Befehl, der immer ausgeführt wird, wenn ein Container aus dem Image erstellt wird. In diesem Fall ist der Befehl die Binärdatei vontraefikim Container. Sie können diesem Befehl zusätzliche Argumente übergeben, wenn Sie den Container starten. Wir haben jedoch alle Einstellungen in der Dateitraefik.tomlkonfiguriert.

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 aufhttps://monitor.your_domain richten. Sie werden aufgefordert, Ihren Benutzernamen und Ihr Kennwort einzugeben. Dies sindadmin und das Kennwort, das Sie in Schritt 1 konfiguriert haben.

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

Empty Traefik dashboard

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 mit Traefik] == 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 Cotainer hinter Traefik starten:

  1. Ein Blog mitofficial Wordpress image.

  2. Ein Datenbankverwaltungsserver, derofficial Adminer image verwendet.

Wir werden diese beiden Anwendungen mit Docker Compose mithilfe einerdocker-compose.yml-Datei verwalten. Öffnen Sie die Dateidocker-compose.ymlin 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-Version3, 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, ziehen wir es ein, indem wir den Netzwerknamenweb angeben undexternal auftrueetzen ) s. 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 Netzwerkinternal.

Als Nächstes definieren wir jedes unsererserviceseinzeln. Beginnen wir mit dem Containerblog, 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.your_domain
      - traefik.docker.network=web
      - traefik.port=80
    networks:
      - internal
      - web
    depends_on:
      - mysql

Mit dem Schlüsselenvironmentkönnen Sie Umgebungsvariablen angeben, die im Container festgelegt werden. Wenn Sie keinen Wert fürWORDPRESS_DB_PASSWORD festlegen, weisen Sie Docker Compose an, den Wert aus unserer Shell abzurufen und 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 Abschnittlabels geben Sie 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ächlichenblog-Container verweist).

  • traefik.frontend.rule=Host:blog.your_domain weist Traefik an, den angeforderten Host zu untersuchen. Wenn er mit dem Muster vonblog.your_domain übereinstimmt, sollte der Datenverkehr zum Containerbloggeleitet werden.

  • traefik.docker.network=web gibt an, unter welchem ​​Netzwerk nach Traefik gesucht werden soll, um die interne IP für diesen Container zu finden. Da unser Traefik-Container Zugriff auf alle Docker-Informationen hat, wird möglicherweise die IP-Adresse für dasinternal-Netzwerk verwendet, wenn wir dies nicht angeben.

  • traefik.port gibt den exponierten Port an, über den Traefik den Verkehr zu diesem Container leiten soll.

Mit dieser Konfiguration wird der gesamte Datenverkehr, der an den Port80 unseres Docker-Hosts gesendet wird, an den Containerblogweitergeleitet.

Wir weisen diesen Container zwei verschiedenen Netzwerken zu, damit Traefik ihn über das Netzwerk vonwebfinden und über das Netzwerk voninternalmit dem Datenbankcontainer kommunizieren kann.

Zuletzt teilt der Schlüsseldepends_onDocker Compose mit, dass dieser Containeraftertarten muss, wenn seine Abhängigkeiten ausgeführt werden. Da WordPress zum Ausführen eine Datenbank benötigt, müssen wir unserenmysql-Container ausführen, bevor wir unserenblog-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 einenenvironment-Element ohne Wert verwenden. Die VariablenMYSQL_ROOT_PASSWORD undWORDPRESS_DB_PASSWORD müssen auf denselben Wert gesetzt werden, um sicherzustellen, dass unser WordPress-Container mit MySQL kommunizieren kann. Wir möchten den Containermysqlnicht Traefik oder der Außenwelt aussetzen, daher weisen wir diesen Container nur dem Netzwerkinternalzu. Da Traefik Zugriff auf den Docker-Socket hat, stellt der Prozess standardmäßig weiterhin ein Frontend für denmysql-Container bereit. Daher fügen wir die Bezeichnungtraefik.enable=false hinzu, um anzugeben, dass Traefik diesen Container nicht verfügbar machen soll.

Fügen Sie abschließend diese Konfiguration hinzu, um den Administrator-Container zu definieren:

docker-compose.yml

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

Dieser Container basiert auf dem offiziellen Administrator-Image. Die Konfiguration vonnetwork unddepends_on für diesen Container entspricht genau der Konfiguration, die wir für den Containerblog verwenden.

Da wir jedoch den gesamten Datenverkehr an Port80 auf unserem Docker-Host direkt an denblog-Container weiterleiten, müssen wir diesen Container anders konfigurieren, damit der Datenverkehr an unseren80-Container gelangt. t2) s Behälter. Die Zeiletraefik.frontend.rule=Host:db-admin.your_domain weist Traefik an, den angeforderten Host zu untersuchen. Wenn es mit dem Muster vondb-admin.your_domain übereinstimmt, leitet Traefik den Verkehr zum Containeradminerweiter.

Zu diesem Zeitpunkt solltedocker-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.your_domain
      - 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.your_domain
      - 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 VariablenWORDPRESS_DB_PASSWORD undMYSQL_ROOT_PASSWORD fest, bevor Sie Ihre Container starten:

export WORDPRESS_DB_PASSWORD=secure_database_password
export MYSQL_ROOT_PASSWORD=secure_database_password

Ersetzen Siesecure_database_password durch Ihr gewünschtes Datenbankkennwort. Denken Sie daran, fürWORDPRESS_DB_PASSWORD undMYSQL_ROOT_PASSWORD dasselbe Passwort zu verwenden.

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

docker-compose up -d

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

Populated Traefik dashboard

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

WordPress setup screen

Greifen Sie jetzt auf Adminer zu, indem Siedb-admin.your_domain in Ihrem Browser besuchen undyour_domain erneut durch Ihre Domain ersetzen. Dermysql-Container ist nicht der Außenwelt ausgesetzt, aber deradminer-Container hat Zugriff über dasinternal-Docker-Netzwerk, das er unter Verwendung desmysql-Containernamens als teilt ein Hostname.

Verwenden Sie auf dem Adminer-Anmeldebildschirm den Benutzernamenroot,mysql fürserver und den Wert, den Sie fürMYSQL_ROOT_PASSWORD für das Kennwort festgelegt haben. Sobald Sie angemeldet sind, wird die Admin-Benutzeroberfläche angezeigt:

Adminer connected to the MySQL database

Beide Sites funktionieren jetzt und Sie können das Dashboard beimonitor.your_domain 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 Anwendungscontainerebene erleichtert das Konfigurieren weiterer Dienste, und es ist nicht erforderlich, dentraefik-Container neu zu starten, wenn Sie dem Proxy-Verkehr neue Anwendungen hinzufügen, da Traefik die Änderungen sofort über die Docker-Socket-Datei bemerkt Überwachung.

Um mehr darüber zu erfahren, was Sie mit Traefik tun können, gehen Sie zu den offiziellenTraefik documentation.