Introduction to Traefik 2.0

Traefik is an open source reverse proxy for easy handling of microservices and / or just containers with your applications.



The reverse proxy server (reverse proxy, reverse proxy) is used to relay requests from the external network to any servers / services on the internal network (for example, a web server, database or file storage) and allows:



  • ensure the concealment of the structure of the internal network and details about the services located in it;
  • balancing load (load balancing) between instances of the same service or servers with the same tasks;
  • provide an encrypted (HTTPS) connection between the client and any service, in this case an SSL session is created between the client and the proxy, and an unencrypted HTTP connection is established between the proxy and the service on the internal network, if the service supports HTTPS, then you can organize an encrypted connection on the internal network;
  • organize access control to services (client authentication), as well as set up a firewall (firewall).


This article will describe using Traefik in Docker as a reverse proxy for other Docker containers as well as non-containerized services.



image



Introduction



Traefik β€œEdge Router”, . , , : -, Traefik ; -, Traefik EE β€” , HA (Hight Availability, ), (), , . , Traefik.



Traefik (β€œ ”) , .



:



  • Docker
  • Kubernetes
  • Consul Catalog
  • Marathon
  • Rancher
  • File


.

, , β€” β€œFile”, ( ), - , , -. .



Traefik, β€œFile” TOML YAML, YAML , - , . Traefik Docker. docker-compose, .



* Linux.



Traefik



docker docker-compose, .



traefik, ,



mkdir ~/traefik
cd ~/traefik


() Traefik docker-compose.yml . :



version: '3'
services:
  traefik:
    image: traefik:v2.2
    container_name: traefik
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    ports:
      - 80:80
      - 443:443 
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./data/traefik.yml:/traefik.yml:ro


80 443 HTTP HTTPS . Docker . Traefik traefik.yml data .



networks Docker-, Traefik .

.



( , ):



entryPoints:
  http:
    address: ":80"
  https:
    address: ":443"


http https ( , a b) .



β€” Docker, :



providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false


Traefik , . β€” Traefik ( ).



HTTP HTTPS ( ):



http:
  routers:
    http-catchall:
      rule: HostRegexp(`{host:.+}`)
      entrypoints:
      - http
      middlewares:
      - redirect-to-https
  middlewares:
    redirect-to-https:
      redirectScheme:
        scheme: https
        permanent: false


Traefik HTTP , TCP UDP, http.



Traefik 2 routers () middlewares( ), .





:



  • http-catchall β€” , , http Traefik;
  • rule: β€” , , HostRegexp, Host .+ ( ), Traefik β€” (host ), {name:reg_exp};
  • entrypoints β€” , , http;
  • middlewares β€” , ( ).


.





  • redirect-to-https β€” , , http Traefik;
  • redirectScheme β€” , ;
  • scheme: https β€” HTTPS ;
  • permanent: false β€” .


( β€” BasicAuth).



traefik.yml
entryPoints:
  http:
    address: ":80"
  https:
    address: ":443"

http:
  routers:
    http-catchall:
      rule: hostregexp(`{host:.+}`)
      entrypoints:
      - http
      middlewares:
      - redirect-to-https
  middlewares:
    redirect-to-https:
      redirectScheme:
        scheme: https
        permanent: false

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false


.



sudo docker-compose up -d


, (sudo docker-compose logs -f) , .



Let's Encrypt



HTTPS - SSL , , Let's Encrypt.



(traefik.yml) :



certificatesResolvers:
  letsEncrypt:
    acme:
      email: postmaster@example.com
      storage: acme.json
      caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"
      httpChallenge:
        entryPoint: http


:



  • letsEncrypt β€” ;
  • acme β€” ( - );
  • storage β€” , ;
  • httpChallenge β€” acme-, β€” ;
  • caServer: "https://acme-staging-v02.api.letsencrypt.org/directory" β€” Let's Encrypt , API ( , ).


volumes docker-compose.yml, ( data/acme.json):



    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./data/traefik.yml:/traefik.yml:ro
      - ./data/acme.json:/acme.json


Docker



HTTPS , , Traefik, Traefik Docker, .



