Traefik

Traefik

Traefik 是新一代开源的反向代理(reverse proxy) & 负载均衡(load balancer) & http 网关 (http gateway),设计特别面向云原生(cloud native)环境,其目标用于替代 Nginx。Traefik 使用 Go 开发。最新稳定版本是 2.x。3.0 版本正在 beta 测试。

第三方 benchmark 结果显示 Traefik 绝对性能(http连接处理吞吐量、延时)尚不如 nginx,但差距已经很小。而 Traefik 的功能、设计和特性使其相对于 Nginx 更加适合云原生环境。

Traefik 缺点:

  • 官网文档乱七八糟,缺乏完整的 Quick Start 示例。

应用场景

Traefik 典型的应用场景是自动为 Docker 容器提供反向代理,而无需手动配置。Nginx 环境下必须通过一些第三方工具 (例如 nginx-proxyNginx Proxy Manager) 实现这种功能,但由于 nginx 缺乏可编程性,这些工具内部实现非常不优雅(本质上是动态生成 nginx 配置文件),无法大规模 scale。而 Traefik 原生支持这种功能。

配置系统

Traefil 包括多层次的配置系统:

  • static config : /etc/traefik.toml (或 traefik.yaml)。
  • dynamic config : 通过 Docker 容器的 label 配置。例如本容器的路由信息。

Quick Start (单机 Docker 环境)

启动 Traefik

docker run -d --restart=unless-stopped --name traefik \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /root/files/appdata/traefik/data:/etc/traefik \
  -p 80:80 -p 443:443 \
  traefik:v2.10

Traefik 配置

/etc/traefik.toml (host: /root/files/appdata/traefik/data/traefik.toml)

[log]
  #level = "DEBUG"

[providers.docker]
  # Default is true! If set to false, containers that do not have a traefik.enable=true label are ignored from routing
  exposedByDefault = false

[entryPoints.web]
  address = ":80"

  # redirect all http access to https
  [entryPoints.web.http]
    [entryPoints.web.http.redirections]
      [entryPoints.web.http.redirections.entryPoint]
        to = "websecure"
        scheme = "https"

[entryPoints.websecure]
  address = ":443"

[entryPoints.websecure.http.tls]

[providers.file]
  directory = "/etc/traefik/config"
  watch = true

/etc/traefik/config (允许动态增加/修改其中的 toml / yaml 配置文件)

/etc/traefik/config/tls.toml (host: /root/files/appdata/traefik/data/config/tls.toml)

[[tls.certificates]]
  certFile = "/certs/example.com.pem"
  keyFile = "/certs/example.com.key"

可以增加任意个 TLS 证书。Traefik 会自动根据容器配置的 Host 选择匹配的证书使用。推荐使用 CloudFlare 的 15年有效期 Origin Certificate。如果用 Let's encrypt,建议配置 Traefik 的 Certificate Resolvers(参考资料)。

应用(App) 容器:

docker run -d -P --name whoami --restart=unless-stopped \
  --label "traefik.enable=true" \
  --label 'traefik.http.routers.whoami.rule=Host(`whoami.example.me`)' \
  traefik/whoami

测试

curl http://whoami.example.com --resolve whoami.example.me:80:127.0.0.1

说明

  • traefik.toml 里必须配置 exposedByDefault = false,否则本机所有 Docker 容器都会被自动发布。
  • toml 里的缩进仅用于视觉上标识配置项的层级。
  • shell 命令参数如果包含 ( , ) 等字符,需要用单引号 (') 括起以避免 Shell 解释。

详细配置

示例里的 whoami, myapp 等均为自己应用的名称,可以任意取值。

应用(App)容器配置

  • --label "traefik.enable=true" \
  • --label 'traefik.http.routers.whoami.rule=Host(whoami.example.me)'
  • --label 'traefik.http.services.whoami.loadbalancer.server.port=12345'

说明

  • 如果应用Docker镜像只发布(EXPOSE)了一个端口,Traefik 自动使用其作为。如果应用镜像没有发布端口或发布了多个端口,必须通过 loadbalancer.server.port手动指定。
  • traefik.http.routers.{router_name} 和 traefik.http.services.{service_name} 里的 router_name / service_name 为绑定本容器的路由 / 服务名称,可以任意指定,但必须是唯一的。

路由 rule

  • Host(whoami.example.me)
  • PathPrefix(/test)
  • &&, ||, ! 布尔运算符可用。

Traefik 自动选择最佳匹配路由,例如:

  • Host(whoami.example.me)
  • Host(whoami.example.me)&&PathPrefix(/test)

只有访问 /test 路径的请求会被第二条规则的应用处理。

docker network

如果 Traefik 本身运行于 Docker 容器里,必须让 Traefik 能够访问应用的 Docker 容器。

如果应用的 Docker 容器与 Traefik 使用不同的 network,可以手动 connect :

docker network connect app_network traefik

代理外部应用

参考配置:

[http.routers.filebrowser]
rule = "Host(`filebrowser.example.com`)"
service = "filebrowser"

[http]
  [http.services]
    [http.services.filebrowser]
      [http.services.filebrowser.loadBalancer]
        [[http.services.filebrowser.loadBalancer.servers]]
          url = "http://172.17.0.1:8080/"

设置或更改 http 请求 header

参考资料

[http.middlewares]
  [http.middlewares.myapp.headers]
    [http.middlewares.myapp.headers.customRequestHeaders]
        X-Script-Name = "test" # Adds
        X-Custom-Request-Header = "" # Removes
    [http.middlewares.myapp.headers.customResponseHeaders]
        X-Custom-Response-Header = "" # Removes

Last update: 2024-02-08 06:30:34 UTC