ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

K8S Ingress 之 traefik-ingress-controller:把 Ingress 入口改到 TaoToken 的实操大纲

K8S Ingress 之 traefik-ingress-controller:把 Ingress 入口改到 TaoToken 的实操大纲 1. 从 NodePort 到 Ingress为什么要把入口交给 traefik-ingress-controllerK8S Ingress 是集群七层流量的统一入口抽象traefik-ingress-controller 则是把这个抽象真正落地成反向代理进程的那块拼图。它能做什么简单说你写一条 Ingress 规则声明「哪个域名、哪个路径转发到哪个 Service」traefik 就会监听 80/443把外部请求按规则送到后端 Pod。适合谁适合已经用 NodePort 暴露过服务、被 30000~32767 端口范围和证书配置折腾过的人。我最早接触这块时服务是用 NodePort 固定 30001 对外暴露的。能跑但问题很快堆起来端口范围受限想用 80/443 得改 apiserver 参数不推荐服务一多每个都要占一个 NodePort还得人工维护端口表避免冲突对外开的端口越多安全面越大最要命的是 HTTPS 证书还得单独再起一个 nginx 或 traefik 来配。这几个需求叠在一起结论就很清楚了——需要一个统一的反向代理层而 K8S 原生给的方案就是 Ingress Ingress Controller。组件关系得先理清不然后面配置容易懵。Service 是后端真实服务的抽象一个 Service 对应多个相同 PodIngress 是转发规则的抽象按 Host 和 path 决定请求落到哪个 ServiceIngress Controller 是真正干活的 Pod它解析 Ingress 规则规则一变就热更新自己的转发配置收到请求后按规则转发。K8S 本身不自带 Controller它只是标准实现有 Nginx、Traefik 等多种。本文用 traefik-ingress-controller把入口从 NodePort 改到 Ingress并给出可复制的 YAML、证书生成、secret 创建和 curl 验证链路。这里有个容易忽略的点Ingress、Service、Pod、Secret 必须在同一个 namespace而 Ingress Controller 自己的 namespace 没有这个要求。这个结论我在实测里踩过后面排障章节会展开。2. TaoToken 前置准备拿到 Base URL、Key 和 Model ID在把入口改到 traefik 之前得先把后端要对接的模型服务准备好。TaoToken 在这里扮演的是统一 API 网关的角色你拿到一组凭证就能在集群里以标准 OpenAI 兼容接口的方式调用模型。这一步不复杂但三件套必须齐全Base URL、API Key、Model ID。Base URL 是https://taotoken.net/api注意这个地址不带任何查询参数直接作为请求前缀。API Key 在控制台的 API Keys 页面生成生成后只显示一次务必当场复制保存。Model ID 取决于你要调用的具体模型在模型列表里能看到对应的标识串。如果你只是想在集群里验证一下模型能不能通可以先用模型对话页面手动发一条请求确认 Key 有效、模型可用再去配 K8S 里的 Service 和 Ingress。这个顺序能帮你把「凭证问题」和「网络问题」分开排查省很多时间。对于长期跑编码任务或 Agent 的场景Coding Plan 更合适它按订阅方式提供额度不用每次请求都算 token。而如果你只是偶尔验证用 API Keys 按量调用就够了。两条路径的凭证是同一套体系切换成本很低。把这三件套记下来后面写 Service 的 ExternalName 或者 ConfigMap 时会直接用到。我建议先在本地用 curl 打一次确认返回正常再进集群配置这样出问题时能快速定位是凭证错还是网络不通。3. 可复制配置traefik 部署、Ingress 规则与后端 Service这一节是全文的核心所有片段都可以直接复制。先部署 traefik-ingress-controller版本用 traefik:1.7.20包含 Namespace、ConfigMap、RBAC、Deployment 四部分。ConfigMap 里的 traefik.toml 定义了 http/https 两个 entryPoint开启 compress并配置了 ping 健康检查入口。apiVersion: v1 kind: Namespace metadata: name: traefik-ingress-controller --- apiVersion: v1 kind: ConfigMap metadata: name: traefik-ingress labels: app: traefik namespace: traefik-ingress-controller data: traefik.toml: | logLevel info defaultEntryPoints [http, https] [entryPoints] [entryPoints.http] address :80 compress true [entryPoints.http.redirect] entryPoint https [entryPoints.https] address :443 compress true [entryPoints.https.tls] [ping] entryPoint http [kubernetes] [traefikLog] format json --- kind: ServiceAccount apiVersion: v1 metadata: name: traefik-ingress namespace: traefik-ingress-controller --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: traefik-ingress rules: - apiGroups: [] resources: [pods, services, endpoints, secrets] verbs: [get, list, watch] - apiGroups: [extensions] resources: [ingresses] verbs: [get, list, watch] - apiGroups: [extensions] resources: [ingresses/status] verbs: [update] --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: traefik-ingress roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: traefik-ingress subjects: - kind: ServiceAccount name: traefik-ingress namespace: traefik-ingress-controller --- apiVersion: apps/v1 kind: Deployment metadata: name: traefik-ingress labels: app: traefik namespace: traefik-ingress-controller spec: replicas: 1 selector: matchLabels: app: traefik template: metadata: labels: app: traefik spec: hostNetwork: true serviceAccountName: traefik-ingress terminationGracePeriodSeconds: 60 containers: - image: traefik:1.7.20 name: traefik-ingress readinessProbe: httpGet: path: /ping port: http failureThreshold: 1 initialDelaySeconds: 10 periodSeconds: 10 livenessProbe: httpGet: path: /ping port: http failureThreshold: 3 initialDelaySeconds: 10 periodSeconds: 10 volumeMounts: - mountPath: /config name: config ports: - name: http containerPort: 80 protocol: TCP - name: https containerPort: 443 protocol: TCP args: - --configfile/config/traefik.toml volumes: - name: config configMap: name: traefik-ingress注意hostNetwork: true这一行它让 traefik 直接占用宿主机 80/443省去再套一层 Service 的麻烦。生产环境如果要多副本得改成 LoadBalancer 或 NodePort 方式这里为了演示链路清晰就用 hostNetwork。接着是后端 Service。假设你的模型调用服务叫taotoken-backend监听 8080Service 定义如下apiVersion: v1 kind: Service metadata: name: taotoken-backend namespace: default spec: selector: app: taotoken-backend ports: - name: http port: 8080 targetPort: 8080 protocol: TCP type: ClusterIP然后是 Ingress 规则把域名api.taotoken-demo.com的/v1路径转发到上面的 ServiceapiVersion: extensions/v1beta1 kind: Ingress metadata: name: taotoken-ingress namespace: default annotations: kubernetes.io/ingress.class: traefik spec: tls: - hosts: - api.taotoken-demo.com secretName: taotoken-tls rules: - host: api.taotoken-demo.com http: paths: - path: /v1 backend: serviceName: taotoken-backend servicePort: 8080这里kubernetes.io/ingress.class: traefik是关键注解告诉集群这条规则归 traefik 管。tls 段引用了 secrettaotoken-tls下一步生成。证书用 openssl 自签命令如下openssl genrsa -out taotoken-key.pem 2048 openssl req -new -x509 -key taotoken-key.pem -out taotoken.pem \ -subj /CCN/STBeiJing/LBeiJing/OTaoToken/OUDemo/CNapi.taotoken-demo.com \ -days 3650 openssl x509 -in taotoken.pem -text -noout生成后创建 secretkubectl create secret tls taotoken-tls \ --key taotoken-key.pem \ --cert taotoken.pem \ -n default最后一次性 applykubectl apply -f traefik.yml kubectl apply -f taotoken-service.yaml kubectl apply -f taotoken-ingress.yaml如果你用的是 Cline MCP 或 Codex 的 auth.json 方式对接记得把 Base URL 填https://taotoken.net/apiKey 填控制台生成的串Model ID 填你选定的模型标识三者缺一不可。CC Switch 场景同理切换配置时这三项要同步改否则会出现 401 或模型找不到的报错。4. 验证请求链路curl 看状态码与返回体配置 apply 完先确认资源状态。执行kubectl get pod -A应该看到 traefik-ingress-controller 命名空间下有一个 Running 的 Poddefault 下有你后端的 Pod。再kubectl get ingress -n defaultHOSTS 列显示api.taotoken-demo.comPORTS 显示 80, 443。kubectl get secret -n default能看到taotoken-tlsTYPE 是 kubernetes.io/tls。然后在本地 hosts 文件加一条解析把域名指向 traefik 所在节点 IP。Linux/macOS 是/etc/hostsWindows 是C:\Windows\System32\drivers\etc\hosts追加192.168.1.65 api.taotoken-demo.com接着用 curl 验证。先测 HTTP 是否被重定向到 HTTPScurl -I http://api.taotoken-demo.com/v1/models预期返回 301 或 308Location 指向 https 地址。再测 HTTPS 直连自签证书加-k跳过校验curl -k -i https://api.taotoken-demo.com/v1/models \ -H Authorization: Bearer $TAOTOKEN_API_KEY正常情况返回 200body 里是模型列表 JSON。如果后端服务需要 POST可以这样打一条对话请求curl -k -X POST https://api.taotoken-demo.com/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d { model: your-model-id, messages: [{role: user, content: ping}] }返回体里出现choices数组说明整条链路通了外部请求 → traefik 80/443 → Ingress 规则匹配 → Service → 后端 Pod → TaoToken API → 模型返回。状态码 200 加上 choices 字段就是链路健康的标志。如果只想快速确认 traefik 本身活着可以打它的 ping 端点curl -k https://api.taotoken-demo.com/ping返回OK说明 controller 正常。这一步能把「controller 挂了」和「后端不通」区分开排障时很有用。5. 常见报错排查401、local proxy failed、reading choices、OAuth排障这块我按真实遇到过的报错来写每条都给定位思路。401 Unauthorized最常见。先确认 curl 里的Authorization: Bearer后面那串 Key 是不是控制台生成的完整串有没有多空格或换行。再确认后端服务读取 Key 的环境变量有没有正确注入。如果是 Cline MCP 或 Codex auth.json 场景检查文件里的 Base URL 是不是https://taotoken.net/apiKey 和 Model ID 是否三件套齐全。缺任何一项都会 401。local proxy failed这个报错通常出现在客户端侧说明请求根本没到 traefik。先kubectl get pod -n traefik-ingress-controller看 controller 是否 Running再看kubectl logs有没有监听 80/443 失败。如果 hostNetwork 模式下 80 被占用controller 会起不来。用ss -lntp | grep :80查占用进程。另外确认 hosts 解析的 IP 是不是 traefik 所在节点解析错了请求会打到别处。reading choices 相关报错一般是返回体解析失败说明请求到了后端但响应格式不对。检查后端服务返回的是不是标准 JSON有没有被中间件改写。如果 Ingress 上加了 rewrite 或 redirect 中间件路径可能被改掉导致后端收到错误路径返回非预期内容。把中间件临时去掉再测一次能快速定位。OAuth 报错如果你在 Ingress 上挂了 OAuth 中间件做鉴权报错多半是 token 过期或回调地址不匹配。检查中间件配置里的 client ID、secret、callback URL 是否和实际域名一致。自签证书场景下OAuth 回调可能因为证书不受信而失败测试阶段可以先绕过鉴权中间件确认链路通了再逐步加回。还有一个隐蔽的坑Ingress、Service、Pod、Secret 不在同一个 namespace。我实测时把 Ingress 放在 defaultService 放在别的 namespace规则匹配到了但后端找不到返回 503。记住那条结论——这四个资源必须同 namespacecontroller 自己的 namespace 无所谓。排查顺序建议先kubectl get看资源状态再kubectl logs看 controller 日志然后 curl 打 ping 确认 controller 活着最后带 Key 打业务接口。一层层往下别一上来就怀疑模型服务。6. 把入口固定下来后续接入与凭证管理链路验证通过后日常维护其实就两件事管好凭证管好规则。凭证方面API Key 建议用 K8S Secret 注入到后端 Pod不要硬编码在镜像或 YAML 里。轮换 Key 时只改 Secret重启 Pod 即可Ingress 规则不用动。规则方面新增服务时复制一份 Ingress YAML改 host、path、serviceName、servicePort 四个字段就行。如果多个服务共用一个域名用不同 path 区分比如/v1/chat和/v1/embeddings分别指向不同 Service。traefik 会按最长路径优先匹配不用担心冲突。证书续期别忘了。自签证书虽然设了 3650 天但生产环境建议用 cert-manager 自动续期或者至少记个日历提醒。证书过期后浏览器和 curl 都会报错但 traefik 本身不会主动告警容易漏。如果你后面要跑长期编码任务或 Agent把凭证从按量 API Key 换成 Coding Plan 的订阅凭证接入方式不变还是 Base URL Key Model ID 三件套只是额度模型不同。切换时记得同步更新 K8S Secret 和客户端配置避免一半旧一半新导致 401。整套配置跑下来最大的收益是入口统一了80/443 对外证书集中管新增服务只改一条 Ingress。NodePort 那套端口维护表可以彻底扔掉。
返回列表