Traefik 是一款开源的边缘路由器(Edge Router),它通过直接与 Docker、Kubernetes 等编排器集成,自动发现并配置指向您服务的路由,充当动态的反向代理和负载均衡器。
核心概念
Traefik 采用动态配置模型,后端服务发生变化时无需手动修改配置文件或重启服务。这种实时适应能力由若干相互关联的组件共同实现。
Provider
Provider 是让 Traefik 与您的基础设施交互的连接器。它们监听底层编排器的 API,捕捉新容器、服务或部署等变化。
常见的 Provider 包括:
* Docker: 监听 Docker daemon 事件和容器 label。
* Kubernetes: 监听 Kubernetes API 中的 Ingress、IngressRoute、Service 和 Endpoint 资源。
* File: 从静态 YAML 或 TOML 文件读取配置。
* Consul、etcd、ZooKeeper: 与键值存储集成以实现动态配置。
路由配置
Traefik 按照既定的路由流程处理进入的请求:
- EntryPoint: 网络监听器,定义 Traefik 监听的端口(例如 80 端口上的
web、443 端口上的websecure)。 - Router: Router 依据既定规则分析进入的请求(例如
Host()、PathPrefix()、Headers())。如果请求匹配某个 Router 的规则,就会被转发。Router 还会指定自己监听哪些 EntryPoint,并可应用 Middleware。 - Middleware: 可在请求到达服务前修改请求,或在响应返回客户端前修改响应的组件。它们可以串联使用。
- Service: Service 定义如何访问真实的后端应用实例。一个 Service 通常指向应用的一个或多个 IP 地址和端口。Traefik 可在同一 Service 的多个实例之间进行负载均衡。
流程为:请求 -> EntryPoint -> Router -> Middleware -> Service -> 后端应用。
主要功能
自动服务发现
Traefik 直接与 Docker、Kubernetes 等编排器集成。它通过读取元数据(例如 Docker label、Kubernetes annotation 或 Custom Resource)自动发现服务,并动态更新路由配置,无需任何手动干预或重启。这样就不必再维护单独的代理配置文件。
SSL/TLS 终止
Traefik 内置支持 SSL/TLS 终止。它可通过 ACME(Automatic Certificate Management Environment)协议使用 Let's Encrypt 自动签发和续期证书,支持 HTTP-01、TLS-ALPN-01 和 DNS-01 验证方式。也可以配置自定义证书。
负载均衡
Traefik 可作为负载均衡器,将进入的流量分发到某个服务的多个实例上。
可用的负载均衡策略包括:
* Round Robin: 按顺序将请求分发给各服务器。
* Weighted Round Robin: 允许为服务器分配权重以控制流量分配。
* Sticky Sessions: 确保来自特定客户端的请求始终被路由到同一台服务器。
Middleware
Middleware 提供了修改请求或响应的灵活方式,可应用于特定 Router 或全局生效。
常见 Middleware 示例:
* 认证: 基本认证(BasicAuth)、Digest 认证。
* 限流(Rate Limiting): 控制客户端在指定时间内可发起的请求数量。
* Header 处理: 添加、删除或修改请求/响应 header。
* 重定向: HTTP 到 HTTPS 的重定向、永久重定向。
* IP 白名单/黑名单: 根据客户端 IP 地址限制访问。
控制台
Traefik 自带基于 Web 的控制台,可实时展示已配置的 Router、Service 和 Middleware。管理员可借此查看当前生效的配置并监控流量。
Traefik 与 Docker
将 Traefik 与 Docker 集成,需要以容器方式运行 Traefik,并允许它访问 Docker daemon 的套接字。服务配置通常通过应用容器上的 Docker label 来管理。
docker-compose.yml 配置示例
下面的示例演示了用于部署 Traefik 和示例应用 whoami 的 docker-compose.yml 文件。
version: '3.8'
services:
traefik:
image: traefik:v2.10
command:
- --api.dashboard=true
- --providers.docker=true
- --providers.docker.exposedbydefault=false # 仅暴露带有 traefik.enable=true 的服务
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --certificatesresolvers.myresolver.acme.tlschallenge=true # 用于 Let's Encrypt
- --certificatesresolvers.myresolver.acme.email=your-email@example.com
- --certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json # 证书的持久化存储
ports:
- "80:80"
- "443:443"
- "8080:8080" # 暴露 Traefik 控制台
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro" # 挂载 Docker 套接字供 provider 访问
- "./letsencrypt:/letsencrypt" # ACME 证书的持久化存储
labels:
# 为控制台服务本身启用 Traefik
- "traefik.enable=true"
# Traefik 控制台的 Router
- "traefik.http.routers.traefik-dashboard.rule=Host(`traefik.yourdomain.com`)"
- "traefik.http.routers.traefik-dashboard.entrypoints=websecure"
- "traefik.http.routers.traefik-dashboard.service=api@internal" # Traefik 内部 API 服务
- "traefik.http.routers.traefik-dashboard.tls.certresolver=myresolver"
# 控制台的基本认证 middleware(请替换为真实的 htpasswd 哈希)
- "traefik.http.routers.traefik-dashboard.middlewares=dashboard-auth@docker"
- "traefik.http.middlewares.dashboard-auth.basicauth.users=user:$$apr1$$YOUR_HTPASSWD_HASH"
networks:
- web
whoami:
image: traefik/whoami
labels:
- "traefik.enable=true" # 为该服务启用 Traefik
- "traefik.http.routers.whoami.rule=Host(`whoami.yourdomain.com`)" # 定义路由规则
- "traefik.http.routers.whoami.entrypoints=websecure" # 监听 websecure(HTTPS)
- "traefik.http.routers.whoami.tls.certresolver=myresolver" # 使用 Let's Encrypt resolver
networks:
- web
networks:
web:
external: true # 所有面向 Web 的服务使用同一个外部网络
注意:运行 docker-compose up -d 之前,请先用 docker network create web 创建该外部网络。
使用 echo $(htpasswd -nb user password) 为 dashboard-auth 生成 htpasswd 哈希。
Traefik 与 Kubernetes
Traefik 通过 Kubernetes API 与其集成,既支持标准 Ingress 资源,也提供自己的 Custom Resource Definition(CRD)用于高级配置。推荐的安装方式是使用 Helm。
使用 Helm 安装
helm repo add traefik https://traefik.github.io/charts
helm repo update
helm install traefik traefik/traefik \
--namespace traefik \
--create-namespace \
-f values.yaml
values.yaml 文件通常用于配置 Traefik 的 EntryPoint、Provider 和 ACME resolver(例如用于 Let's Encrypt 的 myresolver)。
通过 Custom Resource Definition(CRD)配置
Traefik 用自己的 CRD 扩展了 Kubernetes 的能力,提供比标准 Ingress 更强的控制力:
* IngressRoute: 定义路由规则、entry point 及关联的 Service,包括 TLS 配置和 middleware。它是标准 Kubernetes Ingress 更强大的替代方案。
* Middleware: 定义可复用的请求/响应修改器,可应用于 IngressRoute。
* TraefikService: 允许更细致地定义后端服务,包括负载均衡策略和外部服务。
Kubernetes 配置示例
本示例展示了 whoami 应用的 Kubernetes Deployment、Service 和 IngressRoute。
# whoami-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami
labels:
app: whoami
spec:
replicas: 2
selector:
matchLabels:
app: whoami
template:
metadata:
labels:
app: whoami
spec:
containers:
- name: whoami
image: traefik/whoami
ports:
- containerPort: 80
---
# whoami-service.yaml
apiVersion: v1
kind: Service
metadata:
name: whoami
spec:
selector:
app: whoami
ports:
- protocol: TCP
port: 80
targetPort: 80
---
# whoami-ingressroute.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: whoami-ingressroute
spec:
entryPoints:
- websecure # 假设已在 Traefik 的 Helm values 中配置了 'websecure' entry point
routes:
- match: Host(`whoami.yourdomain.com`)
kind: Rule
services:
- name: whoami # 指向 Kubernetes 中名为 'whoami' 的 Service
port: 80
tls:
certResolver: myresolver # 假设已在 Traefik 的 Helm values 中配置了用于 Let's Encrypt 的 'myresolver'
对比:Traefik 与传统代理(Nginx/HAProxy)
| 特性 | Traefik | Nginx/HAProxy(传统) |
|---|---|---|
| 配置模型 | 动态、API 驱动、自动发现 | 静态文件、手动更新、需要 reload/restart |
| 服务发现 | 内置支持 Docker、K8s、Consul 等 | 需要外部工具(例如 consul-template)或手动配置 |
| SSL/TLS 管理 | 自动集成 Let's Encrypt | 手动配置,自动化需外部工具或脚本 |
| 动态环境下的复杂度 | 低,原生集成,label/CRD 简单 | 高,自动化需要复杂脚本或编排 |
| 控制台 | 内置 Web 界面 | 通常没有,需第三方监控工具 |
| 主要适用场景 | 微服务、临时容器、云原生环境 | 稳定、长期运行的服务,高性能边缘代理 |
监控与控制台
Traefik 控制台提供图形界面,用于可视化当前路由配置并监控 Traefik 状态。可通过浏览器访问,通常在 8080 端口(如 Docker 示例中所配置)。出于安全考虑,标准做法是用基本认证之类的 middleware 保护控制台。
最佳实践
- 隔离 Traefik: 将 Traefik 运行在专用网络或独立的 Kubernetes namespace 中,以提升安全性并简化管理。
- 保护控制台: 始终用认证(例如
BasicAuthmiddleware)保护 Traefik 控制台,并确保它只对授权人员开放。 - 为 ACME 使用持久化存储: 对于 Let's Encrypt 证书,请确保 ACME 存储路径(例如
/letsencrypt/acme.json)映射到持久化存储,避免容器重启或重新部署时丢失证书。 - 最小权限: 挂载 Docker 套接字(
/var/run/docker.sock)时,确保 Traefik 以所需的最小权限运行。若不需要写权限,可考虑使用只读挂载(:ro)。 exposedbydefault=false: 对于 Docker provider,设置--providers.docker.exposedbydefault=false是安全和管理上的最佳实践。这要求需要暴露的容器显式带上traefik.enable=truelabel。
