【Docker】之 Traefik 安装部署

简介

  Traefik 是一款开源的边缘路由器,可以作为整个平台的入口(网关),根据逻辑规则,处理并路由整个传入的请求。

  1. 自动服务发现
  2. 原生兼容所有主要集群技术,例如 Kubernetes、Docker、Docker Swarm、AWS、Mesos、Marathon,并且可以同时处理多个。
  3. 无需维护和同步单独的配置文件,自动实时更新,无需重新启动,不会中断连接
  4. 集成了漂亮的 dashboard 界面

配置

Traefik 中的配置分为2部分

  • 全动态路由配置(动态配置),从Provider获取定义如何由系统来处理请求。此配置可以更改并无缝热重载,不会出现任何请求中断或连接丢失。
  • 启动配置(静态配置),设置与Provider连接并定义Traefik 将侦听的入口点。

静态配置

  Traefik 中定义静态配置选项有三种不同的、互斥的(即您只能同时使用一种)的方法:

  • 在配置文件中
  • 在命令行参数中
  • 作为环境变量

  配置文件
  启动时,Traefik 在以下位置搜索名为traefik.yml(或traefik.yamltraefik.toml)的文件:

  • /etc/traefik/
  • $XDG_CONFIG_HOME/
  • $HOME/.config/
  • .(工作目录)

  可以使用configFile参数覆盖它:

traefik --configFile=foo/bar/myconfigfile.yml

参数

  可以使用 traefik --help 获取参数:

--accesslog:
访问日志设置。(默认值:false)

--api:
启用 api/仪表板。(默认值:false)

--certificatesresolvers.<name>:
证书解析器配置。(默认值:false)

--entrypoints.<name>:
入口点定义。(默认值:false)

--log:
Traefik 日志设置。(默认值:false)

--pilot.dashboard:
在仪表板中启用 Traefik Pilot。(默认值:true)

--ping:
启用ping。(默认值:false)

--providers.docker:
使用默认设置启用 Docker 后端。(默认值:false)

环境变量

  常见的环境变量有(和参数一样,只不过换成大写形式,加上TRAEFIK_前缀):

TRAEFIK_ACCESSLOG:
访问日志设置。(默认值:false)

TRAEFIK_API:
启用 api/仪表板。(默认值:false)

TRAEFIK_CERTIFICATESRESOLVERS_<NAME>:
证书解析器配置。(默认值:false)

TRAEFIK_ENTRYPOINTS_<NAME>:
入口点定义。(默认值:false)

TRAEFIK_LOG:
Traefik 日志设置。(默认值:false)

TRAEFIK_PILOT_DASHBOARD:
在仪表板中启用 Traefik Pilot。(默认值:true)

TRAEFIK_PING:
启用ping。(默认值:false)

TRAEFIK_PROVIDERS_DOCKER:
使用默认设置启用 Docker 后端。(默认值:false)

Docker部署Traefik

创建目录

mkdir -p /root/docker/traefik/{config,ssl}

创建外部网卡

docker network create traefik \
-o com.docker.network.bridge.name=traefik \
-o com.docker.network.bridge.host_binding_ipv4=0.0.0.0 \
--driver=bridge --subnet=172.18.0.0/16 --gateway=172.18.0.1

docker-compose.yml

version: '3.9'

services:

  traefik:
    container_name: traefik
    image: traefik:v2.9.1
    restart: always
    ports:
      # The HTTP port
      - 30080:80
      # Https
      - 443:443
      # The Web UI (enabled by --api.insecure=true)
      - "38080:8080"
    networks:
      - traefik
    command: traefik --configFile /etc/traefik.toml
    volumes:
      # So that Traefik can listen to the Docker events
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./ssl/:/data/ssl/:ro
      - ./traefik.toml:/etc/traefik.toml:ro
      - ./config/:/etc/traefik/config/:ro
    healthcheck:
      test: ["CMD-SHELL", "wget -q --spider --proxy off localhost:8080/ping || exit 1"]
      interval: 3s
      timeout: 5s

# 先创建外部网卡 docker network create traefik
networks:
  traefik:
    external: true

  command二选一