Docker Traefik (labels) . docker-compose.yml:



    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik.entrypoints=https"
      - "traefik.http.routers.traefik.rule=Host(`traefik.example.com`)"
      - "traefik.http.routers.traefik.tls=true"
      - "traefik.http.routers.traefik.tls.certresolver=letsEncrypt"
      - "traefik.http.routers.traefik.service=api@internal"
      - "traefik.http.services.traefik-traefik.loadbalancer.server.port=888"


:

traefik.enable=true β€” Traefik , ;

traefik.http.routers.traefik.entrypoints=https β€” https;

traefik.http.routers.traefik.rule=Host(traefik.example.com) β€” traefik.example.com;

traefik.http.routers.traefik.tls=true β€” TLS;

traefik.http.routers.traefik.tls.certresolver=letsEncrypt β€” ;

traefik.http.routers.traefik.service=api@internal β€” , β€” api@internal, , , ;

traefik.http.services.traefik-traefik.loadbalancer.server.port=888 β€” , , .



, traefik.yml:



api:
  dashboard: true


( docker-compose.yml):



sudo docker-compose down && sudo docker-compose up -d


traefik.example.com ( , Traefik) .



, , , BasicAuth, Traefik middleware.



(admin/password)^



$ htpasswd -nb admin password
admin:$apr1$vDSqkf.v$GTJOtsd9CBiAFFnHTI2Ds1


docker-compose.yml :



      - "traefik.http.middlewares.traefik-auth.basicauth.users=admin:$$apr1$$vDSqkf.v$$GTJOtsd9CBiAFFnHTI2Ds1"
      - "traefik.http.routers.traefik.middlewares=traefik-auth"


, $ $$.

traefik.http.middlewares.traefik-auth.basicauth.users=... β€” middleware basicauth users;

traefik.http.routers.traefik.middlewares=traefik-auth β€” traefik - middleware.



docker-compose.yml
version: '3'
services:
  traefik:
    image: traefik:v2.2
    container_name: traefik
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    ports:
      - 80:80
      - 443:443 
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./data/traefik.yml:/traefik.yml:ro
      - ./data/acme.json:/acme.json
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik.entrypoints=https"
      - "traefik.http.routers.traefik.rule=Host(`traefik.example.com`)"
      - "traefik.http.routers.traefik.tls=true"
      - "traefik.http.routers.traefik.tls.certresolver=letsEncrypt"
      - "traefik.http.routers.traefik.service=api@internal"
      - "traefik.http.services.traefik-traefik.loadbalancer.server.port=888"
      - "traefik.http.middlewares.traefik-auth.basicauth.users=admin:$$apr1$$vDSqkf.v$$GTJOtsd9CBiAFFnHTI2Ds1"
      - "traefik.http.routers.traefik.middlewares=traefik-auth"


.



, docker-compose ( docker):



    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.test.entrypoints=https"
      - "traefik.http.routers.test.rule=Host(`test.example.com`)"
      - "traefik.http.routers.test.tls=true"
      - "traefik.http.routers.test.tls.certresolver=letsEncrypt"
      - "traefik.http.services.test-service.loadbalancer.server.port=80"


traefik.http.services.test-service.loadbalancer.server.port=80 β€” test-service 80, test, Traefik , .



File



, - ( IP 192.168.1.222 8080) , HTTPS. .



docker-compose.yml volume:



    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./data/traefik.yml:/traefik.yml:ro
      - ./data/custom/:/custom/:ro
      - ./data/acme.json:/acme.json


data/custom/ ( , ).



traefik.yml file :



providers:
...
  file:
    directory: /custom
    watch: true


docker-compose.yml, watch: true Traefik ( β€œ ”, , ).



Traefik (data/custom/host.yml):



http:
  routers:
    host:
      entryPoints: 
      - https
      service: service-host
      rule: Host(`host.example.com`) 
      tls:
        certResolver: letsEncrypt
  services:
    service-host:  
      loadBalancer:
        servers:
        - url: http://192.168.1.222:8080/
        passHostHeader: true 


, service: service-host β€” , TLS.



:



_:
  loadBalancer:
    servers:
    -    
    - ...


passHostHeader: true , .





:



docker-compose.yml
version: '3'
services:
  traefik:
    image: traefik:v2.2
    container_name: traefik
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    ports:
      - 80:80
      - 443:443 
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./data/traefik.yml:/traefik.yml:ro
      - ./data/custom/:/custom/:ro
      - ./data/acme.json:/acme.json
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik.entrypoints=https"
      - "traefik.http.routers.traefik.rule=Host(`traefik.example.com`)"
      - "traefik.http.routers.traefik.tls=true"
      - "traefik.http.routers.traefik.tls.certresolver=letsEncrypt"
      - "traefik.http.routers.traefik.service=api@internal"
      - "traefik.http.services.traefik-traefik.loadbalancer.server.port=888"
      - "traefik.http.middlewares.traefik-auth.basicauth.users=admin:$$apr1$$vDSqkf.v$$GTJOtsd9CBiAFFnHTI2Ds1"
      - "traefik.http.routers.traefik.middlewares=traefik-auth"


data/traefik.yml
api:
  dashboard: true

entryPoints:
  http:
    address: ":80"
  https:
    address: ":443"

http:
  routers:
    http-catchall:
      rule: hostregexp(`{host:.+}`)
      entrypoints:
      - http
      middlewares:
      - redirect-to-https
  middlewares:
    redirect-to-https:
      redirectScheme:
        scheme: https
        permanent: false

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
  file:
    directory: /custom
    watch: true

certificatesResolvers:
  letsEncrypt:
    acme:
      email: postmaster@example.com
      storage: acme.json
      #caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"
      httpChallenge:
        entryPoint: http


data/custom/host.yml
http:
  routers:
    host:
      entryPoints: 
      - https
      service: service-host
      rule: Host(`host.example.com`) 
      tls:
        certResolver: letsEncrypt
  services:
    service-host:  
      loadBalancer:
        servers:
        - url: http://192.168.1.222:8080/
        passHostHeader: true 


Traefik HTTP Docker File. SSL Let's Encrypt, HTTPS, .



TCP UDP ( , β€” TCP), , Traefik .



.



Traefik allows you to collect information about your work in various formats, let's see how this is done when using Prometheus.



Add a new entry point

data/traefik.yml::



entryPoints:
...
  metrics:
    address: ":8082"


docker-compose.yml:



    ports:
      - 80:80
      - 443:443 
      - 8082:8082


And add the ability to collect metrics for Prometheus from this port data/traefik.yml:



metrics:
  prometheus:
    entryPoint: metrics


It remains only to configure Prometheus to collect metrics from traefik_ip:8082.



Here is the content of the files with the resulting configurations:



docker-compose.yml
version: '3'
services:
  traefik:
    image: traefik:v2.2
    container_name: traefik
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    ports:
      - 80:80
      - 443:443 
      - 8082:8082
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./data/traefik.yml:/traefik.yml:ro
      - ./data/custom/:/custom/:ro
      - ./data/acme.json:/acme.json
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik.entrypoints=https"
      - "traefik.http.routers.traefik.rule=Host(`traefik.example.com`)"
      - "traefik.http.routers.traefik.tls=true"
      - "traefik.http.routers.traefik.tls.certresolver=letsEncrypt"
      - "traefik.http.routers.traefik.service=api@internal"
      - "traefik.http.services.traefik-traefik.loadbalancer.server.port=888"
      - "traefik.http.middlewares.traefik-auth.basicauth.users=admin:$$apr1$$vDSqkf.v$$GTJOtsd9CBiAFFnHTI2Ds1"
      - "traefik.http.routers.traefik.middlewares=traefik-auth"


data / traefik.yml
api:
  dashboard: true

entryPoints:
  http:
    address: ":80"
  https:
    address: ":443"
  metrics:
    address: ":8082"

metrics:
  prometheus:
    entryPoint: metrics

http:
  routers:
    http-catchall:
      rule: hostregexp(`{host:.+}`)
      entrypoints:
      - http
      middlewares:
      - redirect-to-https
  middlewares:
    redirect-to-https:
      redirectScheme:
        scheme: https
        permanent: false

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
  file:
    directory: /custom
    watch: true

certificatesResolvers:
  letsEncrypt:
    acme:
      email: postmaster@example.com
      storage: acme.json
      #caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"
      httpChallenge:
        entryPoint: http



All Articles