Traefik 基于服务自动发现实现代理
简介⌗
Traefik 是一款基于 Go 语言开发的代理服务器,同时也是 Kubernetes 的 Ingress,所以天然支持多种服务发现机制:
- File
- Nomad
- Docker
- Kubernetes
- Etcd
- Consul
- Redis
- HTTP
- ZooKeeper
我这里主要使用 Docker 来后端服务的自动发现与反向代理!
前置条件⌗
我打算使用 *.service.local
作为 Traefik 反向代理后端服务的访问域名,Traefik 的 Console 则是 ingress.service.local
。
生成证书⌗
在本地开发环境,我希望也是通过 HTTPS 来管理和访问 Traefik,所以用 mkcert 创建了自签名的证书。
mkcert -cert-file ./fullchain.cer -key-file ./fullchain.key service.local "*.service.local"
配置 TLS⌗
global:
checkNewVersion: true
sendAnonymousUsage: true
serversTransport:
insecureSkipVerify: true
tls:
options:
default:
sniStrict: true
minVersion: VersionTLS12
maxVersion: VersionTLS13
cipherSuites:
- TLS_AES_128_GCM_SHA256
- TLS_AES_256_GCM_SHA384
- TLS_CHACHA20_POLY1305_SHA256
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
certificates:
- certFile: /certs/fullchain.cer
keyFile: /certs/fullchain.key
这里发现 serversTransport.insecureSkipVerify
似乎并不生效,因为某个后端服务使用自签的证书运行的 HTTPS 服务,开了这个配置项后,依然无法正常访问,需要再 Traefik 启动时手动增加 --serverstransport.insecureskipverify=true
参数,才能按预期运行!
编排⌗
services:
traefik:
image: traefik:latest
hostname: traefik
container_name: traefik
ports:
- "0.0.0.0:80:80/tcp"
- "0.0.0.0:443:443/tcp"
networks:
- traefik
command:
- --api=true
- --api.dashboard=true
- --log.level=FATAL
- --serverstransport.insecureskipverify=true
- --entrypoints.http.address=:80
- --entrypoints.https.address=:443
- --providers.file=true
- --providers.file.watch=true
- --providers.file.directory=/etc/traefik/config
- --providers.file.debugloggeneratedtemplate=true
- --providers.docker=true
- --providers.docker.watch=true
- --providers.docker.network=traefik
- --providers.docker.useBindPortIP=false
- --providers.docker.endpoint=unix:///var/run/docker.sock
labels:
- traefik.enable=true
- traefik.docker.network=traefik
- traefik.http.middlewares.gzip.compress=true
- traefik.http.middlewares.redir-https.redirectscheme.scheme=https
- traefik.http.middlewares.redir-https.redirectscheme.permanent=true
- traefik.http.routers.traefik-dashboard.middlewares=redir-https@docker
- traefik.http.routers.traefik-dashboard-secure.middlewares=gzip@docker
- traefik.http.routers.traefik-dashboard-api-secure.middlewares=gzip@docker
- traefik.http.routers.traefik-dashboard.entrypoints=http
- traefik.http.routers.traefik-dashboard.rule=Host(`ingress.service.local`)
- traefik.http.routers.traefik-dashboard.service=noop@internal
- traefik.http.routers.traefik-dashboard-secure.entrypoints=https
- traefik.http.routers.traefik-dashboard-secure.tls=true
- traefik.http.routers.traefik-dashboard-secure.rule=Host(`ingress.service.local`)
- traefik.http.routers.traefik-dashboard-secure.service=dashboard@internal
- traefik.http.routers.traefik-dashboard-api-secure.entrypoints=https
- traefik.http.routers.traefik-dashboard-api-secure.tls=true
- traefik.http.routers.traefik-dashboard-api-secure.rule=Host(`ingress.service.local`) && PathPrefix(`/api`)
- traefik.http.routers.traefik-dashboard-api-secure.service=api@internal
volumes:
- ./certs/:/certs/:ro
- ./config/:/etc/traefik/config/:ro
# So that Traefik can listen to the Docker events
- /var/run/docker.sock:/var/run/docker.sock
networks:
traefik:
external: true
配置解释:
- 17 行设置跳过对后端 HTTPS 的校验
- 36 行用于配置 gzip 中间件,对内响应容进行压缩,
- 37~38 行则用于配置 HTTP 重定向到 HTTPS
- 44 行为 Traefik Dashboard 配置 Entrypoint 为 HTTP,也就是监听 80 端口的流量
- 45 行为 Traefik Dashboard 配置 路由规则,这里是请求域名是
ingress.service.local
就会路由到 Traefik 上 - 46 行为 Traefik Dashboard 指定后端的服务,noop@internal 是 Traefik 内部的一个“魔术变量”
创建网络⌗
docker network create traefik --subnet 10.8.10.0/24 --gateway 10.8.10.1
网段和网关可以根据自己的需求自行设置!
启动服务⌗
docker compose up -d
最终效果⌗
I hope this is helpful, Happy hacking…