1. Traefik 2.X 在 k8s 里当 ingress-controller 到底解决了什么问题Traefik 2.X 是一个云原生反向代理和负载均衡器在 Kubernetes 集群里通常以 ingress-controller 的身份运行。它能做什么简单说就是把集群外部的流量按域名、路径、Header 等规则转发到集群内部的 Service 上同时支持自动发现 Ingress、IngressRoute、Middleware 等 CRD 资源。适合谁适合已经在用 k8s、想找一个配置轻量、Dashboard 可视化、支持动态路由的入口网关的开发和运维同学。我这次聚焦的场景很具体Traefik 2.X 作为 k8s ingress-controller 时Dashboard 怎么安全暴露、EntryPoint 怎么和路由规则配合、以及如何把入口统一到 TaoToken 的调用链路上做端到端验证。很多人第一次装 Traefik 2.X 会卡在两个地方一是 Dashboard 默认只监听 8080 且没有认证直接暴露到 NodePort 上等于把管理面板送人二是 EntryPoint 的 web/websecure 和 IngressRoute 的 entryPoints 字段对不上导致 curl 一直 404。Traefik 2.X 和 1.X 最大的区别是引入了 CRDCustom Resource Definition路由不再只靠 Ingress 注解而是用 IngressRoute、Middleware、TLSOption 这些自定义资源来描述。这意味着你可以把「路由」和「中间件」解耦比如给 Dashboard 单独加一个 BasicAuth 中间件而不影响业务路由。这个设计在实操里非常香因为 Dashboard 暴露和业务入口往往是两套安全策略。下面我会从零开始给出可复制的 RBAC、Deployment、Service、IngressRoute、Middleware YAML 片段然后演示用 curl 验证路由命中、401 响应最后把整条链路和 TaoToken 的统一入口配置对齐。你可以在本地 kind、minikube 或者任意测试集群里跟着做。2. 前置准备TaoToken 统一入口与集群环境对齐在动手写 YAML 之前先把「统一入口」这件事想清楚。Traefik 的 EntryPoint 是它监听流量的端口比如 web 对应 80websecure 对应 443traefik 对应 8080Dashboard。而 TaoToken 在这里扮演的是统一 API 入口的角色——你的模型调用、coding-plan、console 管理都走同一个 Base URL这样在 Traefik 里做路由和鉴权时只需要维护一套上游地址。TaoToken 的官网入口是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 入口是 https://taotoken.net/api 。注意 API 地址不带 UTM 参数配置里要写干净。如果你后面要在 Traefik 后面接模型对话或者 coding-plan建议先把这几个 deep link 记下来模型对话、coding-plan、console、api-keys、doc、ClaudeCodeAnthropic。这些页面在配置鉴权和验证请求时会反复用到。集群侧的准备一个可用的 k8s 集群1.20kubectl 能正常连上最好有 2 个以上节点或者单节点但资源够。Traefik 2.X 我用的是 2.5.5 之后的版本CRD 已经稳定。先确认你的集群里没有别的 ingress-controller 抢 80/443否则 EntryPoint 会绑定失败。kubectl get nodes kubectl get svc -A | grep -E LoadBalancer|NodePort如果看到已经有 nginx-ingress 在跑要么先停掉要么给 Traefik 换端口。我实测下来本地测试集群用 NodePort 暴露 30974 给 Dashboard 是最省事的生产环境则应该走 websecure BasicAuth。还有一个容易忽略的点Traefik 2.X 的 CRD 需要先安装否则你 apply IngressRoute 会报no matches for kind IngressRoute。CRD 文件在官方仓库的docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml或者直接用 helm chart 装。我下面给的是手动 apply 的方式方便你理解每一步。3. 可复制配置RBAC、Deployment、Service 与 IngressRoute YAML这一章是核心所有片段都可以直接复制。先装 CRD再装 RBAC然后是 Deployment 和 Service最后是 Dashboard 的 IngressRoute 和 BasicAuth Middleware。先创建 CRDkubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v2.9/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.ymlRBAC 部分注意新版文件比较长别复制少了apiVersion: v1 kind: ServiceAccount metadata: name: traefik-ingress-controller namespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: traefik-ingress-controller rules: - apiGroups: [] resources: [services, endpoints, secrets] verbs: [get, list, watch] - apiGroups: [extensions, networking.k8s.io] resources: [ingresses, ingressclasses] verbs: [get, list, watch] - apiGroups: [traefik.containo.us] resources: [ingressroutes, middlewares, tlsoptions] verbs: [get, list, watch] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: traefik-ingress-controller roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: traefik-ingress-controller subjects: - kind: ServiceAccount name: traefik-ingress-controller namespace: kube-systemDeployment 里关键是 EntryPoint 的启动参数web 监听 80websecure 监听 443traefik 监听 8080 给 DashboardapiVersion: apps/v1 kind: Deployment metadata: name: traefik namespace: kube-system spec: replicas: 1 selector: matchLabels: app: traefik template: metadata: labels: app: traefik spec: serviceAccountName: traefik-ingress-controller containers: - name: traefik image: traefik:v2.9 args: - --api.insecuretrue - --api.dashboardtrue - --providers.kubernetescrdtrue - --entrypoints.web.address:80 - --entrypoints.websecure.address:443 - --entrypoints.traefik.address:8080 ports: - name: web containerPort: 80 - name: websecure containerPort: 443 - name: traefik containerPort: 8080Service 用 NodePort 暴露Dashboard 走 30974apiVersion: v1 kind: Service metadata: name: traefik namespace: kube-system spec: type: NodePort selector: app: traefik ports: - name: web port: 80 targetPort: 80 nodePort: 30080 - name: websecure port: 443 targetPort: 443 nodePort: 30443 - name: traefik port: 8080 targetPort: 8080 nodePort: 30974Dashboard 的 IngressRoute 和 BasicAuth Middleware这里就是「把 Dashboard 配置改到统一入口」的关键。Middleware 用 htpasswd 生成的密文你可以用htpasswd -nb admin yourpassword生成apiVersion: traefik.containo.us/v1alpha1 kind: Middleware metadata: name: dashboard-auth namespace: kube-system spec: basicAuth: secret: dashboard-auth-secret --- apiVersion: v1 kind: Secret metadata: name: dashboard-auth-secret namespace: kube-system type: Opaque stringData: users: | admin:$apr1$xyz$abcdefghijklmnopqrstuv --- apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: traefik-dashboard namespace: kube-system spec: entryPoints: - traefik routes: - match: Host(traefik.local) (PathPrefix(/api) || PathPrefix(/dashboard)) kind: Rule services: - name: apiinternal kind: TraefikService middlewares: - name: dashboard-auth注意entryPoints写的是traefik对应 Deployment 里的--entrypoints.traefik.address:8080。如果你写成webcurl 会 404这是最常见的坑。另外apiinternal是 Traefik 内置服务不需要你手动创建 Service。4. 验证请求curl 命中路由与 401 响应实测配置 apply 完之后先确认 Pod 和 CRD 都就绪kubectl get pods -n kube-system | grep traefik kubectl get ingressroute -n kube-system kubectl get middleware -n kube-system等 Pod 变成 Running然后拿节点 IPkubectl get nodes -o wide假设节点 IP 是 192.168.1.30Dashboard 的 NodePort 是 30974。先测不带认证的请求应该返回 401curl -i http://192.168.1.30:30974/dashboard/预期输出里会有HTTP/1.1 401 Unauthorized Www-Authenticate: Basic realmtraefik这说明 BasicAuth Middleware 生效了路由也命中了。如果返回 404说明 IngressRoute 的 match 规则或者 entryPoints 写错了。如果返回 502说明apiinternal服务没找到检查 CRD 是否装全。再测带认证的请求curl -i -u admin:yourpassword http://192.168.1.30:30974/dashboard/这次应该返回 200并且能看到 Dashboard 的 HTML。如果你在浏览器里访问会弹出登录框输入账号密码后进入 Traefik Dashboard能看到 Routers、Services、Middlewares 的实时状态。再验证一下 web EntryPoint 上的业务路由。假设你有一个 tomcat 服务创建一个 IngressRouteapiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: tomcat-route namespace: default spec: entryPoints: - web routes: - match: Host(my.tomcat.com) kind: Rule services: - name: tomcat-svc port: 8080然后在物理机 hosts 里加一条192.168.1.30 my.tomcat.com用 curl 验证curl -i -H Host: my.tomcat.com http://192.168.1.30:30080/如果返回 tomcat 的欢迎页说明 web EntryPoint 的路由也通了。这一步和 Dashboard 的区别在于 entryPoints 从traefik换成了web端口从 30974 换成了 30080。如果你要把这条链路和 TaoToken 的模型调用对齐可以在业务服务里把上游 Base URL 配成 https://taotoken.net/api 然后用同样的 curl 方式验证模型对话接口是否可达。TaoToken 的 API Key 在 console 的 api-keys 页面生成配置时注意 Base URL、Key、Model ID 三件套要写全。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth实操里最容易撞的几个报错我按真实日志对照给你排。第一个是 401 Unauthorized。如果你 curl Dashboard 不带-u返回 401这是正常的说明 Middleware 生效。但如果你带了正确的账号密码还是 401检查 Secret 里的users字段格式必须是用户名:密文密文用htpasswd -nb生成不能用明文。另外 Secret 的 namespace 要和 Middleware 一致否则 Traefik 读不到。第二个是local proxy failed或者dial tcp: connection refused。这通常出现在你把上游配成 localhost 或者 127.0.0.1 的时候。Traefik 在 Pod 里跑localhost 指向的是 Pod 自己不是你的物理机。正确做法是写 Service 名或者集群内 DNS比如tomcat-svc.default.svc.cluster.local。如果你在配置 TaoToken 的 Base URL也要确认写的是 https://taotoken.net/api 而不是本地地址。第三个是reading choices相关的报错一般出现在模型调用返回体解析失败时。如果你在 Traefik 后面接了一个模型代理服务返回的 JSON 结构不对客户端解析choices字段就会报错。排查方法是先用 curl 直接打上游确认返回体是标准格式再经过 Traefik 转发。Traefik 本身不会改返回体所以问题多半在服务端。第四个是 OAuth 相关报错比如OAuth token exchange failed。如果你在 Middleware 里配了 forwardAuth 或者 OIDC检查 issuer URL 和 client secret 是否正确。Traefik 2.X 的 forwardAuth 会把请求头转发给认证服务认证服务返回 2xx 才放行。如果认证服务本身挂了就会一直 401。建议先用 curl 单独测认证服务的健康检查接口。还有一个隐蔽的坑IngressRoute 的entryPoints名字必须和 Deployment 里的--entrypoints.xxx.address完全一致。我见过有人写websecure但 Deployment 里只配了web结果路由一直不生效。用kubectl logs -n kube-system deploy/traefik看日志会提示entrypoint not found。最后如果你同时用了 CC Switch、Cline MCP 或者 Codex 的 auth.json记得三件套要写全Base URL 用 https://taotoken.net/api Key 用 console 生成的Model ID 按文档填。缺任何一个都会导致鉴权失败或者模型找不到。6. 把入口统一到 TaoToken长期编码与 Agent 场景的接入建议Dashboard 和 EntryPoint 配通之后下一步就是把业务入口统一到 TaoToken 的调用链路上。如果你只是临时验证模型对话直接用模型对话页面测就行。但如果你要做长期编码或者 Agent 场景建议走 Coding Plan这样配额和路由策略更稳定。具体做法在 Traefik 的 IngressRoute 里把上游 Service 指向你的模型代理服务代理服务里配置 TaoToken 的 Base URL 和 Key。这样外部流量先到 TraefikTraefik 做路由和鉴权再转发到代理服务代理服务调用 TaoToken API。整条链路的入口是统一的鉴权也集中在 Traefik 的 Middleware 里。如果你用的是 Claude Code 做润色或者代码生成接入方式类似在配置里填 Base URL https://taotoken.net/api Key 从 api-keys 页面拿Model ID 按文档选。Traefik 这边只需要保证 websecure EntryPoint 的证书和路由规则正确剩下的交给上游。排障的时候优先看 Traefik 的 DashboardRouters 页面会显示每条路由的命中状态和错误信息。如果某个 Router 显示红色点进去看详细报错通常是 match 规则写错或者 Service 不存在。接入文档里有完整的参数说明遇到不确定的字段先去 doc 页面查。最后提醒一句Dashboard 的--api.insecuretrue只适合本地测试生产环境一定要关掉改用 websecure BasicAuth 或者 forwardAuth。我踩过的坑就是测试环境图省事开了 insecure结果 Dashboard 被扫到虽然没造成损失但也是个教训。把 Dashboard 和 EntryPoint 都收敛到统一入口之后整个 k8s 集群的流量治理会清晰很多。