Traefik docker 初始化与配置案例

背景

之前在K3S 中用过Traefik,感觉使用起来挺方便的——代理K3S内部服务时,只需要在具体应用中"启用" traefik 代理功能就好。

这点不像传统的反代服务(Nginx/OpenResty):

每新增一个内部服务,就要追加一段 location ^~ /path 配置。

常见反代服务对比

维度 Traefik Nginx OpenResty
核心定位 云原生反向代理 / 入口网关 高性能 Web 服务器 / 反代 可编程 Nginx 网关
服务发现 很强,原生支持 Docker/K8s 等 原生较弱,通常靠静态配置或外部生成 同 Nginx,可用 Lua 扩展
配置方式 动态配置、label、CRD、文件 nginx.conf 静态配置为主 nginx.conf + Lua 代码
HTTPS 自动化 原生 Let’s Encrypt 需配合 certbot/acme.sh 同 Nginx
容器友好度 很高 中等 中等
Kubernetes 入口 原生支持 Ingress / CRD / Gateway API 有 Nginx Ingress Controller 通常不是首选 K8s Ingress
动态路由 较弱,通常 reload 很强,但需要 Lua 开发
可编程能力 中等,靠 middleware/plugin 低到中等 很强
静态文件服务 一般 很强 很强
HTTP 缓存 较弱 很强 很强且可编程
性能 很好 极强 极强
学习成本 中等 中等 较高
运维复杂度 容器环境下较低 配置可控但手工多 高,代码与配置混合
典型场景 Docker/K8s 多服务入口 网站、反代、静态资源、缓存 API 网关、自定义边缘逻辑

Traefik 最明显的定位就是云原生环境下,动态地加载反向代理规则和路由。

下面就以 TrueNAS 中如何安装&配置Traefik 服务为主题,展示各种web 服务的代理配置案例:

  1. 调用本地ACME https 证书

  2. Traefik 代理自己dashboard web页面

  3. Traefik 代理同一docker 网络中的其他docker 应用web页面

  4. Traefik 代理本地宿主机的web 应用页面

效果如下——

image-20260713184236428

算上Traefik 自身服务的代理和health-check接口,共启用了 6个web services。稍候我们会 一一介绍。

image-20260713184428006

安装Traefik

TrueNAS上安装Traefik 有两种方式:

  1. 使用TrueNAS 社区配置模板——web ui安装方便,但是一些参数会与模板配置冲突

  2. 通过docker-compose.yaml 配置文件安装——修改配置参数方便,但需要有docker 的基本概念

    通过yaml 进行安装

docker-compose.yaml 配置文件我已经整理好了,直接粘贴就可以启动啦——

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
version: '3.8'
networks:
  ix-traefik_default:
    external: True
services:
  traefik:
    image: traefik:v3.7.7
    container_name: traefik
    restart: unless-stopped
    command:
      - '--api.dashboard=true'
      - '--ping=true'
      - '--providers.docker=true'
      - '--providers.docker.exposedbydefault=false'
      - '--entrypoints.web.address=:80'
      - '--entrypoints.websecure.address=:443'
      - '--entrypoints.web.http.redirections.entrypoint.to=websecure'
      - '--entrypoints.web.http.redirections.entrypoint.scheme=https'
      # 指定动态配置文件加载路径
      - '--providers.file.filename=/etc/traefik/dynamic_config.yml'
      - '--providers.file.watch=true'
    healthcheck:
      interval: 30s
      retries: 3
      start_period: 10s
      test:
        - CMD
        - traefik
        - healthcheck
        - '--ping'
      timeout: 5s
    ports:
      - '80:80'
      - '443:443'
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /etc/certificates:/etc/certificates:ro
      # 需要提前创建动态配置文件
      - /mnt/YOUR_PATH/dynamic_config.yml:/etc/traefik/dynamic_config.yml:ro
    networks:
      - ix-traefik_default

需要注意的一点是:

因为Traefik 作为web 代理服务器,它自身需要占用tcp 80443 端口。

所以,在启用Traefik 应用前,需要修改宿主机 (TrueNAS) 自身的web 端口到其他不冲突的端口,例如 这里的81 和444。

image-20260713191124300

0. 加载通配符证书

因为TrueNAS 本地保存了 ACME 生成的二级域名证书(*.home.nxlan.cn )——

1
2
3
4
5
6
7
8
9
# ls -al /etc/certificates 
total 45
drwxr-xr-x   3 root root    9 Jul 10 10:34 .
drwxr-xr-x 135 root root  245 Jul 13 15:51 ..
-rw-r--r--   1 root root  745 Jul 13 15:52 ACME_CSR.csr
-r--------   1 root root  306 Jul 13 15:52 ACME_CSR.key
-rw-r--r--   1 root root 4872 Jul 13 15:52 ACME_Certificate.crt
-r--------   1 root root  306 Jul 13 15:52 ACME_Certificate.key
drwxr-xr-x   2 root root    2 Jul 10 10:34 CA

那在Traefik 中就没必要重新申请证书了,所以,这里需要将已有的证书 “”给Traefik 使用。

具体操作上,分两个步骤:

  • 以只读方式挂载配置文件

    1
    2
    3
    4
    
    volumes:
      - /etc/certificates:/etc/certificates:ro
      # 需要提前创建动态配置文件
      - /mnt/YOUR_PATH/dynamic_config.yml:/etc/traefik/dynamic_config.yml:ro
    

    并在配置文件/mnt/YOUR_PATH/dynamic_config.yml 中追加以下内容——

    1
    2
    3
    4
    5
    6
    
    # dynamic_config.yml
    tls:
      certificates:
        # 注意:这里的文件路径实际上指向的是Traefik 应用内部的绝对路径
        - certFile: /etc/certificates/ACME_Certificate.crt
          keyFile: /etc/certificates/ACME_Certificate.key
    
  • 在Traefik 中启用上述动态配置文件

    1
    2
    3
    4
    
    command:  
      # 具体到上述 yaml 配置文件
      - '--providers.file.filename=/etc/traefik/dynamic_config.yml'
      - '--providers.file.watch=true'
    

