Hotdry.
systems-engineering

Traefik 动态配置代理:零停机服务发现与热重载实践

利用文件 Provider 的 fsnotify 监听机制,实现 Traefik 动态配置热重载,支持 Let's Encrypt 中间件链与负载均衡的工程参数、阈值与监控清单。

在微服务架构中,反向代理的配置更新往往带来停机风险,Traefik 通过 Provider 机制和文件系统监听(如 fsnotify,类似 inotify),实现零停机动态配置代理。本文聚焦单一技术点:文件 Provider 的 watch 模式下,如何工程化零停机服务发现、配置热重载,并链式集成 Let's Encrypt 证书与负载均衡中间件,提供可落地参数和清单。

Traefik 动态配置的核心原理

Traefik 将配置分为静态(入口点、Provider)和动态(路由、中间件、服务),动态部分支持热重载。核心是 Provider(如 file、docker),通过 watcher 监听变化,实现原子更新:检测变更 → 合并配置 → 对比差异 → 替换旧配置,无需重启进程。文件 Provider 使用 fsnotify 库监听目录事件(CREATE/WRITE/REMOVE),类似于 Linux inotify,确保 <1s 内生效。

证据:在静态配置 traefik.yml 中启用:

providers:
  file:
    directory: "/etc/traefik/dynamic"  # 监控目录
    watch: true                        # 启用 fsnotify
    pollInterval: "5s"                 # 轮询兜底

修改 dynamic 目录下 YAML 文件(如 routers.yml),Traefik 立即应用,无流量中断。官方文档指出,这种 “读 - 修改 - 替换” 模式避免不一致状态。

零停机服务发现与配置热重载参数

服务发现依赖 Provider:Docker 通过 labels 自动注册,Kubernetes 用 CRD。结合 file watch,实现混合动态代理。

落地参数清单:

  • 目录结构(多文件拆分,提高可维护):
    /etc/traefik/dynamic/
    ├── routers/api-router.yml     # Host(`api.example.com`)
    ├── middlewares/auth.yml       # BasicAuth 等
    └── services/web-service.yml   # LoadBalancer servers
    
  • 热重载阈值:
    参数 推荐值 说明
    pollInterval 5s 文件通知失效时轮询间隔,生产 <10s
    dialTimeout 5s serversTransport.forwardingTimeouts,转发超时
    responseHeaderTimeout 10s 后端响应超时
  • 监控点:
    • Prometheus Metrics: traefik_entrypoint_requests_total{status_code="502"} 监控坏网关。
    • 日志级别: DEBUG 开发,INFO 生产,观察 "Configuration change detected"。
    • Dashboard: :8080 查看路由状态(enabled/disabled)。

风险:大规模(>1 万路由)内存增 50MB / 万条,调 --accesslog 和 GC 参数。

中间件链:Let's Encrypt + 负载均衡

Traefik 中间件责任链模式,支持链式组合:认证 → 限流 → 压缩 → TLS。Let's Encrypt 通过 ACME resolver 自动证书,负载均衡内置 WRR/DRR/HealthCheck。

示例动态配置(dynamic/routers.yml):

http:
  routers:
    api-router:
      rule: "Host(`api.example.com`)"
      entryPoints: ["websecure"]
      middlewares: ["le@file", "lb@file", "rate-limit@file"]
      service: api-service@file
      tls:
        certResolver: letsencrypt  # 自动 HTTPS

  middlewares:
    le:
      redirectScheme:
        scheme: https  # HTTP → HTTPS
    rate-limit:
      rateLimit:
        average: 100  # 每秒 100 请求
        burst: 50
    lb:
      headers:
        customRequestHeaders:
          X-Forwarded-Proto: "https"

  services:
    api-service:
      loadBalancer:
        servers:
          - url: "http://backend1:8080"
            weight: 9
          - url: "http://backend2:8080"
            weight: 1  # 金丝雀 10%
        healthCheck:
          path: "/health"
          interval: "10s"
          timeout: "3s"

ACME 配置(静态 traefik.yml):

certificatesResolvers:
  letsencrypt:
    acme:
      email: "admin@example.com"
      storage: "acme.json"  # 持久化
      httpChallenge:
        entryPoint: web

系统自动申请 / 续期(提前 30 天),链入中间件实现零配置 HTTPS。

负载均衡清单:

  • 策略: WRR(权重轮询,默认);DRR(动态降低故障权重)。
  • HealthCheck: path=/health,interval=10s,阈值(consecutiveErrors=3)。
  • Sticky Session: cookie-based 会话保持。
  • 灰度: weighted services (90/10)。

生产回滚与监控策略

回滚清单:

  1. 备份 dynamic 目录快照。
  2. API 触发:curl -X POST http://localhost:8080/api/rawdata -d @backup.json
  3. SIGHUP 信号:docker kill -s SIGHUP traefik 重载动态配置。
  4. LivenessProbe: /ping,period=10s。

完整 Docker Compose 示例:

services:
  traefik:
    image: traefik:v3.1
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./dynamic:/etc/traefik/dynamic:ro
    command:
      - --providers.file.directory=/etc/traefik/dynamic
      - --providers.file.watch=true
      - --providers.docker=true
      - --entrypoints.web.address=:80
      - --entrypoints.websecure.address=:443

Traefik 吞吐 10 万 + QPS(4 核 8G),P99<10ms。生产建议:结合 Prometheus/Grafana 监控路由变更延迟。

资料来源:

(正文字数:1256)

查看归档