首页
/ Traefik Kubernetes CRD 提供程序完全指南:配置 kubernetesCRD 与自定义资源路由

Traefik Kubernetes CRD 提供程序完全指南:配置 kubernetesCRD 与自定义资源路由

2026-09-06 16:27:49作者:凤尚柏Louis

本文以 Traefik 官方文档中的 Kubernetes Custom Resources 配置参考为主体,完整覆盖 kubernetesCRD 提供程序的启用方式、全部配置参数、endpoint 连接机制与 Traefik CRD(如 IngressRouteMiddleware)资源清单,并结合 pkg/provider/kubernetes/crd 下的源码实现,说明事件监听、节流(throttling)、跨命名空间引用等关键机制的底层原理。读完本文,你可以在不使用 Helm Chart 的情况下手动安装 Traefik CRD 与 RBAC、正确配置并调优 CRD 提供程序,并理解每个配置项在源码中对应的实际行为。

一、什么是 kubernetesCRD 提供程序

Traefik 通过 Kubernetes 自定义资源(Custom Resources,如 IngressRouteMiddleware 等)暴露了自身的路由能力。当启用 kubernetesCRD 提供程序时,Traefik 基于 Kubernetes 的 Custom Resource Definition(CRD)机制来获取动态路由配置——即它把 traefik.io 组下的 CRD 资源"翻译"成 Traefik 内部的动态配置(HTTP/TCP/UDP 路由、中间件、TLS 选项与存储、后端传输参数等)。

从源码看,这一翻译逻辑集中在 CRD 提供程序实现Provider.Provide 方法启动一个工作协程,先创建 Kubernetes 客户端,随后通过 k8sClient.WatchAll 监听资源事件,每次事件触发时调用 loadConfigurationFromCRD 重建整份动态配置并写入配置通道(dynamic.Message),由 Traefik 服务器热加载。

如果通过 Helm Chart 安装 Traefik,kubernetesCRD 提供程序默认就是启用的;只有手动安装或手工升级时,才需要自行满足下文的前置要求。

二、前置要求:安装 CRD 定义与 RBAC

当你不使用 Helm Chart 安装 Traefik,或者正在通过 Helm 升级整套 Traefik 资源时,文档明确要求做两件事:

  1. 添加/更新全部 Traefik 资源的 CRD 定义;
  2. 添加/更新 Traefik 自定义资源的 RBAC。

原始文档给出的安装命令引用的是远程清单文件,在当前仓库中这两个清单同样存在,可直接从仓库获取:

安装方式为(以本地清单路径替换对应地址):

# 安装 Traefik 资源定义(CRD)
kubectl apply -f docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml

# 安装 Traefik 所需 RBAC
kubectl apply -f docs/content/reference/dynamic-configuration/kubernetes-crd-rbac.yml

查看 kubernetes-crd-definition-v1.yml 可以看到,每个 CRD 都是标准的多文档清单,例如 ingressroutes.traefik.io 的 group 为 traefik.io、kind 为 IngressRoute、scope 为 Namespaced、版本为 v1alpha1。仓库中还按资源类型提供了独立的参考清单,如 traefik.io_ingressroutes.yamltraefik.io_middlewares.yamltraefik.io_traefikservices.yaml 等。

再看 kubernetes-crd-rbac.yml,ClusterRole traefik-ingress-controller 授权的资源范围与提供程序行为一一对应:

  • servicessecretsnodesconfigmapsget/list/watch——分别对应 IngressRoute 引用的后端 Service、TLS 证书 Secret、NodePortLB 依赖的 Node 以及 ServersTransport 的 CA ConfigMap;
  • podsget——注释中说明该权限用于注入 k8s.pod.uidk8s.pod.name 的 OTel 属性,未启用 OTel 追踪/日志/指标时并非必需;
  • endpointslices(discovery.k8s.io):list/watch——提供程序通过 EndpointSlice 而非 Endpoints 获取后端 Pod 地址;
  • ingressesingressclassesingresses/status:用于兼容原生 Ingress 场景(ingressClass 参数的处理);
  • traefik.io 组下的 10 类资源:middlewaresmiddlewaretcpsingressroutestraefikservicesingressroutetcpsingressrouteudpstlsoptionstlsstoresserverstransportsserverstransporttcps,均为 get/list/watch

这一 RBAC 范围与 disableClusterScopeResources 参数直接呼应:该选项开启后,Traefik 不再发现集群级资源(IngressClassNodes),从而可以收回对应的集群资源读取权限——详见后文。

三、启用 kubernetesCRD 提供程序

