Este post é principalmente para mim: acho a documentação do Traefik difícil de navegar, então, tendo descoberto isso em resposta a uma pergunta no Stack Overflow , estou colocando aqui para ajudá-lo a ficar na minha cabeça.
A questão pergunta essencialmente como executar o roteamento de solicitações para contêineres baseado em porta, de modo que uma solicitação de http://example.com
vá para um contêiner enquanto uma solicitação de http://example.com:9090
vá para um contêiner diferente.
Criando pontos de entrada
Uma configuração padrão do Traefik já terá um listener na porta 80, mas se quisermos aceitar conexões na porta 9090, precisamos criar um novo listener: o que o Traefik chama de entrypoint . Fazemos isso usando a --entrypoints.
opção. Por exemplo, --entrypoints.ep1.address=80
cria um ponto de entrada chamado ep1
na porta 80, enquanto --entrypoints.ep2.address=9090
cria um ponto de entrada chamado ep2
na porta 9090. Esses nomes são importantes porque os usaremos para mapear contêineres para o ouvinte apropriado mais tarde.
Isso nos dá uma configuração do Traefik que se parece com:
proxy:
image: traefik:latest
command:
- --api.insecure=true
- --providers.docker
- --entrypoints.ep1.address=:80
- --entrypoints.ep2.address=:9090
ports:
- "80:80"
- "127.0.0.1:8080:8080"
- "9090:9090"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
Precisamos publicar portas 80
e 9090
no host para aceitar conexões. A porta 8080 é, por padrão, o painel do Traefik; nesta configuração, eu o tenho vinculado localhost
porque não quero fornecer acesso externo ao painel.
Serviços de roteamento
Agora precisamos configurar nossos serviços para que as conexões nas portas 80 e 9090 sejam roteadas para os contêineres apropriados. Fazemos isso usando o traefik.http.routers.
rótulo. Aqui está um exemplo simples:
app1:
image: docker.io/alpinelinux/darkhttpd:latest
labels:
- traefik.http.routers.app1.entrypoints=ep1
- traefik.http.routers.app1.rule=Host(`example.com`)
Na configuração acima, estamos usando os seguintes rótulos:
-
traefik.http.routers.app1.entrypoints=ep1
Isso vincula nosso
app1
contêiner ao ponto deep1
entrada. -
traefik.http.routers.app1.rule=Host(`example.com`)
Isso corresponde a solicitações com
Host: example.com
.
Então, em combinação, essas duas regras dizem que qualquer solicitação na porta 80 Host: example.com
será roteada para o app1
contêiner.
Para obter a porta 9090
roteada para um segundo contêiner, adicionamos:
app2:
image: docker.io/alpinelinux/darkhttpd:latest
labels:
- traefik.http.routers.app2.rule=Host(`example.com`)
- traefik.http.routers.app2.entrypoints=ep2
Isso é a mesma coisa, exceto que usamos entrypoint ep2
.
Com tudo rodando, podemos observar os logs docker-compose up
e ver que uma requisição na porta 80:
curl -H 'host: example.com' localhost
É atendido por app1
:
app1_1 | 172.20.0.2 - - [21/Jun/2022:02:44:11 +0000] "GET / HTTP/1.1" 200 354 "" "curl/7.76.1"
E essa solicitação na porta 9090:
curl -H 'host: example.com' localhost:9090
É atendido por app2
:
app2_1 | 172.20.0.2 - - [21/Jun/2022:02:44:39 +0000] "GET / HTTP/1.1" 200 354 "" "curl/7.76.1"
O docker-compose.yaml
arquivo completo deste post se parece com:
version: "3"
services:
proxy:
image: traefik:latest
command:
- --api.insecure=true
- --providers.docker
- --entrypoints.ep1.address=:80
- --entrypoints.ep2.address=:9090
ports:
- "80:80"
- "8080:8080"
- "9090:9090"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
app1:
image: docker.io/alpinelinux/darkhttpd:latest
labels:
- traefik.http.routers.app1.rule=Host(`example.com`)
- traefik.http.routers.app1.entrypoints=ep1
app2:
image: docker.io/alpinelinux/darkhttpd:latest
labels:
- traefik.http.routers.app2.rule=Host(`example.com`)
- traefik.http.routers.app2.entrypoints=ep2