command: traefik --configFile /etc/traefik.toml
command:
  - "--entrypoints.http.address=:80"
  - "--entrypoints.https.address=:443"
  - "--api=true"
  - "--api.insecure=true"
  - "--api.dashboard=true"
  - "--api.debug=false"
  - "--ping=true"
  - "--providers.docker=true"
  - "--providers.docker.watch=true"
  - "--providers.docker.exposedbydefault=false"
  - "--providers.docker.endpoint=unix:///var/run/docker.sock"
  - "--providers.docker.swarmMode=false"
  - "--providers.docker.useBindPortIP=false"
  - "--providers.docker.network=traefik"
  - "--providers.file=true"
  - "--providers.file.watch=true"
  - "--providers.file.directory=/etc/traefik/config"
  - "--providers.file.debugloggeneratedtemplate=true"

路由与负载均衡

  当使用 Docker 作为provider 时,Traefik 使用容器标签(labels)来检索其路由配置。
  完整的Traefik 的架构分为这几部分:

  • entryPoints 侦听传入流量(端口,…)EntryPoints 是 Traefik 的网络入口点。它们定义了将接收数据包的端口,以及是侦听 TCP 还是 UDP。
  • routers 分析请求(主机、路径、标头、SSL 等),路由器负责将传入请求连接到可以处理它们的服务
  • services 将请求转发给您的服务(负载平衡,…)
  • middlewares 可能会更新请求或根据请求做出决定(身份验证、速率限制、标头等)
  • providers 发现存在于您的基础架构上的服务(他们的 IP、健康状况……)

entryPoints

EntryPoints 是 Traefik 的网络入口点。它们定义将接收请求的端口(无论是 HTTP 还是 TCP)

部署中指定,可以是启动命令参数:
command:
	- "--entrypoints.http.address=:80"
静态配置文件中:
entryPoints:
  http:
   address: ":80"

Provider配置

  • endpoint必需默认=“unix:///var/run/docker.sock”
  • useBindPortIP可选,默认=false,Traefik 将请求路由匹配到容器的 IP/端口。设置useBindPortIP=true,Traefik 使用附加到容器绑定的 IP/端口,而不是其内部网络 IP/端口。当与traefik.http.services.<name>.loadbalancer.server.port标签结合使用时(告诉 Traefik 将请求路由匹配到特定端口),Traefik 会尝试在 port 上找到绑定traefik.http.services.<name>.loadbalancer.server.port。如果找不到这样的绑定,Traefik 会回退到容器的内部网络 IP,但仍然使用traefik.http.services.<name>.loadbalancer.server.port标签中设置的IP/端口 。
  • exposedByDefault可选,默认=true。默认情况下Traefik 公开容器。如果设置为falsetraefik.enable=true则从生成的路由配置中忽略没有标签的容器。
  • network可选,默认=“”定义用于连接到所有容器的默认 docker 网络。可以使用traefik.docker.network标签在每个容器的基础上覆盖此选项。
  • defaultRule可选,默认=Host()如果标签未定义任何规则,则该选项定义要应用于容器的路由规则。
  • swarmMode可选,默认=false。启用 Swarm 模式(而不是独立的 Docker)。
  • swarmModeRefreshSeconds可选,默认值=15。定义群模式的轮询间隔(以秒为单位)。
  • httpClientTimeout可选,默认=0。定义 HTTP 连接的客户端超时(以秒为单位)。如果它的值为0,则不设置超时。
  • watch可选,默认=true。监听 Docker Swarm 事件。

    中间件配置

    # 在 labels 中指定
    traefik.http.middlewares.中间件名称.中间件类型=
    
    常用中间件类型
    • AddPrefix 添加前缀
      # Prefixing with /foo
      labels:
        - "traefik.http.middlewares.add-foo.addprefix.prefix=/foo"
      
    • BasicAuth 添加基本身份验证
      labels:
        - "traefik.http.middlewares.test-auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0"
      
    • Buffering 限制了可以转发到服务的请求的大小。
      通过缓冲,Traefik 将整个请求读入内存(可能将大请求缓冲到磁盘中),并拒绝超过指定大小限制的请求。这可以帮助服务避免大量数据(multipart/form-data例如),并且可以最大限度地减少向服务发送数据所花费的时间。
      # Sets the maximum request body to 2MB
      labels:
        - "traefik.http.middlewares.limit.buffering.maxRequestBodyBytes=2000000"
      
    • Compress 中间件使用 gzip 压缩
    • ContentType 指定是否让Content-Type标头(如果后端尚未定义)自动设置为从响应内容派生的值。
    • DigestAuth 中间件将您的服务的访问权限限制为已知用户
    • ErrorPage 中间件根据 HTTP 状态代码的配置范围返回一个自定义页面来代替默认页面。
    • ForwardAuth 中间件将身份验证委托给外部服务。如果服务以 2XX 代码应答,则授予访问权限,并执行原始请求。否则,返回来自认证服务器的响应。
    • Headers 中间件管理请求和响应的标头。
    • IPWhitelist 根据客户端 IP 接受/拒绝请求。
    • inflightreq 限制同时进行中的请求数
    • PassTLSClientCert 将通过的客户端 TLS 证书中的选定数据添加到标头中。
    • RateLimit 控制进入服务的请求数
    • RedirectRegex 使用正则表达式匹配和替换来重定向请求。
    • RedirectScheme 将请求从一个方案/端口重定向到另一个。
    • replacepath 替换请求 URL 的路径。
    • ReplaceRegex 使用正则表达式匹配和替换来替换 URL 的路径。
    • retry 如果后端服务器没有回复,重试中间件向后端服务器重新发出给定次数的请求。服务器一响应,中间件就会停止重试,无论响应状态如何。Retry 中间件有一个可选配置来启用指数退避。
    • stripprefix 在转发请求之前从路径中删除前缀
    • stripprefixregex 在转发请求之前从路径中删除前缀(使用正则表达式)

