跳转至

582_Traefik反向代理

一句话概述:Traefik 是云原生反向代理和负载均衡器,能自动发现 Docker 容器并配置路由,自动申请和续期 Let's Encrypt SSL 证书,无需手动配置 Nginx。

核心知识点表

概念白话解释
反向代理站在用户和服务之间的"中间人",把请求转发到正确的服务
EntryPointTraefik 监听的端口,通常是 80(HTTP)和 443(HTTPS)
Router路由规则,根据域名/路径决定请求发到哪个服务
Service后端的实际服务(你的应用容器)
Middleware中间件,在请求到达服务前做处理(如认证、限流、重定向)
Provider配置来源,Traefik 从 Docker/K8s/文件中自动发现服务
ACMELet's Encrypt 自动证书管理协议,免费 SSL

安装配置

Docker Compose 基础配置

# docker-compose.yml
services:
  traefik:
    image: traefik:v3.7                 # 最新稳定版(2026年5月)
    container_name: traefik              # 容器名
    restart: unless-stopped              # 自动重启
    command:
      - "--api.dashboard=true"           # 启用管理面板
      - "--providers.docker=true"        # 启用 Docker 自动发现
      - "--providers.docker.exposedbydefault=false"  # 默认不暴露容器
      - "--entrypoints.web.address=:80"              # HTTP 入口
      - "--entrypoints.websecure.address=:443"       # HTTPS 入口
      - "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"  # TLS 验证
      - "--certificatesresolvers.letsencrypt.acme.email=you@example.com"  # 邮箱
      - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"  # 证书存储
    ports:
      - "80:80"                          # HTTP
      - "443:443"                        # HTTPS
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"  # Docker socket(只读)
      - "./letsencrypt:/letsencrypt"     # 证书持久化目录
    labels:
      - "traefik.enable=true"            # 允许 Traefik 管理自己
      - "traefik.http.routers.dashboard.rule=Host(`traefik.example.com`)"  # 面板域名
      - "traefik.http.routers.dashboard.service=api@internal"  # 内置面板服务
      - "traefik.http.routers.dashboard.entrypoints=websecure" # 只允许 HTTPS
      - "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"  # 自动SSL

启动 Traefik

mkdir letsencrypt                    # 创建证书目录
docker compose up -d                 # 启动
docker compose logs -f traefik       # 查看日志

基本使用

用 Label 暴露应用

# 在同一个 docker-compose.yml 中添加应用:
services:
  traefik:
    # ... Traefik 配置同上 ...

  myapp:
    image: nginx:alpine               # 你的应用镜像
    labels:
      - "traefik.enable=true"          # 告诉 Traefik 管理这个容器
      - "traefik.http.routers.myapp.rule=Host(`myapp.example.com`)"  # 域名规则
      - "traefik.http.routers.myapp.entrypoints=websecure"  # 使用 HTTPS
      - "traefik.http.routers.myapp.tls.certresolver=letsencrypt"  # 自动 SSL
      # Traefik 自动发现容器端口,如果有多个端口需要指定:
      # - "traefik.http.services.myapp.loadbalancer.server.port=3000"

  blog:
    image: ghost:latest                # 另一个应用
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.blog.rule=Host(`blog.example.com`)"
      - "traefik.http.routers.blog.entrypoints=websecure"
      - "traefik.http.routers.blog.tls.certresolver=letsencrypt"

HTTP 自动跳转 HTTPS

# 在 Traefik 的 command 中添加:
command:
  # ... 其他配置 ...
  - "--entrypoints.web.http.redirections.entryPoint.to=websecure"  # HTTP → HTTPS
  - "--entrypoints.web.http.redirections.entryPoint.scheme=https"  # 使用 HTTPS

基于路径的路由

# 同一域名下,不同路径转发到不同服务
labels:
  - "traefik.http.routers.api.rule=Host(`example.com`) && PathPrefix(`/api`)"
  - "traefik.http.routers.frontend.rule=Host(`example.com`) && PathPrefix(`/`)"

高级用法

中间件(Middleware)

# 1. Basic Auth(基本认证)
labels:
  - "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$xyz$$hash"
  # 生成密码哈希:htpasswd -nb admin your-password
  - "traefik.http.routers.myapp.middlewares=auth"  # 应用中间件

# 2. 限流(Rate Limiting)
labels:
  - "traefik.http.middlewares.ratelimit.ratelimit.average=100"  # 每秒100请求
  - "traefik.http.middlewares.ratelimit.ratelimit.burst=50"     # 突发50请求
  - "traefik.http.routers.myapp.middlewares=ratelimit"

