Traefik 示意图

Traefik 是一个用于反向代理的软件,如果你没有听说过,可以把它看作 Nignx 也是可以的。

Traefik 相比与 Nginx 更适合容器化部署:

  1. 只需要配置下容器的标签,Traefik 就可以自动发现新服务的加入,并根据标签绑定对应的域名
  2. 支持 TLS 证书自动申请(Let’s Encrypt)
  3. 支持 TCP/UDP 协议的转发
  4. 支持动态配置,可以在服务运行的状态下进行 ServiceRouterMiddleware 的增/删/改

Traefik 在项目最初部署阶段,会让整个部署更聚焦。以前用 Nginx 部署,你除了需要把容器启动起来,还需要配置 Nignx 将对应服务的域名反向代理到容器导出的端口上。

Traefik 将这个绑定域名的步骤放在了 docker compose 编写的阶段只需给容器加一个标签即可。项目上线时启动容器,Traefik 根据标签的配置把域名绑定到对应的容器上。

Traefik 可以通过 docker network 容器进行通讯,这意味着容器服务的端口无须再导出到物理机,Traefik 通过 docker network 就可以找到对应的容器处理请求。

Traefik 整个流程如下(中间件非必须,可有可无):

入口点(Entrypoints) -> 路由(Routers) -> [中间件(Middleware)] -> 服务(Service) -> Server

Traefik 的配置分为两个:程序配置和路由配置。程序配置通过 traefik.yml 文件进行配置。traefik.yml 提供了路由配置的解析引擎(Providers)。

traefik.yml 配置示例如下:

log:
    level: INFO
accessLog: {}
api:
    dashboard: true
    insecure: true

entryPoints: # 入口点配置
    web:
        address: ":80"


providers:
    docker: # 通过 docker label 的方式进行路由配置
        endpoint: "unix:///var/run/docker.sock"
        exposedByDefault: false
        watch: true
        network: traefik_webgateway // docker network 用于 traefik 与容器进行通讯

接下来说说 Traefik 一些核心概念:

Providers

Providers 并不在反向代理的流程里,他的存在只是为了告诉 Traefik 由谁来提供路由配置。

Traefik 支持 DockerSwarmKubernetes IngressRouteKubernetes Gateway APIConsul CatalogNomadECSKV

本文后续关于路由相关的配置统一用 Docker Label 的形式来展现。

入口点 ( Entrypoints )

指的 Traefik 的监听端口,你可以分别建立 HTTP , TCP , UDP 等多个入口点。

路由会绑定入口点,当一个请求来时,会根据请求的端口来找到对应的入口点,并通过请求路由去寻找绑定该入口点下的路由。

入口点通过 traefik.yml 的配置文件配置

entryPoints:
    web:
        address: ":80"

路由( Routers )

Traefik 的指路人,告诉 Traefik 要找谁来处理请求。

路由的配置如下:

services:
  web:
    ...
    labels:
      traefik.http.routers.myrouter.rule=Host(`domain.com`)

中间件 ( Middleware )

在请求到达 Service 前做一些额外的处理,例如增加请求头,替换请求的 path ,也可以做一些权限校验,IP 黑名单等操作。

服务 ( Service )

服务是实际处理请求的一个抽象集合,请求会在服务下找一个正常的 Server 进行处理。

服务配置如下:

services:
  web:
    ...
    labels:
      - "traefik.http.services.myservice.loadbalancer.server.port=8000"

- "traefik.http.services.myservice.loadbalancer.healthCheck.path=/health"

- "traefik.http.services.myservice.loadbalancer.healthCheck.interval=10s"

- "traefik.http.services.myservice.loadbalancer.healthCheck.timeout=1s"

Server

Server 是在服务下具体干活的角色,一个服务可以包含多个 ServerServerProviders=docker 的时候,就是一个个容器。

Docker Compose 示例

services:
  web:
    restart: always
    labels:
        - "traefik.enable=true" # 启动 traefik 服务发现
        - "traefik.http.routers.myrouter.rule=Host(`domain.com`)" # 路由绑定域名
        - "traefik.http.routers.myrouter.entrypoints=web" # 配置入口点
        - "traefik.http.routers.myrouter.rule=PathPrefix(`/`)"
        - "traefik.http.middlewares.test-retry.retry.attempts=5"
        - "traefik.http.middlewares.test-retry.retry.initialinterval=200ms"
        - "traefik.http.services.myservice.loadbalancer.server.port=8000" # 服务端口号,即容器内部监听的端口号    
        - "traefik.http.services.myservice.loadbalancer.healthCheck.path=/health" # 服务健康检测的 path
        - "traefik.http.services.myservice.loadbalancer.healthCheck.interval=10s" # 服务健康检测间隔时间
        - "traefik.http.services.myservice.loadbalancer.healthCheck.timeout=1s" # 服务健康检测超时时间
    networks:
      - traefik
    environment:
      - CONTAIN_NAME=takeout-blue
networks:
  traefik:
    name: traefik_webgateway # traefik.yml 配置的 network
    external: true

总结

Traefik 以它更容易,更紧密的结合 dockerk8s 在云原生的场景下有了自己的一席之地。本文仅是粗略的概括了 Traefik 的一些特性,构建出一个大致的学习地图,如果你也对 Traefik 感兴趣,可以选择通过官方文档进一步学习。

文末示例项目为一个 Traefik 快速上手的项目,如有需要可以下载下来启动一下辅助理解。

Reference

traefik doc : https://doc.traefik.io/traefik/

示例项目: https://github.com/yunxi177/traefik