ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

k8s整合Traefik:把Ingress路由配置改到TaoToken统一入口

k8s整合Traefik:把Ingress路由配置改到TaoToken统一入口 1. 为什么要把 K8s Ingress 路由统一到 TaoToken 入口在 K8s 集群里用 Traefik 做 Ingress Controller最直观的好处是服务发现自动、路由规则实时生效。但真正落地到多团队共用的测试环境时问题往往不在 Traefik 本身而在于上游服务端点散落各处每个业务组自己申请模型 API Key、自己配 Base URL、自己管配额最后路由是通了密钥和调用量却没人说得清。我这次要解决的场景很具体集群里已经跑着 Traefik业务服务通过 IngressRoute 暴露现在希望把涉及大模型调用的上游端点统一收敛到 TaoToken 的 API 通道https://taotoken.net/api这样密钥只在 TaoToken 控制台集中管理调用配额也能按项目维度看。Traefik 在这里扮演的角色是边缘路由器 中间件编排器它不直接调用模型而是把外部请求按规则转发到集群内的网关服务网关再统一走 TaoToken 通道。先明确几个 Traefik 的核心概念后面配置才不会晕Providers 负责自动发现服务K8s 场景下就是kubernetesCRD和kubernetesIngress两个 providerEntryPoints 是监听端口比如 web(80) 和 websecure(443)Routers 根据 Host、Path、Header 等规则把请求接到 ServiceMiddlewares 在请求到达服务前做改写比如强制 HTTPS、加认证头、限流Services 才是真正转发目标。这套模型和传统 Nginx 最大的区别是Nginx 要你手写 upstream 和 locationTraefik 通过 CRD 声明式定义改完 apply 就生效不用 reload。对于统一入口这个目标我们需要的是一条可复用的 IngressRoute 模板 一个指向 TaoToken 通道的 Service 一组 Middleware。适合谁看已经在 K8s 里跑 Traefik、想把模型调用端点收口的运维或后端或者正准备用 Traefik 替换 Nginx Ingress、需要一份能直接 apply 的 YAML 的人。下面所有清单我都实测过集群版本 v1.22Traefik Helm Chart 对应 2.x 系列。2. TaoToken 前置准备与 Traefik 安装配置在把路由指向 TaoToken 之前得先把两件事做完拿到 TaoToken 的 API Key以及让 Traefik 在集群里正常跑起来。2.1 获取 TaoToken API Key 与 Base URL打开 TaoToken 控制台https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content在 API Keys 页面创建一个新 Key。创建时建议按项目命名比如k8s-traefik-gateway方便后面在 Traefik 的 Service 里引用。创建完成后你会拿到两样东西Base URLhttps://taotoken.net/apiAPI Key形如sk-xxxxxxxx只显示一次记得存好这里有个关键点Traefik 本身不存 KeyKey 应该放在集群内的 Secret 里由网关服务读取。所以下一步是创建 Secret。kubectl create secret generic taotoken-credentials \ --from-literalapi-keysk-你的实际Key \ --namespace default如果你用的是 Coding Plan 或需要长期跑 Agent 任务建议在控制台里单独建一个 Key 并设置配额上限避免测试环境把额度跑满。模型对话入口在https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content可以先在页面上验证 Key 是否可用再去配 Traefik。2.2 用 Helm 安装 Traefik先确认 Helm 版本v3.6 以上都行helm version如果没装 Helm从官方 release 下载对应架构的包解压后把二进制移到/usr/local/bin/。然后添加 Traefik 的 Helm 仓库helm repo add traefik https://traefik.github.io/charts helm repo update创建一份定制 values 文件traefik-values.yaml核心是开启 CRD provider、固定入口端口、指定节点deployment: enabled: true kind: Deployment ingressClass: enabled: true isDefaultClass: false ingressRoute: dashboard: enabled: false providers: kubernetesCRD: enabled: true allowCrossNamespace: true allowExternalNameServices: true kubernetesIngress: enabled: true allowExternalNameServices: true logs: general: level: INFO access: enabled: true ports: web: port: 8000 hostPort: 80 redirectTo: websecure websecure: port: 8443 hostPort: 443 securityContext: capabilities: drop: [] readOnlyRootFilesystem: false runAsGroup: 0 runAsNonRoot: false runAsUser: 0 nodeSelector: kubernetes.io/hostname: 你的边缘节点名注意redirectTo: websecure这一行它让所有 HTTP 请求自动跳 HTTPS比后面单独配 Middleware 更省事。安装命令helm upgrade --install traefik traefik/traefik \ -f traefik-values.yaml \ --namespace kube-system装完检查 Pod 和 IngressClasskubectl get pods -n kube-system -l app.kubernetes.io/nametraefik kubectl get ingressclass看到traefik这个 IngressClass 且 CONTROLLER 是traefik.io/ingress-controller就对了。如果 Pod 起不来多半是 hostPort 80/443 被占用或者 nodeSelector 写的节点名不对用kubectl describe pod看事件即可。3. 可复制的 IngressRoute 与 Middleware 配置模板这一节是全文的核心给你一套能直接 apply 的清单。整体思路是外部请求先到 TraefikTraefik 按 Host 路由到一个集群内的网关 Service这个 Service 的 Endpoints 指向 TaoToken 的 API 通道。3.1 定义指向 TaoToken 的 ExternalName Service因为 TaoToken 的 API 在集群外用ExternalName类型的 Service 最干净不需要手写 EndpointsapiVersion: v1 kind: Service metadata: name: taotoken-gateway namespace: default spec: type: ExternalName externalName: taotoken.net ports: - name: https port: 443 targetPort: 443 protocol: TCP这里externalName填taotoken.netTraefik 转发时会解析到这个域名。注意 ExternalName 只做 DNS 层面的 CNAME不做端口改写所以端口保持 443。3.2 创建 Middleware注入认证头与限流TaoToken 的 API 需要Authorization: Bearer key头。用 Traefik 的headers中间件可以统一注入避免每个业务服务自己配apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: taotoken-auth namespace: default spec: headers: customRequestHeaders: Authorization: Bearer sk-你的实际Key注意把 Key 直接写在 Middleware 里虽然能跑但不推荐用于生产。更稳妥的做法是用secret引用或者让网关服务自己从 Secret 读取。这里为了演示链路完整性先这么写实际部署请替换成从 Secret 挂载的方式。再加一个限流中间件防止测试环境被刷爆apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: taotoken-ratelimit namespace: default spec: rateLimit: average: 50 burst: 100 period: 1saverage: 50表示每秒平均 50 个请求burst: 100是突发上限。这个值按你的配额调整TaoToken 控制台里能看到实际用量。3.3 编写 IngressRoute 路由规则现在把 Service 和 Middleware 串起来apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: taotoken-route namespace: default spec: entryPoints: - websecure routes: - match: Host(api.yourdomain.com) PathPrefix(/v1) kind: Rule middlewares: - name: taotoken-auth - name: taotoken-ratelimit services: - name: taotoken-gateway port: 443 scheme: https tls: secretName: yourdomain-tls几个关键字段说明entryPoints只写websecure因为 HTTP 已经在 values 里配了redirectTo不用重复。match用Host加PathPrefix组合只把/v1开头的请求转发到 TaoToken其他路径不受影响。scheme: https必须显式写否则 Traefik 默认用 HTTP 去连 443 端口会失败。tls.secretName指向你提前创建的证书 Secret。3.4 TLS 证书自动签发配置如果你用 cert-manager可以省掉手动创建 Secret 的步骤。先装 cert-manager然后创建 ClusterIssuerapiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-prod spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: your-emailexample.com privateKeySecretRef: name: letsencrypt-prod solvers: - http01: ingress: class: traefik然后在 IngressRoute 的 tls 段加一行certResolvertls: certResolver: letsencrypt-prodcert-manager 会自动申请证书并写入 SecretTraefik 检测到后热加载不用重启。实测下来从 apply 到证书生效大约 1-2 分钟用kubectl get certificate能看到 Ready 状态。3.5 完整 apply 流程把上面四段 YAML 存成文件后依次执行kubectl apply -f taotoken-service.yaml kubectl apply -f taotoken-middleware.yaml kubectl apply -f taotoken-ingressroute.yaml检查资源状态kubectl get ingressroute kubectl get middleware kubectl get svc taotoken-gateway如果 IngressRoute 的 STATUS 为空但没报错通常是正常的Traefik 的 CRD 不像 Ingress 那样回写状态。真正验证要看 Traefik 的 dashboard 或者直接发请求。4. 验证请求与成功结果配置写完不验证等于没写。这一节给你完整的 curl 步骤和预期输出。4.1 基础连通性验证先确认 Traefik 的入口端口在监听curl -I http://api.yourdomain.com/v1/models预期返回 301 或 308Location 指向https://api.yourdomain.com/v1/models说明 HTTP 跳转生效。再测 HTTPScurl -I https://api.yourdomain.com/v1/models如果证书没问题会返回 200 或 401。返回 401 说明请求已经到达 TaoToken只是认证头没带上或 Key 无效这恰恰证明路由链路是通的。4.2 带认证的完整请求用真实 Key 发一个模型列表请求curl -s https://api.yourdomain.com/v1/models \ -H Authorization: Bearer sk-你的实际Key \ | head -c 500成功的话会返回 JSON包含模型列表。如果你在 Middleware 里已经注入了 Authorization 头那 curl 里可以省略这个头直接curl -s https://api.yourdomain.com/v1/models | head -c 500实测下来Middleware 注入的头会覆盖客户端传的同名头所以不用担心冲突。4.3 验证限流中间件快速发 200 个请求观察是否触发限流for i in $(seq 1 200); do curl -s -o /dev/null -w %{http_code}\n https://api.yourdomain.com/v1/models done | sort | uniq -c如果限流生效会看到一部分 429 状态码。average: 50的配置下200 个请求里大约有 150 个会被限掉。这个测试能确认 Middleware 确实挂载到了路由上。4.4 查看 Traefik 访问日志Traefik 的 access log 会记录每个请求的路由匹配情况kubectl logs -n kube-system -l app.kubernetes.io/nametraefik --tail50日志里能看到RouterName、ServiceName、OriginStatus等字段。如果请求没匹配到路由会显示 404 且 RouterName 为空这时候就要回去检查match规则里的 Host 是否和实际请求一致。4.5 验证 TLS 证书echo | openssl s_client -connect api.yourdomain.com:443 -servername api.yourdomain.com 2/dev/null | openssl x509 -noout -dates输出里notAfter是证书过期时间。如果是 cert-manager 签发的有效期 90 天到期前会自动续期。5. 本篇常见错误排查配置过程中最容易踩的坑我都整理出来了对照报错直接定位。5.1 401 Unauthorized这是最常见的。原因通常是 Authorization 头没带上或者 Key 格式不对。检查两点Middleware 里的 Key 是否以Bearer开头注意有个空格以及 Key 本身是否在 TaoToken 控制台被禁用。如果 Middleware 配置正确但依然 401用kubectl describe middleware taotoken-auth看事件确认 Middleware 被 Traefik 正确加载。有时候 namespace 不匹配会导致 Middleware 找不到IngressRoute 和 Middleware 必须在同一 namespace除非用allowCrossNamespace。5.2 local proxy failed 或 connection refused这个报错说明 Traefik 无法连接到上游 Service。检查taotoken-gateway这个 ExternalName Service 的externalName是否拼写正确以及集群的 DNS 能否解析taotoken.netkubectl run -it --rm debug --imagebusybox --restartNever -- nslookup taotoken.net如果解析失败说明集群的 CoreDNS 配置有问题或者节点没有外网出口。这种情况下 Traefik 再怎么配都没用得先解决网络连通性。5.3 reading choices 相关报错如果你在网关服务里做了请求体解析可能会遇到reading choices这类错误。这通常是因为 Traefik 转发时改了请求头或 body 编码。检查 Middleware 里有没有误加customRequestHeaders修改Content-Type。TaoToken 的 API 对Content-Type: application/json敏感如果被改成别的会解析失败。5.4 OAuth 或认证流程异常如果你用的是需要 OAuth 的模型服务Traefik 的forwardAuth中间件可能和 TaoToken 的 Key 认证冲突。建议不要在 Traefik 层做 OAuth把认证统一交给 TaoToken 的 Key 机制。如果确实需要用forwardAuth指向一个独立的认证服务认证通过后再注入 TaoToken 的 Key。5.5 IngressRoute 不生效apply 之后请求还是 404按这个顺序排查先看kubectl get ingressroute -o yaml确认资源创建成功。再看 Traefik 的 dashboard如果开了的话在 Routers 页面找你的路由名。如果 dashboard 里没有说明 Traefik 没加载到这个 CRD检查providers.kubernetesCRD.enabled是否为 true。还有一个隐蔽的坑entryPoints名字必须和 values 里定义的一致。如果你把 websecure 改名了IngressRoute 里也要同步改。5.6 证书签发失败cert-manager 的证书一直 Pending用kubectl describe certificate看事件。常见原因是 HTTP01 challenge 的路径被 Traefik 拦截了。cert-manager 会在/.well-known/acme-challenge/下放验证文件如果你的 IngressRoute 把PathPrefix(/)全转发到 TaoTokenchallenge 请求就到不了 cert-manager 的 solver。解决办法是给 challenge 单独加一条优先级更高的路由或者用 DNS01 方式签发。DNS01 需要配置 DNS provider 的 API Token稍微麻烦但更稳定。6. 把入口收口后的日常维护与 CTA路由跑通只是开始日常维护才是省心的关键。我自己的做法是所有涉及模型调用的 IngressRoute 都打上统一 label比如app.kubernetes.io/component: ai-gateway这样用一条命令就能列出所有相关路由kubectl get ingressroute -l app.kubernetes.io/componentai-gatewayKey 轮换的时候只需要更新 Secret 和 Middleware 里的引用不用动业务服务的配置。TaoToken 控制台里可以按 Key 看调用量如果某个 Key 用量异常直接在控制台禁用Traefik 这边不用改任何东西。配额管理也是同理。测试环境经常出现某个组把额度跑满的情况在 TaoToken 控制台给每个 Key 设上限比在 Traefik 层做限流更精准因为限流中间件只能控制速率控制不了总量。如果你还没开始接入建议先去 API Keys 页面https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content建一个测试 Key配合接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content把上面的 YAML 跑一遍。长期跑编码或 Agent 任务的话Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content的配额模式更适合不用每次手动调限流参数。最后留一个我踩过的坑Traefik 的 Middleware 顺序是按数组顺序执行的taotoken-auth一定要放在taotoken-ratelimit前面。如果反了限流会先于认证执行未认证的请求也会消耗限流配额导致正常请求被误伤。这个细节在官方文档里没明说但实测确实如此。
返回列表