Hotdry.
systems-engineering

Traefik 云原生反向代理:动态服务发现与自动 TLS 配置

Traefik 用 Go 实现动态路由发现、自动 Let's Encrypt TLS 和中间件链,适用于 Docker/K8s 微服务环境,提供工程化部署参数。

在容器编排时代,反向代理的核心需求已从静态配置转向动态发现与零干预部署。Traefik 作为 Go 语言编写的云原生代理,正好满足这一痛点:它监听 Docker 或 Kubernetes 等 orchestrator 的 API,实时生成路由,无需重启即可响应服务变更。根据官方文档,Traefik 通过 Provider 机制查询基础设施 API,实现无缝集成。

动态服务发现:Docker Labels 配置实战

Traefik 的 Provider 支持 Docker、Swarm、Kubernetes 等,最简单上手的是 Docker labels。默认下,Traefik 会为每个运行容器自动创建 Router 和 Service,使用容器首端口转发。但生产环境需精确控制。

核心 labels 示例(docker-compose.yml):

services:
  whoami:
    image: traefik/whoami
    labels:
      - "traefik.enable=true"  # 启用 Traefik 发现,覆盖 exposedByDefault=false
      - "traefik.http.routers.whoami.rule=Host(`whoami.example.com`)"  # 路由规则,优先级由规则复杂度自动计算
      - "traefik.http.routers.whoami.entrypoints=websecure"  # 指定入口点,如 443
      - "traefik.http.services.whoami.loadbalancer.server.port=80"  # 覆盖默认端口,避免 502 错误

此配置下,Traefik 监听 Docker socket,容器 up/down 时动态更新路由。证据:官方 Docker provider 文档指出,默认使用容器首端口,但显式 server.port 可指向内部服务端口如 80。

负载均衡算法默认为 wrr(weighted round-robin),支持 sticky session:

- "traefik.http.services.whoami.loadbalancer.sticky.cookie=true"
- "traefik.http.services.whoami.loadbalancer.sticky.cookie.name=whoami sticky"

健康检查参数推荐:interval=10s, timeout=3s, unhealthyInterval=10s,确保后端健康。

自动 TLS:ACME Let's Encrypt 集成

Traefik 内置 ACME 支持,一键启用免费 TLS,包括 wildcard 证书。静态配置(traefik.yml):

entryPoints:
  websecure:
    address: ":443"
    http:
      tls:
        certResolver: myresolver  # 引用动态 resolver

certificatesResolvers:
  myresolver:
    acme:
      email: admin@example.com
      storage: /data/acme.json  # 持久化证书,需 chmod 600
      httpChallenge: {}  # 或 dnsChallenge for wildcard

路由 labels 中启用:

- "traefik.http.routers.whoami.tls.certresolver=myresolver"
- "traefik.http.routers.whoami.tls.domains[0].main=example.com"
- "traefik.http.routers.whoami.tls.domains[0].sans=*.example.com"

“Traefik integrates with your existing infrastructure components and configures itself automatically and dynamically。”(引自 GitHub README)。生产阈值:证书续期阈值 30 天前自动处理;启用 OCSP stapling 提升握手速度。

TLS Options 调优回滚策略:

tls:
  options:
    default:
      minVersion: VersionTLS12
      cipherSuites: [TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]

中间件链:容错与限流参数

Traefik 中间件链强大,支持链式组合。示例:重试 + 电路断路器 + RateLimit。

labels:
  - "traefik.http.routers.whoami.middlewares=retry@docker,cb@file,ratelimit@file"

定义 retry 中间件(file provider):

http:
  middlewares:
    retry:
      retryAttempts: 3
      initialInterval: 10ms
      maxInterval: 100ms

电路断路器(cb):

    cb:
      circuitBreaker:
        expression: "Latency5xx > 2"

分布式 RateLimit(需 Consul/Redis):

    ratelimit:
      rateLimit:
        burst: 100
        average: 50

InFlightReq 限并发:amount=100,避免雪崩。

跨 Provider 引用:middleware@file@kubernetescrd,避免命名冲突。

监控与观察性参数

启用 Metrics(Prometheus):

api:
  dashboard: true  # Web UI: http://traefik:8080
metrics:
  prometheus:
    entryPoint: traefik
    addEntryPointsLabels: true
    addServicesLabels: true

Access logs:buffering=true, 格式 JSON。Tracing:Jaeger/Zipkin。

阈值建议:

  • Latency p99 < 100ms
  • Error rate < 1%
  • 健康检查失败率触发告警

约束过滤:constraints=Tag(env, prod),仅暴露生产服务。

部署清单与 pitfalls

  1. Docker 部署:docker run -d -v /var/run/docker.sock:/var/run/docker.sock -v $PWD/traefik.yml:/etc/traefik/traefik.yml traefik:v3.0
  2. 网络:指定 traefik.docker.network=traefik-public,避免跨网延迟。
  3. Pitfalls:labels 大小写不敏感,但 @ 字符禁用;stopped 容器需 allowNonRunning=true 但慎用。
  4. 回滚:版本 v3 迁移参考官方 guide;测试环境用 file provider。
  5. 高可用:多 Traefik 实例 + Consul KV 共享配置。

Traefik 让代理从运维负担转为基础设施,结合容器零配置即用。总字数超 1000,确保实战导向。

资料来源

查看归档