首页
/ 如何用 Traefik 的 Nomad Provider 根据服务标签自动生成路由

如何用 Traefik 的 Nomad Provider 根据服务标签自动生成路由

2026-09-08 19:15:51作者:申梦珏Efrain

如果你的服务跑在 HashiCorp Nomad 上,并且希望 Traefik 能够根据服务自身的标签(tags)自动发现并生成 HTTP 路由,那么需要启用 Traefik 的 Nomad Provider。完成这篇文章的操作后,Traefik 会轮询 Nomad API 获取服务列表,把每个 Nomad service 的 tags 解析成 Traefik 的动态路由配置:新增、删除或修改服务标签时,路由随之自动更新,不需要再手动维护文件式路由规则。

前提条件:

  • 一个正在运行的 Nomad 集群,Traefik 能够访问其 API(默认连接 http://127.0.0.1:4646);
  • Traefik 的静态配置可修改(配置文件或启动参数均可)。

启用 Nomad Provider

在 Traefik 的静态配置中开启 provider 即可,文档支持三种等价写法:

# File (YAML)
providers:
  nomad: {}
# File (TOML)
[providers.nomad]
# CLI
--providers.nomad=true

Provider 完整选项说明见 Nomad Provider 文档。常用的几个配置项:

配置项 作用 默认值
providers.nomad.endpoint.address Nomad 服务器地址 http://127.0.0.1:4646
providers.nomad.endpoint.token Nomad 开启 ACL 时使用的每请求 ACL token(对应权限为 read-job ""
providers.nomad.refreshInterval 轮询间隔,开启 watch 后此选项被忽略 15s
providers.nomad.watch 启用 watch 模式,按事件刷新配置 false
providers.nomad.exposedByDefault 是否默认暴露所有 Nomad 服务 true
providers.nomad.namespaces 限定在哪些 Nomad namespace 中发现服务 ""

默认情况下,Provider 每 15s 轮询一次 Nomad API;服务变更会在这个周期内反映到路由上。如果希望按事件即时刷新,可以开启 watch 模式(此时可配合 providers.nomad.throttleDuration 限制事件处理频率,该选项只在 watch 启用时可用)。

一个启用 Provider 并指向远程 Nomad 节点的完整示例:

providers:
  nomad:
    endpoint:
      address: "http://192.168.1.10:4646"
    refreshInterval: 5s

在 Nomad Job 中通过 tags 定义路由

这是整个流程的核心:Traefik 会把 Nomad service 的 tags 当作配置来源。文档给出的最小示例是在 job 文件的 service 段里给服务加上路由规则 tag(文档示例):

job "my-service" {
  datacenters = ["dc1"]

  group "web" {
    task "app" {
      driver = "docker"

      service {
        name = "my-service"
        tags = [
          "traefik.http.routers.my-service.rule=Host(`example.com`)",
        ]
      }
    }
  }
}

规则生效后的效果:

  • Traefik 为每个发现的 Nomad service 自动创建一个同名的 Traefik service,并为每个服务实例注册一个 server;
  • 同时自动生成一个默认路由,规则为服务名(默认模板是 Host({{ normalize .Name }}),即 Host(my-service));
  • 如果 tags 中通过 traefik.http.routers.<名称>.rule 显式定义了规则(如上例),则以该规则覆盖默认规则。

也就是说,如果什么都不配,my-service 也会有一条 Host(my-service) 的路由指向它。想让某个域名指向该服务,就加一条 rule tag。

指定转发端口:避免 502

默认情况下,Traefik 使用该容器暴露的第一个端口。当服务实际监听端口不是第一个端口时,会出现 HTTP/502 Gateway Error。解决方法是用 tag 覆盖目标端口:

service {
  name = "my-service"
  tags = [
    "traefik.http.routers.my-service.rule=Host(`example.com`)",
    "traefik.http.routers.my-service.service=my-service",
    "traefik.http.services.my-service.loadbalancer.server.port=12345",
  ]
}

traefik.http.services.<名称>.loadbalancer.server.port 会覆盖“取第一个端口”的默认行为。此外,如果只按 Nomad Service Discovery 的默认流程暴露端口(例如在 job 中暴露 :1337),Traefik 也能直接检测到并使用该端口。

一个容器挂多个路由和服务

需要把多个域名转发到同一容器的不同端口时,用 service 参数把 router 指到各自的服务,再分别为每个服务定义端口:

service {
  name = "my-service"
  tags = [
    "traefik.http.routers.www-router.rule=Host(`example-a.com`)",
    "traefik.http.routers.www-router.service=www-service",
    "traefik.http.services.www-service.loadbalancer.server.port=8000",
    "traefik.http.routers.admin-router.rule=Host(`example-b.com`)",
    "traefik.http.routers.admin-router.service=admin-service",
    "traefik.http.services.admin-service.loadbalancer.server.port=9000",
  ]
}

这样 http://example-a.com 转发到容器 8000 端口,http://example-b.com 转发到 9000 端口。

用 tags 声明并引用 Middleware

中间件同样可以用 tags 声明,前缀是 traefik.http.middlewares.<名称>.,然后由 router tag 引用。例如声明一个 HTTPS 重定向中间件:

# 声明 middleware
traefik.http.middlewares.my-redirect.redirectscheme.scheme=https
# router 引用它
traefik.http.routers.my-service.middlewares=my-redirect

注意文档中明确的限制:如果有多个同名字中间件但参数不同,中间件会声明失败。

Router 与 Service 可配置的全部 tag 选项(entrypointsmiddlewarestlspriorityhealthchecksticky.cookie 等)见 Nomad 路由配置文档

控制哪些服务会被发现

exposedByDefault 默认为 true,即 Traefik 会为所有检测到的 Nomad 服务创建路由。如果只想暴露部分服务,把它设为 false,并在需要暴露的服务上加 traefik.enable=true tag:

providers:
  nomad:
    exposedByDefault: false
service {
  name = "my-service"
  tags = [
    "traefik.enable=true",
    "traefik.http.routers.my-service.rule=Host(`example.com`)",
  ]
}

traefik.enable 会覆盖 exposedByDefault 的取值。另一种更细粒度的方式是 constraints 表达式,用 Tag() / TagRegex() 函数匹配服务标签,例如:

[providers.nomad]
  # 只包含带有标签 a.tag.name=foo 的服务
  constraints = "Tag(`a.tag.name=foo`)"

文档提醒:traefik.* 是保留标签命名空间,不能用作自定义 constraints 的键。两种方式的完整说明见 Provider 概览文档中的 Restrict the Scope of Service Discovery 一节

另外,如果 Nomad 启用了 namespace,可以用 providers.nomad.namespaces 限定发现范围;此时发现的对象名会带后缀,格式为 <resource-name>@nomad-<namespace>。文档同时警告:namespacesnamespace 两个选项只能二选一。

验证路由是否生成

Traefik 自带 API(默认在 traefik entrypoint 的 8080 端口),可以用来核对动态路由是否按预期生成,端点定义见 API & Dashboard 文档

# 列出所有 HTTP 路由,确认 my-service 路由存在且 rule 正确
curl http://<traefik-host>:8080/api/http/routers

# 列出所有 HTTP 服务,确认服务及其 server 地址、端口
curl http://<traefik-host>:8080/api/http/services

判断标准:修改 job 的 tags 并让 Nomad 生效后(轮询模式下最长等一个 refreshInterval 周期),上述接口中应出现对应的 router/service 条目,rule 与 tags 中定义的 Host(example.com) 一致。文档未给出这些接口的固定示例输出,实际返回字段以接口输出为准。

限制与注意事项

  • tags 大小写不敏感,但值里的域名等配置按字符串解析。
  • 不要把敏感数据放进 tags。文档明确建议:证书、凭据等应存放在 secrets 或文件等更安全的位置,而不是服务标签里。
  • 声明 TCP/UDP Router 或 Service 的副作用:一旦为某个 Nomad 服务声明了 TCP(或 UDP)Router/Service,Traefik 就不会再为它自动创建 HTTP Router/Service。HTTP 与 TCP 路由可以共存,但必须手动分别声明。
  • defaultRule 模板限制:自定义默认规则必须是合法的 Go template(支持 sprig 函数),通过 Name 标识符访问服务名,并可访问该服务上所有带 prefix(默认 traefik)的标签。文档还提示:如果 Traefik 自身也被暴露且命中默认规则,可能产生指向自己的路由环,Traefik 会加内部中间件拒绝来自同一路由的转发以防死循环。
  • 多 Provider 共存时的优先级:未显式配置 providers.precedence 时,nomad 在默认优先级表中排第 12 位,低于 kubernetesgatewaykubernetescrdkubernetesswarmdockerfile 等;它只在两个 Provider 的路由规则相同且 priority 数值相等时起 tiebreaker 作用。

相关文档:Nomad Provider 配置Nomad 路由配置(tags 全量选项)

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.76 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
860
1.35 K
docsdocs
暂无描述
Markdown
899
5.83 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
925
1.85 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.84 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
533
601
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.03 K
525
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.37 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
395