Router配置

# 指定路由入口点,http为traefik启动时定义的端口
"traefik.http.routers.自定义路由名称.entrypoints=http"

# 定义路由规则,监听来自于域名的请求,Host中用`符号
"traefik.http.routers.自定义路由名称.rule=Host(`www.domain.com`)"

# 设置路由引用中间件
"traefik.http.routers.自定义路由名称.middlewares=中间件名称" 

# 指定路由后端为哪个service,多个service时需要具体指定路由到哪个
"traefik.http.routers.自定义路由名称.service=服务名" 

Services配置

 ## 用于docker服务发现与负载均衡,自动发现指定端口的服务,作为后端服务
 ## 如果容器expose了单个端口,则 Traefik 使用此端口进行私有通信
 ## 如果一个容器 expose了多个端口,或者没有暴露任何端口,那么你必须使用标签手动指定 Traefik 应该使用哪个端口进行通信

"traefik.http.services.自定义服务名.loadbalancer.server.port=应用端口"

示例

version: '3'
services:
  wg-easy:
    image: weejewel/wg-easy
    container_name: wg-easy
    environment:
      - WG_HOST=18.183.2.23
      - WG_DEFAULT_DNS=114.114.114.114,8.8.4.4
    ports:
      - "51820:51820/udp"
    sysctls:
      - net.ipv4.ip_forward=1
      - net.ipv4.conf.all.src_valid_mark=1
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    labels:

      # 启用 traefik 动态配置
      - "traefik.enable=true"

      # 设置trafik 网络
      - "traefik.docker.network=traefik"

      ##  定义名为 auth-user 的 基本认证 中间件,密码使用htpasswd生成,$作为转义字符
      - "traefik.http.middlewares.auth-users.basicauth.users=admin:$$apr1$$WArvArno$$CUyHO2J8dg6BQNUbhTiwA."   

      # 定义名为 wg-easy 的路由,该路由在入口点 Web(端口80)上侦听
      - "traefik.http.routers.wg-easy.entrypoints=http"

      ## 设置wg-easy路由入口点 引用中间件auth-users
      - "traefik.http.routers.wg-easy.middlewares=auth-users" 
      
      ##  定义此 wg-easy 路由规则,监听来自于域名为he.simple11618.xyz的请求,将其路由到服务
      - "traefik.http.routers.wg-easy.rule=Host(`he.simple11618.xyz`)"

      ## 将请求转发到容器上的端口,需要使用路由器上的service参数引用服务负载均衡器端口定义
      ## 默认转发到expose的第一个端口,多端口需要单独指定
      - "traefik.http.services.my-service.loadbalancer.server.port=51821"


    networks:
      - traefik

networks:
  traefik:
    external: true

PS

参考:
Traefik的官方文档
Docker 个人服务器运维
Traefik学习
docker篇-(docker-compose安装web网关traefik)