1. 为什么要在 k8s 里给 Traefik 接一层统一 API Key在 k8s 集群里用 Traefik 做 Ingress Controller 的同学大概率都遇到过这样一个场景集群里跑着好几个内部 AI 工具服务比如代码补全网关、文档问答服务、Agent 调度器每个服务各自维护一套上游大模型 API Key。时间一长Key 散落在各个 Deployment 的 env、ConfigMap、甚至硬编码在镜像里轮换一次要改十几个地方谁调用了哪个模型也说不清楚。Traefik 本身是云原生反向代理里对动态配置支持比较舒服的一个它通过 CRDIngressRoute、Middleware就能把路由和鉴权逻辑声明式地管起来。我们完全可以把「统一 API Key 接入」这件事下沉到 Traefik 这一层外部请求先经过 Traefik 的 Middleware 做鉴权再转发到后端服务后端服务只认 Traefik 转发过来的内部标识不再直接持有上游 Key。这篇要交付的就是一套可复制的配置骨架Traefik Middleware 怎么写、IngressRoute 怎么指向 TaoToken 的 API 地址、Key 放在哪个 Secret 里、以及用 curl 怎么验证「路由转发 鉴权」两件事都生效。适合已经在集群里跑着 Traefik、想给 AI 工具链做统一入口的运维和平台同学。下面所有 YAML 都可以直接改改域名和命名空间就用。2. TaoToken 前置准备Key、地址与命名空间约定在写 Traefik 配置之前先把「上游通道」这件事定下来。TaoToken 在这里扮演的角色是统一的模型 API 入口你只需要一个 Key、一个 Base URL就能在集群里被 Traefik 转发调用不用每个服务单独去对接不同厂商。官网入口在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 注册后在控制台生成 API Key。API 的基础地址是 https://taotoken.net/api 注意这个地址不带任何查询参数配置里直接写它就行。控制台里管理 Key 的页面在 https://taotoken.net/console 生成和吊销都在那里操作。我习惯把这类凭证统一放进一个独立的命名空间比如ai-gateway跟业务命名空间解耦。这样 Traefik 的 Middleware 引用 Secret 时权限边界清晰轮换 Key 也只动一个地方。先建命名空间kubectl create namespace ai-gateway然后把 Key 写进 Secret。注意这里用stringData而不是data省得你手动 base64apiVersion: v1 kind: Secret metadata: name: taotoken-credentials namespace: ai-gateway type: Opaque stringData: api-key: sk-你的TaoTokenKey api-base: https://taotoken.net/api应用它kubectl apply -f taotoken-secret.yaml kubectl get secret taotoken-credentials -n ai-gateway看到 Secret 存在就说明前置就绪。这里有个细节Traefik 的 Middleware 本身不能直接读 Secret 内容做请求头注入所以实际注入 Key 的动作要么放在后端服务的 sidecar要么用 Traefik 的headersMiddleware 做静态头。下面第 3 节我会给出两种写法你按自己的架构选。3. 可复制的 Traefik Middleware 与 IngressRoute 骨架3.1 鉴权 Middleware校验外部请求携带的 Token第一层 Middleware 负责「挡住没带 Key 的请求」。Traefik 的forwardAuth可以把鉴权委托给一个小的认证服务但如果你只是想校验一个固定 Header用headerserrors组合更轻。下面这个 Middleware 要求请求必须带X-Api-Token值从 Secret 里读不方便所以更推荐用 forwardAuth 指向一个极简校验服务。先给一个纯声明式的headers写法适合内部可信网络apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: ai-auth-check namespace: ai-gateway spec: headers: customRequestHeaders: X-Gateway-Source: traefik-ai customResponseHeaders: X-Gateway-Verified: true这个 Middleware 的作用是给所有经过它的请求打上来源标记后端服务可以据此判断请求确实来自 Traefik 网关而不是集群内直连。真正的 Key 校验建议用 forwardAuth指向一个校验服务校验服务再去比对 Secret 里的值。3.2 注入上游 Key 的 Middleware第二层 Middleware 负责把 TaoToken 的 Key 注入到转发请求里。因为 Traefik 不能动态读 Secret 注入 Header常见做法是后端服务自己从挂载的 Secret 里读 KeyTraefik 只负责路由。但如果你确实想在网关层统一注入可以用一个 initContainer 把 Key 渲染进 Traefik 的静态配置或者用plugin。这里给一个更实用的折中后端服务挂载 SecretTraefik 只做路由和限流。apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: ai-rate-limit namespace: ai-gateway spec: rateLimit: average: 50 burst: 100 period: 1s限流放在网关层能防止某个服务把上游额度打爆这是统一接入最实际的价值之一。3.3 IngressRoute把域名路由到后端 AI 服务现在把 Middleware 串起来写 IngressRoute。假设你的后端服务叫ai-tool-svc监听 8080域名用ai.internal.example.comapiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: ai-tool-route namespace: ai-gateway spec: entryPoints: - web routes: - match: Host(ai.internal.example.com) PathPrefix(/v1) kind: Rule middlewares: - name: ai-auth-check - name: ai-rate-limit services: - name: ai-tool-svc port: 8080这里PathPrefix(/v1)是关键因为 TaoToken 的 API 路径通常以/v1开头后端服务转发时保持路径一致就不用做 rewrite。如果你的后端服务期望的路径跟上游不同加一个replacePathRegexMiddleware 即可。3.4 后端服务如何拿到 TaoToken 地址后端 Deployment 里挂载 Secret环境变量指向 TaoToken 的 Base URLapiVersion: apps/v1 kind: Deployment metadata: name: ai-tool namespace: ai-gateway spec: replicas: 2 selector: matchLabels: app: ai-tool template: metadata: labels: app: ai-tool spec: containers: - name: ai-tool image: your-ai-tool:latest env: - name: TAOTOKEN_API_BASE valueFrom: secretKeyRef: name: taotoken-credentials key: api-base - name: TAOTOKEN_API_KEY valueFrom: secretKeyRef: name: taotoken-credentials key: api-key ports: - containerPort: 8080这样后端服务启动时读到的就是https://taotoken.net/api和你的 Key它对外发起模型调用时直接拼/v1/chat/completions这类路径即可。Traefik 负责的是「外部请求怎么进来」TaoToken 负责的是「模型请求怎么出去」两层职责分开配置就不会互相打架。4. 验证curl 打通路由转发与鉴权配置写完不验证等于没写。分三步走。第一步确认 Traefik 已经识别到 IngressRoutekubectl get ingressroute -n ai-gateway kubectl describe ingressroute ai-tool-route -n ai-gatewaydescribe 里能看到Status和绑定的 entryPoint如果为空多半是 CRD 版本不对或 Traefik 没开 kubernetesCRD provider。第二步从集群外 curl 域名验证路由转发curl -v http://ai.internal.example.com/v1/models \ -H X-Api-Token: test-token如果返回 200 或后端服务的正常响应说明 Traefik 把请求正确转发到了ai-tool-svc。如果返回 404检查PathPrefix是否匹配返回 502检查 Service 的 selector 和端口。第三步验证限流 Middleware 生效。快速打 200 个请求for i in $(seq 1 200); do curl -s -o /dev/null -w %{http_code}\n \ http://ai.internal.example.com/v1/models \ -H X-Api-Token: test-token done | sort | uniq -c你应该能看到一部分 200、一部分 429。429 就是ai-rate-limit在起作用。这一步能同时验证路由和 Middleware 链都挂上了。第四步验证后端到 TaoToken 的出口。进 Pod 里直接 curlkubectl exec -it deploy/ai-tool -n ai-gateway -- sh curl -s https://taotoken.net/api/v1/models \ -H Authorization: Bearer $TAOTOKEN_API_KEY能列出模型列表说明 Key 和 Base URL 都正确。这一步跟 Traefik 无关但它是整条链路能跑通的前提建议单独确认。5. 本篇常见错排查IngressRoute 不生效kubectl get ingressroute为空。先确认 Traefik 的 CRD 装的是traefik.io/v1alpha1还是老的traefik.containo.us/v1alpha1两者不兼容。再看 Traefik 启动参数里有没有--providers.kubernetescrd没有的话它根本不监听 CRD。curl 返回 404但 Service 本身是通的。九成是match规则写错。Host和PathPrefix之间要用反引号不能少。另外注意 entryPoint 名字默认是web和websecure如果你自定义过就要对应改。返回 502 Bad Gateway。检查 Service 的selector是否匹配 Pod 的 label以及 IngressRoute 里写的 port 是不是 Service 暴露的端口不是容器端口。这两个搞混很常见。限流 Middleware 没反应。rateLimit的average是每秒平均请求数burst是突发上限。如果你只打了几个请求就期待 429那不会触发。用上面那个 200 次的循环测。后端调 TaoToken 报 401。先确认 Secret 里的 Key 没有多余空格或换行stringData写入时容易带尾随空格。再确认 Base URL 是https://taotoken.net/api不要自己加/v1路径拼接交给代码。Traefik Dashboard 里看不到新路由。Dashboard 有缓存刷新一下如果还是没有看 Traefik 日志kubectl logs -n kube-system deploy/traefik里面会打印 CRD 解析错误。6. 后续怎么把这套骨架用顺这套配置跑通之后最值得做的一件事是把 Key 轮换流程固化下来改 Secret、滚动重启后端 DeploymentTraefik 那层完全不用动。因为 Traefik 只管路由和限流Key 的生命周期跟网关解耦这是分层带来的最大好处。如果你后面要接更多 AI 工具比如代码补全、Agent 调度只需要复制一份 IngressRoute改match和servicesMiddleware 直接复用。想验证模型通道本身是否正常可以去 https://taotoken.net/chat 直接对话测试长期跑编码类 Agent 的话Coding Plan 页面 https://taotoken.net/coding-plan 里有更细的额度说明。Key 管理统一在 https://taotoken.net/api-keys 接入文档在 https://taotoken.net/doc 遇到路由或鉴权问题先翻文档里的接入章节比在集群里盲试快得多。