文档给出了四种等价的启用方式:

文件配置(YAML):

providers:
  kubernetesCRD: {}

文件配置(TOML):

[providers.kubernetesCRD]

命令行参数(CLI):

--providers.kubernetescrd=true

Helm Chart Values 文件:

providers:
  kubernetesCRD:
    enabled: true

在静态配置结构体中,该开关对应 static_config.go 中的 KubernetesCRD 字段(*crd.Provider),字段描述为 "Enables Kubernetes CRD provider",即只要该结构体非空,提供程序即被启用。

四、配置参数完整说明

以下为文档中 Configuration Options 一节的全部参数(含默认值与是否必填),结合源码字段注释整理:

字段 说明 默认值 必填
providers.providersThrottleDuration 配置重载后,在响应下一次新的配置刷新事件之前需要等待的最短时间。若该时间内发生多次事件,只处理最近一次,其余全部丢弃。此选项不能按提供程序单独设置,但节流算法对每个提供程序独立生效。 2s
providers.kubernetesCRD.endpoint 服务端点 URL,详见下文 endpoint 小节。 ""
providers.kubernetesCRD.token Kubernetes 客户端配置使用的 Bearer token(集群内客户端不需要)。接受 token 值本身,或 token 所在文件的路径。 ""
providers.kubernetesCRD.certAuthFilePath 证书颁发机构(CA)文件路径,用于 Kubernetes 客户端配置。 ""
providers.kubernetesCRD.namespaces 要监听的命名空间数组。留空则监听所有命名空间。 []
providers.kubernetesCRD.labelSelector 使用 label 选择器过滤特定资源对象。仅作用于 Traefik 自定义资源(所有资源都必须匹配该过滤条件),对 Kubernetes SecretsEndpointSlicesServices 无效。 ""
providers.kubernetesCRD.ingressClass 用于识别要处理的资源对象的 spec.ingressClassName 字段(或已弃用的 kubernetes.io/ingress.class 注解)的取值。若为空,缺失该字段/注解、值为空、或值为 traefik 的资源都会被处理。spec.ingressClassName 字段优先于注解。 ""
providers.kubernetesCRD.throttleDuration 两次 Kubernetes 事件之间生成新配置前的最短等待时间,防止每秒更新多次的集群让 Traefik 配置被持续刷新。为空时每个事件都会触发刷新。 0s
providers.kubernetesCRD.allowEmptyServices 允许创建指向没有可用 endpoint 的服务的路由,使 Traefik 可以先对该服务执行中间件与可观测性处理,再返回 503 false
providers.kubernetesCRD.allowCrossNamespace 允许 IngressRoutes 引用其所在命名空间之外的资源。 false
providers.kubernetesCRD.allowExternalNameServices 允许 IngressRoutes 引用 ExternalName 类型的 Service。 false
providers.kubernetesCRD.crossProviderNamespaces 允许 IngressRouteIngressRouteTCPIngressRouteUDPTraefikService 声明跨提供程序引用(如 myservice@file)的命名空间列表。未设置时所有命名空间均允许;显式设为 [] 时所有跨提供程序引用都会被拒绝。 []
providers.kubernetesCRD.nativeLBByDefault 默认对所有 IngressRoute 使用 Kubernetes Service 原生负载均衡(在 Pod 之间),而不是 Traefik 自带的负载均衡。可在 Service 级配置中覆盖。 false
providers.kubernetesCRD.disableClusterScopeResources 禁止发现集群级资源(IngressClassNodes),从而降低对 Traefik 集群资源读取权限的要求。开启后,带 IngressClass 引用的 IngressRoutes 不会被处理(注解不受此选项影响),同时也不能在 Service 上使用 NodePortLB 选项。 false

对应源码中,这些字段完整定义在 Provider 结构体EndpointTokentypes.FileOrContent 类型,即"值或文件路径"二合一)、CertAuthFilePathNamespacesLabelSelectorIngressClassThrottleDurationAllowEmptyServicesAllowCrossNamespaceAllowExternalNameServicesCrossProviderNamespacesNativeLBByDefaultDisableClusterScopeResources

几个参数在源码中有值得注意的行为细节:

  • 启动期校验Provide 启动时会打印安全提示日志——启用 allowCrossNamespace 输出 Warn 级日志提醒确认符合预期;启用 allowExternalNameServices 输出 Info 日志;crossProviderNamespaces 非 nil 时同样输出 Warn 日志说明受限范围。
  • ingressClass 匹配逻辑shouldProcessIngress 实现了"未设置 ingressClass 时,类名为 traefik 的资源默认被处理"的语义;getIngressClassName 则体现了"字段优先于注解、注解已弃用"的取值顺序。
  • labelSelector 校验newK8sClient 在创建客户端前先用 labels.Parse 解析 LabelSelector,非法选择器会直接返回 "invalid label selector" 错误,而不是运行期静默失败。
  • nativeLB 的 Service 级覆盖nativeLBByDefault 的默认值可在单个 Service 配置中覆盖,参考 Service 文档