记得完成这些后:在本地DNS 服务器上 追加域名解析。

这样,就可以使用 https:// + 证书域名 访问Traefik 的https服务了。

image-20260713193341774

当然,此时还没有追加路由策略,页面暂时是没响应的。

为了后续方便查看Traefik 路由策略和后端真实服务的健康状况,我们先把Traefik 自己的dashboard 页面开放出来。

1. 代理Traefik 自身dashboard页面

这里配置其实挺简单的——只需在刚才创建好的dynamic_config.yml 文件基础上,追加 “http -> routers” 配置:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# dynamic_config.yml
tls:
  certificates:
    - certFile: /etc/certificates/ACME_Certificate.crt
      keyFile: /etc/certificates/ACME_Certificate.key
# 👇 新增配置部分      
http:
  routers:
    traefik-dashboard:
      rule: "Host(`traefik.home.nxlan.cn`)"  # 替换成你的仪表盘域名
      entryPoints:
        - websecure
      service: api@internal                 # 直接指引到内部虚拟机服务
      tls: {}                               # 使用上面配置好的 ACME 证书

然后就可以使用这里关联的域名 https://traefik.home.nxlan.cn,访问Traefik dashboard了。

2. 代理其他docker app 的web页面

这里就是 Traefik 这种面向云原生 服务特别的地方:新增一个应用的反代配置,不需要在Traefik 自身配置文件中去定义、修改。

而是在 被代理服务自身,去声明相关代理参数。

如果以直观的 docker-compose.yaml的方式显示就是下面 labels 中的后4条内容——它们都以 traefik.http.routers.[服务名] 作为开头。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21

version: '3.8'

services:
  code-server:
    image: codercom/code-server:latest # 你的 code-server 镜像
    container_name: code-server
    # ...已有的 volumes 或 environment 配置保持不变...
    networks:
      - ix-traefik_default # 👈 确保关联了相同的网络
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.code-server.rule=Host(`code.example.com`)"
      - "traefik.http.routers.code-server.entrypoints=websecure"
      - "traefik.http.routers.code-server.tls=true"
      # 👇 注意:该端口为容器内部端口。如果容器里面开的是 8080,这里就写 8080
      - "traefik.http.services.code-server.loadbalancer.server.port=8080" 

networks:
  ix-traefik_default:
    external: true # 👈 必须声明此网络为外部网络(由 TrueNAS 系统或 Traefik 应用预先创建)

如果要以 TrueNAS 中webUI的方式显示就是这样——

code-server_labels1

code-server_labels2

这两种方式本质是一样的:

都是通过docker 中的 labels 标签去申明、暴露自己的web服务参数,然后由Traefik 服务发现和消费。

labels 标签的发现到生成具体的反代配置过程如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
发现新容器
读取 labels
如果 traefik.enable=true
解析 router/service/middleware 配置
生成路由
转发流量

3. 代理本地宿主机的web 应用页面

最后,还剩下一种情况,就是代理宿主机本地的web 应用。

因为Traefik 对外已经提供了https 的安全连接服务,内部连接时就可以使用普通的http 传输。

具体配置如下——

还是在 dynamic_config.yml 配置文件下,继续追加一个新的 routers 和 services ,例如:

routers:truenas-gui -> service:truenas-web-service

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# dynamic_config.yml
tls:
  certificates:
    - certFile: /etc/certificates/ACME_Certificate.crt
      keyFile: /etc/certificates/ACME_Certificate.key

http:
  routers:
    traefik-dashboard:
      rule: "Host(`traefik.home.nxlan.cn`)"  # 替换成你的仪表盘域名
      entryPoints:
        - websecure
      service: api@internal                 # 直接指引到内部虚拟机服务
      tls: {}                               # 使用上面配置好的 ACME 证书
    # 👇 新增配置部分
    truenas-gui:
      rule: "Host(`true.home.nxlan.cn`)"          # 👈 替换本地 TrueNAS 的域名
      entryPoints:
        - websecure
      service: truenas-web-service
      tls: {}                                  # 使用上面配置好的 ACME 证书

  services:
    truenas-web-service:
      loadBalancer:
        servers:
          - url: "http://192.168.77.20:81"   # 👈 替换成本地TrueNAS 宿主机局域网http服务`IP:81`

总结

最后提醒下:

不要遗漏 Traefik docker-compose配置文件中让服务自动重启的配置——restart: unless-stopped

否则,万一Traefik 服务启动失败,就只能临时使用 https://your-truenas-domain:444 的页面登录TrueNAS,再去手动启动Traefik 服务。

配置好后,后续新增其他docker 服务时,我们只需在新增docker 配置文件中,追加 labels 配置就好。

Traefik会自动发现、加载它们。

例如:后续我在TrueNAS 上新增了个web 画图应用 drawio

只需在drawio 容器中追加以下 labels 配置 ——

1
2
3
4
5
6
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.drawio.rule=Host(`code.example.com`)"
      - "traefik.http.routers.drawio.entrypoints=websecure"
      - "traefik.http.routers.drawio.tls=true"
      - "traefik.http.services.drawio.loadbalancer.server.port=8080" 

Traefik 就可以自动应用代理转发配置。

image-20260713200530236

Licensed under CC BY-NC-SA 4.0