Telefon-Support: +49 2238 570070
docker,concepts

Reverse Proxy für Docker Services: Træfik

6. August 2017 Leseszeit ~3 Min

Die ersten Schritte in Docker gehen leicht von der Hand, doch möchten wir diverse Microservices auf dem Docker-Hostsystem betreiben, die unter verschiedenen Domainnamen erreichbar sind, wird es schnell kompliziert:

  • nginx-Container aufsetzen
  • nginx-config-Files erstellen
  • nginx im container nach der Änderung neu laden

… usw. usf. - das fühlt sich “nicht richtig” an und sollte doch automatisierbar sein!

Json Wilder muss ähnliches gedacht haben und hat eine schöne Lösung entwickelt, aber KISS sieht für uns definitiv anders aus.

Traefik - Reverse Proxy dynamisch konfiguriert

Traefik ist zunächst einmal ein in golang geschriebener Reverse Proxy: Regeln definieren, wie ein “Frontend” mit einem “Backend” verbunden werden. “Frontend” steht hier für einen Domainnamen wie z.B: api.intertech.de oder eine URL “http://intertech.de/blog”, mit “Backend” ist der installierte WebService gemeint. Der entscheidende Vorteil ist, dass Traefik seine Konfiguration aus diversen Backends beziehen kann und bei Änderungen dynamisch die Regeln anpasst.

Traefik-Flow

Traefik Regeln mit docker service labels definieren

In der einfachste Variante lässt sich Traefik über docker service-labels steuern:

labels:
      - "traefik.backend=restapi"
      - "traefik.frontend.rule=Host:api.intertech.de"
      - "traefik.enable=true"
      - "traefik.port=8080"

Hier definieren wir unseren docker-container als Backend mit dem Namen “restapi” und legen fest, dass Traefik den Datenverkehr für die Domain “api.intertech.de” an unseren Docker-Container auf Port 8080 leitet. Natürliche gibt es noch deutlich mehr mögliche Optionen, die Sie hier finden.

Neben der Variante, die “Labels” verwendet, stehen für größere Installationen auch Backends für diverse KV-Stores wie etcd oder consul zu Verfügung. Genaueres ist in der recht guten Dokumentation der Konfigurations Backends zu finden.

Traefik einsetzen

Wir starten Traefik in einem eigenen docker container. Dabei erhält der Container Zugriff auf docker.sock, sodass dieser mit dem Docker-Daemon des Host-Systems kommunizieren kann. Die Basiskonfiguration erfolgt exemplatisch über diese einfache traefik.toml Datei:

logLevel = "DEBUG"
defaultEntryPoints = ["http", "https"]

# WEB interface of Traefik - it will show web page with overview of frontend and backend configurations 
[web]
address = ":8080"

# Connection to docker host system (docker.sock)
[docker]
domain = "docker.localhost"
watch = true
# This will hide all docker containers that don't have explicitly
# set label to "enable"
exposedbydefault = false

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

# Let's encrypt configuration
[acme]
  email="noc@intertech.de"
  storage="/etc/traefik/acme/acme.json"
  entryPoint="https"
  acmeLogging=true
  onDemand=true
  OnHostRule=true

Der Großteil der Datei ist ziemlich selbsterklärend — das LogLevel wird gesetzt, http und https werden aktiviert, die Verbindung zum docker-daemon auf dem host wird hergestellt und https wird erzwungen (Datenverkehr für Port 80 wird auf Port 443 umgeleitet).

Ein sehr schönes Feature wird im letzte Teil der Datei konfiguriert — acme. Komplett dynamisch wird die Verbindung zu “Let’s encrypt” hergestellt: Für jede “Frontend-Domain” initiiert Traefik die Ausstellung eines SSL-Zertifikats bei “Let’s encrypt” und speichert den Schlüssel und das Zertifikat in der Datei acme.json!

Beispiel-Konfiguration mit docker-compose

docker-compose.yml:

version: '2'

services:
  proxy:
    image: traefik
    command: --logLevel=DEBUG
    networks:
      - reverseproxy
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - $PWD/conf/traefik.toml:/etc/traefik/traefik.toml
      - TraefikAcme:/etc/traefik/acme

networks:
  reverseproxy:
    driver: bridge
volumes:
  TraefikAcme:

Testcontainer:

docker run -d \
     --name whoami1 \
     --label traefik.port=80 \
     --label traefik.enable=true \
     --label traefik.frontend.rule=Host:v-10271.cloud.intertech.de\
     --network traefik_reverseproxy \
     emilevauge/whoami

Ergebnis prüfen:

mbp5:www.intertech.de ff$ curl -i https://v-10271.cloud.intertech.de/
HTTP/1.1 200 OK
Content-Length: 322
Content-Type: text/plain; charset=utf-8
Date: Wed, 23 Aug 2017 10:28:46 GMT

Hostname: 0fe2ec5ea235
IP: 127.0.0.1
IP: 172.18.0.3
GET / HTTP/1.1
Host: v-10271.cloud.intertech.de
User-Agent: curl/7.40.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 5.146.38.4
X-Forwarded-Host: v-10271.cloud.intertech.de
X-Forwarded-Port: 80
X-Forwarded-Proto: https
X-Forwarded-Server: 73196f83f043