endpoint:Kubernetes API 连接方式

文档 endpoint 小节说明的连接规则,与源码 newK8sClient 的实现完全对应,优先级为:

  1. 若环境变量 KUBERNETES_SERVICE_HOSTKUBERNETES_SERVICE_PORT 均存在——判定为集群内部署,走 in-cluster 客户端。此时访问 token 从 /var/run/secrets/kubernetes.io/serviceaccount/token、CA 证书从 /var/run/secrets/kubernetes.io/serviceaccount/ca.crt 读取,两者在集群内部署时由 Kubernetes 自动挂载。若设置了 endpoint,会用它覆盖 in-cluster 配置中的 Host(对应 newInClusterClientconfig.Host = endpoint);
  2. KUBECONFIG 环境变量存在——从该 kubeconfig 文件构建集群外客户端(newExternalClusterClientFromFile);
  3. 否则——走集群外客户端,此时 endpoint 必填newExternalClusterClient 在 endpoint 为空时直接报错 "endpoint missing for external cluster client"),可配合 tokencertAuthFilePath 认证。文档特别指出,endpoint 可以设为 kubectl proxy 的地址,从而复用 kubeconfig 的认证与授权能力。

配置示例(与文档一致):

providers:
  kubernetesCRD:
    endpoint: "http://localhost:8080"
    # ...
[providers.kubernetesCRD]
  endpoint = "http://localhost:8080"
  # ...
--providers.kubernetesCRD.endpoint=http://localhost:8080

事件节流:throttleDuration 与 providersThrottleDuration 的两级机制

文档将节流分为两层,源码中同样能清晰看到:

  • 提供程序层throttleEvents 函数实现 throttleDuration。当节流时长为 0 时不做任何处理(每个事件都触发刷新);否则用带 1 个缓冲的通道暂存"最近一次事件",缓冲满时后续事件被直接丢弃(日志输出 "Dropping event kind ... due to throttling")。这与文档"若多个事件在该时间内发生,只处理最近一个"的描述一致——由于提供程序对不同类型事件一视同仁(每次刷新都是全量重建配置),丢弃中间事件不会造成状态不一致。
  • 服务器层providers.providersThrottleDuration(默认 2s)作用于所有提供程序的公共调度,不能按提供程序配置,但各提供程序独立计时。
  • 触发刷新后,Provide 主循环还会主动 time.Sleep(throttleDuration),从消费侧强制保证两次配置重建间隔不小于节流时长。

这一机制对频繁变更的集群(例如大量 Pod 滚动更新导致 EndpointSlice 高频刷新)尤为重要:把 throttleDuration 调到数百毫秒可显著减少无意义的配置重建。

命名空间监听与资源发现范围

namespaces 参数决定了客户端为哪些命名空间建立 informer。从 clientWrapper.WatchAll 可以看到:

  • namespaces 为空时按 metav1.NamespaceAll 处理,监听全部命名空间;
  • 对每个命名空间分别建立三套 informer:Traefik CRD(10 类资源)、Kubernetes 核心资源(Services、EndpointSlices、ConfigMaps)、Secrets;
  • Secret informer 额外附带 owner!=helm 的过滤条件,避免被 Helm 管理的 Secret 干扰;
  • informer 的重同步周期固定为 10 分钟(resyncPeriod);
  • 集群级 Nodes informer 仅在 disableClusterScopeResources 为 false 时创建——这正是该参数"降低集群资源读取权限要求"的实现依据。

五、Traefik 自定义资源清单(Routing Configuration)

文档指出:Traefik 的 CRD 是"按需求自由组装的构建块"(building blocks)。当前仓库支持的自定义资源及用途如下(路径已转换为仓库根路径):

资源 用途
IngressRoute HTTP 路由
Middleware 在请求发送到后端服务前调整 HTTP 请求
TraefikService HTTP 负载均衡/流量镜像的抽象层
TLSOptions 配置 TLS 连接的参数
TLSStore 配置默认 TLS 存储
ServersTransport 配置 Traefik 与后端之间的(HTTP)传输
IngressRouteTCP TCP 路由
MiddlewareTCP 在请求发送到后端前调整 TCP 请求
ServersTransportTCP 配置 Traefik 与后端之间的(TCP)传输
IngressRouteUDP UDP 路由