# 3. IP 白名单
labels:
  - "traefik.http.middlewares.ipallow.ipallowlist.sourcerange=192.168.1.0/24"
  - "traefik.http.routers.myapp.middlewares=ipallow"

# 4. 压缩(Compress)
labels:
  - "traefik.http.middlewares.compress.compress=true"
  - "traefik.http.routers.myapp.middlewares=compress"

# 5. 重定向
labels:
  - "traefik.http.middlewares.redirect.redirectregex.regex=^https://old.example.com/(.*)"
  - "traefik.http.middlewares.redirect.redirectregex.replacement=https://new.example.com/$${1}"

文件配置(适合静态服务)

# traefik.yml(静态配置)
entryPoints:
  web:
    address: ":80"                     # HTTP 入口
  websecure:
    address: ":443"                    # HTTPS 入口

providers:
  docker:
    exposedByDefault: false            # 默认不暴露容器
  file:
    directory: /etc/traefik/dynamic    # 动态配置目录
    watch: true                        # 监听文件变化

certificatesResolvers:
  letsencrypt:
    acme:
      email: you@example.com
      storage: /letsencrypt/acme.json
      tlsChallenge: {}
# /etc/traefik/dynamic/services.yml(动态配置)
http:
  routers:
    external-app:
      rule: "Host(`app.example.com`)"   # 域名规则
      entryPoints: ["websecure"]        # HTTPS
      service: external-app             # 对应的服务
      tls:
        certResolver: letsencrypt       # SSL 证书

  services:
    external-app:
      loadBalancer:
        servers:
          - url: "http://192.168.1.100:8080"  # 后端服务地址

负载均衡

# 多个后端实例自动负载均衡
services:
  app:
    image: myapp:latest
    deploy:
      replicas: 3                      # 启动 3 个实例
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.app.rule=Host(`app.example.com`)"
      # Traefik 自动在 3 个实例之间做负载均衡

安全加固

# 1. Docker Socket 代理(推荐)
# 不直接暴露 Docker socket,使用 socket-proxy:

# docker-compose.yml 中添加:
services:
  socket-proxy:
    image: tecnativa/docker-socket-proxy  # socket 代理
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      CONTAINERS: 1                       # 只允许读取容器信息
      SERVICES: 1
      TASKS: 1

  traefik:
    # ... 
    # 把 docker.sock 换成 socket-proxy:
    # - "--providers.docker.endpoint=tcp://socket-proxy:2375"

常见报错

报错信息原因解决方案
404 page not found路由规则不匹配检查 Host 规则和 DNS 解析
SSL certificate errorACME 验证失败确保 80/443 端口可从外网访问
Gateway Timeout后端服务没响应检查后端容器是否正常运行
Bad Gateway 502后端端口配置错误添加 loadbalancer.server.port 标签
Too many certificatesLet's Encrypt 频率限制测试时用 staging CA
No routers found容器未加 traefik.enable 标签添加 traefik.enable=true

速查表

# === Label 速查 ===
traefik.enable=true                    # 启用 Traefik 管理
traefik.http.routers.NAME.rule=Host(`domain.com`)  # 域名路由
traefik.http.routers.NAME.entrypoints=websecure    # HTTPS 入口
traefik.http.routers.NAME.tls.certresolver=le      # SSL 证书
traefik.http.routers.NAME.middlewares=auth          # 中间件
traefik.http.services.NAME.loadbalancer.server.port=3000  # 后端端口

# === 路由规则 ===
Host(`example.com`)                    # 匹配域名
PathPrefix(`/api`)                     # 匹配路径前缀
Host(`a.com`) && PathPrefix(`/v1`)     # 组合规则
Headers(`X-Custom`, `value`)           # 匹配请求头

# === 中间件类型 ===
basicauth     # 基本认证
ratelimit     # 限流
ipallowlist   # IP 白名单
compress      # 压缩
redirectregex # 正则重定向
stripprefix   # 去除路径前缀
headers       # 自定义头

同类对比

特性TraefikNginxCaddyHAProxy
自动发现Docker/K8s原生需手动配置需插件需手动配置
自动 SSL内置 ACME需 certbot内置 ACME需外部工具
配置方式Label/YAML配置文件Caddyfile配置文件
热重载自动reload自动reload
Dashboard内置需额外工具不支持Stats页面
K8s Ingress原生支持需安装需插件需安装
学习曲线中等
性能优秀极佳良好极佳

选型建议:Docker/K8s 环境首选 Traefik(自动发现太方便);传统服务器或追求极致性能选 Nginx;想要最简单的自动 HTTPS 选 Caddy。