Docker

Traefik 2.0

A Story of Labels & Containers

Die Umstellung von Version 1.x auf 2.0

Es ist schon ein paar Monate her da erschien die Version 2.0 des Edge Routers Traefik. Die Architektur von diesem Tool wurde in Version 2.0 neu gedacht. Es gibt nun kein Frontend & Backend mehr, sondern es gibt Router, Service und Middlewares. Die Umstellung sollte so einige Hinterhindernisse bereithalten, von den ich gern berichten möchte.

Die Anwendungen welche durch Traefik erreichbar gemacht werden sollten sind alle in Docker Container zu Hause, das versteht sich ja von selbst im Jahre 2019 ;-). Über einfache Labels an diesen Containern registrierten sie sich selbstständig am Treafik. Es war und ist eine reine Freude zu sehen wie dies im laufenden Betrieb erfolgt ohne Anpassungen am Traefik vornehmen zu müssen. Man startet einfach eine Anwendung wie zum Beispiel Portainer und schreibt an paar Label an den Container und schon ist die Anwendung erreichbar.

Zur Absicherung der Kommunikation via HTTPs wird im folgenden Szenario von einem klassischen Wildcard Zertifikat gebrauch gemacht. Die einzige zusätzliche Funktion, welche der Traefik übernimmt, ist die Weiterleitung von HTTP auf HTTPs.

 

Am Inhalt des docker-compose Files ändert sich noch nicht viel. Neu ist es gibt nun zwei Config-Files die die Steuerung übernehmen. Sicherlich könnte man die Konfiguration auch rein via ENVs setzten, aber so paar TOML Dateien sind ja auch ganz schön und es ließt sich dort schlüssig in der TOML Syntax.
Da ein klassisches Wildcard Zertifikat zum Einsatz kommen soll, wird dieses in den Container mit rein gemountet.


version: '3'
services:
  traefik:
    image: traefik:montdor #2
    restart: always
    container_name: traefik
    ports:
      - 80:80
      - 443:443
    networks:
      - web
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./traefik.toml:/traefik.toml
      - ./dynamic-config.toml:/dynamic-config.toml
      - /etc/ssl/private/{yourdomain}:/ssl_private

networks: 
  web: 
    external: true

 

Der Inhalt der traefik.toml wurde stark verringert. Es steuert nun nur noch die festen Einstellungen der Anwendung.


[global]
  checkNewVersion = true
  sendAnonymousUsage = false
  
[entryPoints]
  [entryPoints.web]
    address = ":80"
  [entryPoints.web-secure]
    address = ":443"

[providers]
  [providers.file]
    filename = "/dynamic-config.toml"
    watch = true
    debugLogGeneratedTemplate = true
  [providers.docker]
    endpoint = "unix:///var/run/docker.sock"
    #so the container need a label 'traefik.enable=true'
    exposedByDefault = false

[api]
  dashboard = true
  debug = false
  insecure = false # access the dashboard on the port 8080

[log]
  level = "INFO"

Man muss nun etwas Umdenken denn so manche Settings sind an eine andere Stelle gewandert. Die restliche Config kommt über Provider, so gibt es zum Beispiel den File-Provider, dieser übernimmt den restlichen Teil der Config für den Treafik. Die Datei trägt zwar den Namen dynamic-config.toml, ist aber in diesem Setting eher eine feste Datei.


# https://docs.traefik.io/reference/dynamic-configuration/file/

[http]

  [http.routers]
    [http.routers.api]
      rule = "Host(`traefik.{yourdomain}`)"
      entrypoints = ["web"]
      service = "api@internal"
      middlewares = ["api-schemeredirect"]
    [http.routers.api-secure]
      rule = "Host(`traefik.{yourdomain}`)"
      entrypoints = ["web-secure"]
      service = "api@internal"
      middlewares = ["api-login"]
      [http.routers.api-secure.tls]
        options = "default"

  [http.middlewares]
    [http.middlewares.api-schemeredirect.redirectScheme]
      scheme = "https"
    [http.middlewares.api-login.basicAuth]
      users = ["admin:xxxx"]


[tls]

  [tls.options]
    [tls.options.default]
      sniStrict = false # need by wildcard cert
      minVersion = "VersionTLS12"

  [tls.stores]
    [tls.stores.default]
      [tls.stores.default.defaultCertificate]
        certFile = "/ssl_private/{yourdomain}.crt"
        keyFile = "/ssl_private/{yourdomain}.key"

Es hat eine Weile gedauert bis die Config so geschrieben war, dass sie auch korrekt arbeitet. Etwas knifflig war das das Wildcard Zertifikat korrekt genutzt wurde, hier war sniStrict = false das entscheidende Setting.

Etwas ungewohnt ist der simple redirect von http auf https, da eine Kette von Router, Middelware und Service hierzu separat definiert wird. Aber das schöne ist ja, wenn so eine Config einmal steht und läuft, kann man sie bis zum nächsten Breaking Change verwenden 🙂

 

Jetzt muss man nur noch die Label an den Containern verändern, welche sich am Treafik registrieren sollen. Je nach Funktionen, welche der Traefik übernehmen soll kann die Label Liste schon mal etwas länger werden, aber wahrscheinlich gewöhnt man sich recht schnell auch daran.


version: '3.3'

services:
  portainer:
    image: portainer/portainer
    command: -H unix:///var/run/docker.sock --admin-password 'abcdef....'
    restart: always
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - portainer_data:/data
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=web"
      - "traefik.http.routers.portainer_router.entrypoints=web"
      - "traefik.http.routers.portainer_router.rule=Host(`portainer.{yourdomain}`)"
      - "traefik.http.routers.portainer_router.middlewares=portainer_middleware@docker"
      - "traefik.http.routers.portainer_router.service=portainer_service@docker"
      - "traefik.http.middlewares.portainer_middleware.redirectscheme.scheme=https"
      - "traefik.http.routers.portainer_router_ssl.entrypoints=web-secure"
      - "traefik.http.routers.portainer_router_ssl.rule=Host(`portainer.{yourdomain}`)"
      - "traefik.http.routers.portainer_router_ssl.tls=true"
      - "traefik.http.routers.portainer_router_ssl.tls.options=default"
      - "traefik.http.routers.portainer_router_ssl.service=portainer_service@docker"
      - "traefik.http.services.portainer_service.loadbalancer.server.port=9000"
    networks:
      - web

networks:
  web:
    external: true

volumes:
  portainer_data: