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.
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
β .
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.
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
, .
:
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"
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
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:
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"
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