在容器与 Kubernetes 时代,Traefik 作为云原生反向代理与边缘路由器,最大的卖点就是自动服务发现:你不再手写几十行 upstream 配置,只要给容器或 Pod 打标签,路由就自动生成。相比传统 Nginx 需要手动维护 conf、Caddy 偏向简单站点,Traefik 把”配置即代码”做到了极致,特别适合频繁扩缩容的微服务场景。本文从零跑通 Docker 模式,再延伸到 K8s IngressRoute 与生产检查清单。
一、为什么选 Traefik:与传统网关的对比
反向代理不是新东西,Nginx、Caddy、Kong 都能做,但 Traefik 的差异化在于”动态”二字。下面这张表帮你快速判断它是否适合你的场景。
| 维度 | Traefik | Nginx | Caddy |
|---|---|---|---|
| 服务发现 | 原生(Docker/K8s/Consul) | 需手动/模板 | 有限 |
| 配置方式 | 标签/CRD 声明式 | 静态 conf | Caddyfile |
| HTTPS 自动化 | 内置 ACME | 需 certbot | 内置 |
| Dashboard | 开箱即用 | 第三方 | 无 |
| 适用规模 | 动态微服务 | 通用高性能 | 轻量站点 |
如果你已经在用 Nginx 反向代理 做负载均衡,可以把 Traefik 放在内网服务网格边缘,两者并不冲突。关于 Caddy 的玩法可参考 Caddy 实战。
选型上有一个经验法则:静态站点、需要极致性能调优的七层规则,Nginx 仍是王者;想用一行 Caddyfile 起一个带 HTTPS 的小站,Caddy 最省事;而当后端是十几个会随时扩缩容的容器服务、你不想每次发版都去改网关配置,Traefik 的服务发现优势就彻底释放了。很多团队最终是”Traefik 做南北向动态入口 + Nginx 做入口前的 WAF/限频前置”,各取所长。
二、Docker 模式快速上手
最经典的入门方式是用 docker-compose 同时拉起 Traefik 和一个 whoami 测试服务。注意 Traefik 必须挂载宿主机的 docker.sock 才能监听容器事件。
version: "3.8"
services:
traefik:
image: traefik:v3.1
command:
- "--api.dashboard=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
whoami:
image: traefik/whoami
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.example.com`)"
- "traefik.http.services.whoami.loadbalancer.server.port=80"
关键点是 traefik.enable=true 与路由规则。因为我们在启动参数里设了 exposedbydefault=false,只有显式打标签的容器才会被暴露,避免误把内部服务对外网开放。更多 Docker 网络基础见 Docker 网络模式详解。
三、核心概念:EntryPoints / Routers / Services / Middlewares
理解 Traefik 只需记住四个对象:EntryPoints 是监听端口(如 :80/:443);Routers 用规则把请求匹配到服务;Services 是后端真实实例池;Middlewares 是在路由前后加工请求(重定向、限流、鉴权等)。它们通过标签或 YAML 动态绑定。
# 静态配置 traefik.yml(启动期固定)
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
api:
dashboard: true
providers:
docker:
exposedBydefault: false
上面是”静态配置”,在容器启动前就定好;而路由、服务、中间件这些”动态配置”则跟着业务服务走。在 Docker 模式下,你通常不用单独写 YAML,直接给容器打标签即可声明完整的路由链:
labels:
- "traefik.http.routers.api.rule=Host(`api.example.com`)"
- "traefik.http.routers.api.service=api-svc"
- "traefik.http.services.api-svc.loadbalancer.server.port=8080"
- "traefik.http.routers.api.middlewares=auth-chain"
这里显式把 Router 指向名为 api-svc 的 Service,并挂了一条中间件链 auth-chain。当你用 docker compose up 扩容副本时,Traefik 会自动把新容器加进负载均衡池,缩容则自动摘除——这就是”服务发现”带来的零改配置体验。
四、中间件实战:重定向、压缩与限流
中间件是 Traefik 最好用的能力。下面给 whoami 加三条链:HTTP 强制跳 HTTPS、开启 gzip、并对单个客户端限流。
labels:
- "traefik.http.middlewares.https-redirect.redirectscheme.scheme=https"
- "traefik.http.middlewares.gzip.compress=true"
- "traefik.http.middlewares.ratelimit.ratelimit.average=100"
- "traefik.http.middlewares.ratelimit.ratelimit.burst=50"
- "traefik.http.routers.whoami.middlewares=https-redirect,gzip,ratelimit"
限流参数 average 是每秒平均请求数,burst 是允许的突发量。这与 Nginx 的漏桶算法思路一致,但声明式写法更直观,也更容易随服务伸缩动态调整。
中间件远不止限流。生产环境强烈建议统一加安全响应头,避免每个服务自己配;涉及内部后台还可以接 forwardauth 做集中鉴权,把鉴权逻辑从业务代码里抽出来。
labels:
- "traefik.http.middlewares.sec-headers.headers.customresponseheaders.X-Content-Type-Options=nosniff"
- "traefik.http.middlewares.sec-headers.headers.stsSeconds=31536000"
- "traefik.http.middlewares.gate.forwardauth.address=http://auth-svc:9000/verify"
- "traefik.http.middlewares.gate.forwardauth.trustforwardheader=true"
五、HTTPS 自动化:Let’s Encrypt + ACME
Traefik 内置 ACME 客户端,能自动申请并续期证书。生产环境务必用 DNS 挑战(如阿里云 DNS)避免 80 端口被墙。下面配置一个 certresolver。
certificatesResolvers:
letsencrypt:
acme:
email: admin@example.com
storage: /letsencrypt/acme.json
dnsChallenge:
provider: alidns
# 在 whoami 上启用
labels:
- "traefik.http.routers.whoami.tls.certresolver=letsencrypt"
- "traefik.http.routers.whoami.entrypoints=websecure"
acme.json 必须权限 600,否则 Traefik 会拒绝启动。证书自动续期无需人工干预,比手动对接 Nginx 反向代理 的 certbot 省心得多。
如果一台网关要托管多个域名,可以开 certificatesresolvers.letsencrypt.acme.certificatesixtype=SNI 并按域名分别挂 tls.certresolver;通配符证书(*.example.com)必须用 DNS 挑战,HTTP 挑战无法验证泛域名。证书默认 90 天,Traefik 会在到期前 30 天自动续期,期间服务不中断。
六、Kubernetes Ingress 模式
在 K8s 里 Traefik 通过 CRD(IngressRoute)代替原生 Ingress,能力更强。先装 Helm chart,再用下面资源暴露服务。
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: whoami-route
spec:
entryPoints:
- websecure
routes:
- match: Host(`whoami.example.com`)
kind: Rule
services:
- name: whoami
port: 80
tls:
certResolver: letsencrypt
IngressRoute 支持多命名空间、加权路由、TCP/UDP 等原生 Ingress 没有的能力。K8s 基础概念可回顾 K8s 入门:Pod、Deployment、Service。
七、可观测性:Dashboard 与 Metrics
Traefik 自带 Dashboard(默认 8080 端口),实时看到所有路由、服务健康与中间件。生产建议把指标接到 Prometheus,配合 Grafana 看 QPS、TLS 握手耗时与 5xx 比例。
# 静态配置开启 metrics
metrics:
prometheus:
addEntryPointsLabels: true
addServicesLabels: true
entryPoint: web
监控面板搭建思路与 Prometheus + Grafana 监控实战 一致,把 Traefik 的 /metrics 纳管进同一套告警体系即可。
除了指标,访问日志也建议改成 JSON 格式,方便后续进 Loki 或 ES 做字段检索。下面这段开启带客户端 IP 与耗时字段的 accesslog:
accessLog:
format: json
fields:
headers:
defaultMode: keep
names:
User-Agent: keep
X-Forwarded-For: keep
八、生产落地检查清单
| 检查项 | 建议 |
|---|---|
| exposedByDefault | 设为 false,显式开启 |
| ACME 存储 | acme.json 权限 600 + 持久卷 |
| Dashboard 暴露 | 加 Basic Auth,勿公网裸开 |
| 限流 | 按业务 QPS 设 average/burst |
| 健康检查 | 开启 /ping 并接活探针 |
| 日志 | 开 accesslog + JSON 格式 |
九、常见问题排查
9.1 路由 404 但服务在跑
九成是 exposedbydefault=false 却漏了 traefik.enable=true,或 Host 规则域名与访问域名不一致。打开 Dashboard 的 Routers 页对照最直观。
9.2 证书申请一直 pending
多为 DNS 挑战 API 密钥缺失或 80 端口被防火墙拦。改用 DNS 挑战并确认对应云厂商环境变量已注入容器。
9.3 健康检查一直 502
容器起来了但 Traefik 探活失败,通常是 loadbalancer.server.port 写成了容器映射端口而非容器内监听端口,或 readiness 探针比 Traefik 注册更早。用 docker logs 看 Traefik 是否真的监听到该端口。
9.4 文件描述符耗尽
高并发下偶发 too many open files,需要在宿主机把 Traefik 容器的 ulimit 调高,并在 docker run 里加 --ulimit nofile=65536:65536,否则连接会被悄悄丢弃。
十、灰度发布与权重路由
Traefik 原生支持按权重把流量切到不同服务版本,无需额外网关即可做金丝雀发布。下面把 90% 流量给稳定版、10% 给金丝雀版:
labels:
- "traefik.http.services.app-svc.weighted.services[0].name=app-v1"
- "traefik.http.services.app-svc.weighted.services[0].weight=90"
- "traefik.http.services.app-svc.weighted.services[1].name=app-v2"
- "traefik.http.services.app-svc.weighted.services[1].weight=10"
配合健康探针与监控,你可以先放 10% 观察错误率,再逐步调高权重到 100%,全程无需停服。这和 Kubernetes 自身的滚动更新互补:K8s 管 Pod 生命周期,Traefik 管南北向流量切分。
十一、结语
Traefik 把”反向代理 + 服务发现 + HTTPS 自动化”收进一套声明式体系,是容器化与 K8s 场景下的首选边缘路由。它不等于取代 Nginx——更常见的架构是 Traefik 做南北向动态路由、Nginx 做七层精细管控。把本文的 Docker 示例跑通,你就拥有了可随服务伸缩自动更新的流量入口。