loadConfigurationFromCRD 的结构可以看到这些资源如何映射到 Traefik 动态配置:一次刷新会重建 HTTP(IngressRoute/TraefikService)、TCP(IngressRouteTCP)、UDP(IngressRouteUDP)路由配置,以及 TLS 段下的 Options(TLSOptions)与 Stores(TLSStore + Secret 证书),随后再逐条翻译 MiddlewareMiddlewareTCPServersTransportServersTransportTCP

中间件的翻译范围很广,例如 loadConfigurationFromCRD 中的 Middleware 处理 覆盖了 basicAuth/digestAuth/forwardAuth、错误页(errors)、插件(plugin)、限流(rateLimit,含 Redis 配置)、重试(retry)、熔断(circuitBreaker)、链式(chain)以及 headers、IP 白/黑名单、压缩、缓冲、重试等十余种类型;CreateClientFromConfig 中客户端的 UserAgent 也带有 kubernetes/crd 标识,便于在 API Server 侧识别流量来源。

六、引用规则与特有部分(Particularities)

文档 Particularities 一节列出了两个约定,源码实现均有对应:

  1. 使用 namenamespace 引用其他 Kubernetes 资源:Traefik 内部以 namespace-name 形式为资源生成 ID(见 makeID),再经 provider.Normalize 归一化;
  2. 敏感数据(TLS 证书与凭据)统一通过 Secret 承载:例如 HTTPS 路由引用的 TLS Secret 必须包含 tls.crttls.key 两个数据项,getCertificateBlocks 会对缺失或为空的条目返回明确错误;CA 类 Secret 则按 tls.ca 优先、ca.crt 兜底的顺序读取(getCABlocks)。此外,中间件插件配置中支持 urn:k8s:secret:... 形式的秘密引用,运行期由 loadSecretKeys 递归解析为实际值,避免敏感信息以明文写入 CR。

allowCrossNamespacecrossProviderNamespaces 相关的引用解析逻辑集中在 resolveReference,可以确认三条规则:

  • 资源名包含 @ 分隔符(跨提供程序引用,如 myservice@file)时:若 allowCrossNamespace 关闭且引用指向 @kubernetescrd,直接报错;同时父命名空间必须在 crossProviderNamespaces 允许列表内(列表为 nil 表示不限制、空列表表示全部禁止,对应 isCrossProviderNamespaceAllowed);
  • 普通同提供程序引用:命名空间缺省时回落到父资源所在命名空间;若解析出的命名空间与父资源不同且 allowCrossNamespace 为 false,则拒绝;
  • 最终引用统一规范化为 namespace-name 形式。

七、多实例共存与完整示例

文档最后一节 Full Example 指向 Kubernetes 使用指南,其中给出了通过 IngressRoute + Middleware 暴露服务的完整 YAML 示例,建议结合本文参数表阅读。仓库的集成测试夹具也提供了可直接参考的 CRD 场景配置,例如 k8s_crd.toml(含 namespacesingressClass 等参数)、k8s_crd_label_selector.tomllabelSelector 过滤)与 k8s_ingressclass.tomlk8s_ingressclass_disabled.tomlingressClass 启用/禁用对比),对应的 CRD 资源 YAML 位于 integration/fixtures/k8s/ 目录(01-traefik-crd.yml 声明 CRD,03-ingressroute.yml 等声明路由资源)。

八、小结

kubernetesCRD 提供程序是 Traefik 在 Kubernetes 中管理路由的核心入口,其要点可以归纳为:

  1. 启用极简providers.kubernetesCRD: {}(或 --providers.kubernetescrd=true)即可;Helm 安装时默认开启。
  2. 手动部署需补齐两类清单:CRD 定义与 RBAC(kubernetes-crd-definition-v1.ymlkubernetes-crd-rbac.yml)。
  3. 连接集群有明确优先级:集群内环境变量 → KUBECONFIG → 显式 endpoint + token/certAuthFilePath(集群外时 endpoint 必填)。
  4. 两级节流throttleDuration + providersThrottleDuration)保护高频变更集群下的配置稳定性。
  5. 安全边界可调namespaceslabelSelectoringressClassallowCrossNamespacecrossProviderNamespacesdisableClusterScopeResources 共同决定 Traefik 看到多少资源、允许多大的引用范围,可按最小权限原则收敛 RBAC 与监听范围。
登录后查看全文
热门项目推荐
相关项目推荐

项目优选

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