
Traefik 与 Knative Serving 集成Knative Provider 路由配置与按标签百分比灰度流量实战【免费下载链接】traefikThe Cloud Native Application Proxy项目地址: https://gitcode.com/GitHub_Trending/tr/traefikTraefik 的 Knative Provider 让 Traefik 可以直接订阅 Knative Serving 的Ingress自定义资源CRD从而把 Knative 中由Service/Revision定义的流量入口自动转换为 Traefik 的动态路由配置实现 Serverless 场景下的流量接入、按 Revision 百分比灰度与按标签直连。本文以仓库 Knative 路由配置文档 为骨架结合 Knative Provider 的源码实现与集成测试讲解如何部署 Knative Service、如何基于traffic段做 tag 百分比路由以及 Traefik 侧实际生成路由器与负载均衡器的底层机制。Knative Provider 的工作方式当启用 Knative Provider 后Traefik 不再依赖自己的IngressRoute、Ingress 等对象而是直接使用 Knative 生态的 Custom Resource DefinitionsCRDs来获取路由配置。核心链路是Knative Serving 的networking-controller在为每个Service/Route生成内部Ingress资源后Traefik 通过 informer 监听这些对象并推导出对应的动态配置HTTP Router / Service / Middleware。从源码 pkg/provider/kubernetes/knative/kubernetes.go 可以看到loadConfiguration的真实处理过程遍历client.ListIngresses()返回的所有 KnativeIngress只处理带注解networking.knative.dev/ingress.class: traefik.ingress.networking.knative.dev的对象kubernetes.go 中直接比对常量traefikIngressClassName其余跳过为每个 Ingress 加载 TLS 证书读取同命名空间下的 Secret把每个 Ingress 的 Hosts、Headers、Paths、Splits 转换成一组 Traefik Router 与加权轮询 Service。该 Provider 为实验特性根据官方安装配置文档 的说明当前支持 Knative Serving 规范 v1.19.0 与 v1.20.0 两个版本。仓库集成测试中直接引用了 v1.20.0 的 CRD 与 Serving 组件清单integration/fixtures/knative/00-knative-crd-v1.20.0.yml、integration/fixtures/knative/03-knative-serving-v1.20.0.yaml。部署前准备启用 Provider 并配置集群该 Provider 属于实验特性需要在配置的experimental与providers两处同时开启。官方推荐在 File、TOML、CLI 三种配置方式中按需选用experimental: knative: true providers: knative: {}[experimental.knative] [providers.knative]--experimental.knativetrue --providers.knativetrue除此之外要让 Traefik 能接管 Knative 流量还需要按安装配置文档依次完成以下集群准备工作安装或升级 Knative CRD安装 Knative Serving 核心组件修改config-network配置把 Knative 的 ingress class 指向 Traefikkubectl patch configmap/config-network \ -n knative-serving \ --type merge \ -p {data:{ingress.class:traefik.ingress.networking.knative.dev}}可选在config-domain中为 Knative 添加自定义公共域名例如把example.com配置为默认域名后缀这正是后文curl http://helloworld-go.default.example.com中example.com的由来kubectl patch configmap config-domain \ -n knative-serving \ --typemerge \ -p{data:{example.com:}}安装 Traefik 侧所需的 RBACdocs/content/reference/dynamic-configuration/kubernetes-knative-rbac.yml。注意第 5 步的 RBAC 文件揭示了 Provider 需要的全部权限也就是它真实访问的资源集合services与secrets核心组读取后端 Service用于构建上游服务器地址和 TLS 证书 Secretnetworking.internal.knative.dev组下的ingressesget/list/watch用于监听 Knative 内部 Ingressingresses/status的update把 Traefik 控制器就绪状态写回 Ingress 状态供 Knative Serving 判断网络层是否配置完成。从仓库的集成部署清单 integration/fixtures/knative/02-traefik.yml 中可以看到一个完整可用的 Traefik 启动参数示例它同时配置了公共与私有两种入口组、公共/私有 Service 以及节流时长是把 Provider 实际跑起来的关键参考。Provider 常用配置项在动手部署前还需理解 pkg/provider/kubernetes/knative/kubernetes.go 中Provider结构体承载的配置字段含义字段说明默认值providers.knative.endpointKubernetes API Server 地址。部署在集群内时 Traefik 会自动读取KUBERNETES_SERVICE_HOST/KUBERNETES_SERVICE_PORT或KUBECONFIG构建客户端也可显式覆盖自动探测providers.knative.token集群外连接时使用的 Bearer Token无providers.knative.certAuthFilePath集群外连接时 CA 证书文件路径无providers.knative.namespaces要监听的命名空间数组留空则监听全部命名空间全部命名空间providers.knative.labelSelector用 Label Selector 过滤 Knative Ingress 对象无providers.knative.throttleDuration两次 Kubernetes 事件之间触发配置重建的最短间隔防止集群频繁变更导致 Traefik 配置持续抖动为空则每次都触发0providers.knative.publicEntrypoints用于公开暴露 Ingress 的入口点名称为空表示暴露在全部入口点全部入口点providers.knative.publicService公开暴露网络控制器的 Kubernetes Service含name/namespace无providers.knative.privateEntrypoints用于内部cluster-local暴露 Ingress 的入口点名称为空则跳过本地 Ingress无providers.knative.privateService内部暴露网络控制器的 Kubernetes Service含name/namespace无其中publicService/privateService除了用来指引负载均衡地址外还会在事件处理完毕后回写到 Knative Ingress 的LoadBalancerReady状态中见 kubernetes.go 的updateKnativeIngressStatus。部署一个 Knative ServiceService是 Knative 规范中的核心资源定义了进入 Knative 应用的流量入口。它关联到一个IngressKnative networking controller 生成由该 Ingress 指定负责管理与转发流量的网络控制器确保流量被正确导向对应的 Knative 后端服务。下面这份Service清单配置了运行中的 Traefik 控制器来处理进入流量--- apiVersion: serving.knative.dev/v1 kind: Service metadata: name: helloworld-go namespace: default spec: template: spec: containers: - image: gcr.io/knative-samples/helloworld-go env: - name: TARGET value: Go Sample v1一切部署完成后向 HTTP 端点发送GET请求应得到如下响应$ curl http://helloworld-go.default.example.com Hello Go Sample v1!注意这里的example.com是部署 Traefik 控制器时配置的公共域名也就是上文config-domain中 patch 进去的后缀。完整的部署说明见安装配置章节。Tag 化的百分比灰度路由Knative 最典型的灰度能力来自Service清单中的traffic段你可以为多个不同 Revision 指定 tag 与流量百分比实现按比例放量与按 tag 直连验证。示例如下apiVersion: serving.knative.dev/v1 kind: Service metadata: name: helloworld-go namespace: default spec: template: spec: containers: - image: gcr.io/knative-samples/helloworld-go env: - name: TARGET value: Go Sample v2 traffic: - tag: v1 revisionName: helloworld-go-00001 percent: 50 - tag: v2 revisionName: helloworld-go-00002 percent: 50在这个例子中traffic段指定了两个 Revisionhelloworld-go-00001与helloworld-go-00002分别打了v1与v2标签各接收 50% 的流量tag字段允许你用标签直接访问特定 Revision实现免改 DNS 的定向验证。对应的访问地址为http://v1-helloworld-go.default.example.comhttp://v2-helloworld-go.default.example.com而默认地址按百分比分发流量http://helloworld-go.default.example.com底层如何把百分比变成真实路由从 Traefik 源码看这份清单到达 Provider 后会被 Knative networking controller 拆解为带Splits的内部 Ingress 规则。Traefik 端在 buildRouters 中为每条 rule path 生成一个路由并把 rule 的HTTP.Paths中的Splits交给 buildWeightedRoundRobin 处理每个split对应一个 Traefik 子 Service每个子 Service 再通过buildService/buildServerskubernetes.go解析为对后端 Kubernetes Service ClusterIP 的真实 HTTP 上游split.Percent被直接映射为加权轮询中的Weight当列表里只有一个 split 时按规范其权重被强制置为 100对应默认全量路由所有 split 汇总成一个命名为routerKey-wrr的WeightedService 挂到 Router 上从而精确复现 Knative 定义的百分比流量分配。此外 buildRule 展示了路由匹配规则的拼装逻辑多个 Host 之间用||连接多个 Header 用连接路径则编译为PathPrefix(...)最终各条件之间以组合。带 tag 的 URL 之所以能单独命中正是因为对应 Revision 的 Ingress 规则里携带了独立的 tag host如v1-helloworld-go.default.example.com被拼进了规则的Host(...)条件中。HTTP/HTTPS 与证书官方文档在 HTTP/HTTPS 配置 一节指向 Knative Serving 的 external-domain-tls 文档强调外部域名加密通常由 Knative 侧统一配置。而在 Traefik 这一侧源码对 TLS 的处理位于 loadCertificates遍历 Ingressspec.TLS从与 Ingress同命名空间的 Secret 中读取证书与私钥跨命名空间引用当前会被跳过以namespace-secretName为 key 去重缓存Secret 数据中同时缺少tls.crt/tls.key时会报错并跳过该 Ingress只要 Ingress 声明了 TLSbuildRouters 还会额外生成一个带TLS: {}配置的-tlsRouter 副本让 Traefik 对该路由启用 TLS 终止。需要说明的是源码注释中也保留了若干 TODO如支持 rewrite host、HTTPOption 的 HTTP→HTTPS 跳转判定、provider 级默认 TLS Secret 等这些属于当前实现尚未开放的能力边界配置时应以实际验证结果为准。监听、节流与状态回写机制Knative Provider 并不仅是“读一次配置”而是一个持续运行的控制器。从 Provide 与 client.go 可以还原完整事件循环WatchAll会为每个监听命名空间同时启动 Knative Networking informer监听networking.internal.knative.dev/v1alpha1的 Ingress与 Kubernetes informer监听 Services、Secrets并等待缓存同步完成事件统一写入 channel事件到达后调用loadConfiguration全量重建动态配置并通过配置通道推送给 TraefikthrottleEventskubernetes.go实现节流若throttleDuration大于 0缓冲通道内已有一个待处理事件时新事件会被丢弃因为事件类型不影响重建逻辑该设计避免高频集群事件导致配置频繁抖动重建后延迟throttleDuration再调用updateKnativeIngressStatus回写状态保证动态配置先就绪、状态后更新这也是保证 Knative 一致性测试通过的关键见源码注释。另外需要注意 Ingress 的可见性语义规则中IngressVisibilityClusterLocal的 Ingress 会与privateEntrypoints对应若 Provider 未配置私有入口点这类本地 Ingress 会被直接跳过kubernetes.go。如何验证 Provider 的行为仓库用一套专门的 Knative 一致性测试来验证 Provider 的正确性入口为 integration/knative_conformance_test.go。该测试文件带knativeConformance构建标签避免 Knative conformance 工具包与测试框架的 skip-tests 参数冲突其要点包括用 k3s 容器拉起一个临时集群依次应用 00-knative-crd-v1.20.0.yml、RBAC、02-traefik.yml 与 03-knative-serving-v1.20.0.yaml在 Traefik Deployment 中通过--experimental.knative、--providers.knative.publicEntrypointspweb,pwebsecure、--providers.knative.publicService.*、--providers.knative.privateEntrypointsprivweb,privwebsecure、--providers.knative.privateService.*以及--providers.knative.throttleduration2s完整复刻生产配置形态最终调用 Knative 官方 conformance 工具ingress.RunConformance并设置ingressClasstraefik.ingress.networking.knative.dev跳过headers/probe用例。如果你要在自有环境做同等验证可以对照这份清单确认自身的 RBAC、ingress class 注解、公共/私有入口点与 Service 是否配置齐全再通过 Knative 官方 Serving 样例部署Service观察 Traefik 日志中生成的路由与 curl 各 tag 域名时的分发结果。小结Knative Provider 把 Traefik 从“通用 Ingress 控制器”延伸为 Knative Serving 的 serverless 网络层通过监听 Knative 内部 Ingress CRD、按 ingress class 注解过滤归属、把 Host/Header/Path/Splits 翻译为 Router 与加权轮询 Service并回写负载均衡就绪状态最终支持了 KnativeService的默认域名访问、tag 直连与按 Revision 百分比灰度。结合本仓库的安装配置文档、RBAC 清单、Provider 源码 与一致性测试你可以照此在生产集群中完整落地这套 Serverless 流量接入方案。【免费下载链接】traefikThe Cloud Native Application Proxy项目地址: https://gitcode.com/GitHub_Trending/tr/traefik创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考