ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

K8S运维笔记:安装traefik-ingress时把endpoint改到TaoToken

K8S运维笔记:安装traefik-ingress时把endpoint改到TaoToken 1. 为什么 traefik-ingress 安装阶段最容易卡在 endpoint 上K8S 集群里装 traefik-ingress很多人第一次跑kubectl apply之后看到 Pod 一直ImagePullBackOff或者 traefik 起来了但访问外部依赖超时翻日志发现是拉镜像、探活、回调这些环节的 endpoint 指向了默认公网地址而集群出口并不通畅。这个问题的本质不是 traefik 本身难装而是安装过程中涉及的镜像仓库地址、外部 API 通道、健康检查目标这些 endpoint 没有统一收口。traefik-ingress 在 K8S 里的角色是七层入口控制器它自己作为一个 Deployment 跑在kube-system里通过 watch Kubernetes API 感知 Ingress 资源变化然后动态生成路由规则。安装阶段它需要做几件事拉取 traefik 镜像、连接 apiserver、暴露 dashboard、可选地对接外部服务做鉴权或限流。这几件事里镜像拉取和外部依赖访问是最容易因为 endpoint 配置不当而失败的。我试过在一个内网集群里直接套用官方 YAML镜像写的是traefik默认走 Docker Hub结果节点没有配镜像加速Pod 卡在ErrImagePull。后来把镜像地址换到内部 registry 才通。但更隐蔽的问题是 traefik 启动后要访问外部依赖时比如你想让它对接一个统一的 API 通道做鉴权或转发endpoint 如果还指向默认地址请求就会超时dashboard 里能看到路由规则但实际转发失败。所以这篇笔记的核心思路是在安装 traefik-ingress 的阶段就把需要访问外部依赖的 endpoint 统一改到 TaoToken 的 API 通道上用一套 Key 管理所有外部调用避免每个服务单独配 endpoint 导致混乱。TaoToken 在这里扮演的是一个统一的 API 入口你可以把它理解成一个收口层traefik 需要访问的外部依赖都通过这个通道走Key 和 Base URL 统一管理。适合谁看正在 K8S 集群里装 traefik-ingress 的运维或后端开发尤其是集群出口受限、镜像拉取和外部依赖访问容易出问题的环境。下面从 RBAC 到 Deployment 到验证一步步给可复制的配置。2. TaoToken 前置准备Key、Base URL 与 Model ID 三件套在改 traefik-ingress 的 endpoint 之前先把 TaoToken 这边的三件套准备好。这三件套是后面所有配置的基础缺一个后面都会报错。第一件是 API Key。打开 https://taotoken.net/api-keys 登录后创建一个新的 Key复制出来保存好。这个 Key 后面会以 Secret 的形式注入到 traefik 的 Pod 里不要直接写在 YAML 明文里。Key 的格式一般是一串以sk-开头的字符串创建后只显示一次丢了就重新建一个。第二件是 Base URL。TaoToken 的 API 地址是https://taotoken.net/api注意这里不带任何路径后缀后面在配置里拼具体路径时再补。这个地址就是 traefik 访问外部依赖时的统一 endpoint所有需要走外部通道的请求都指向它。第三件是 Model ID。如果你只是用 traefik 做入口转发不涉及模型调用Model ID 可以暂时不填。但如果你在 traefik 的中间件里配置了鉴权或内容处理需要调用模型那就要指定具体的 Model ID。常见的比如claude-sonnet-4-20250514这类具体以你账号里可用的为准。在 https://taotoken.net/models 可以查到当前支持的模型列表。把这三件套准备好之后先在本地用 curl 验证一下 Key 是否可用避免后面在 K8S 里排查半天发现是 Key 的问题curl -X POST https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer sk-你的Key \ -H Content-Type: application/json \ -d { model: claude-sonnet-4-20250514, messages: [{role: user, content: ping}], max_tokens: 10 }如果返回里有choices字段说明 Key 和 Base URL 都没问题。如果返回 401检查 Key 是否复制完整如果返回 404检查 Base URL 是否多了或少了路径。这一步在本地跑通后面在 K8S 里就少一个变量。接下来把 Key 存成 K8S Secret。在kube-system命名空间下创建kubectl create secret generic taotoken-credentials \ --from-literalapi-keysk-你的Key \ --from-literalbase-urlhttps://taotoken.net/api \ -n kube-system创建完用kubectl get secret taotoken-credentials -n kube-system -o yaml确认一下能看到 base64 编码的 value 就行。这个 Secret 后面会在 Deployment 里以环境变量或 volume 的形式挂进去。注意Secret 的 value 是 base64 编码不是加密。生产环境建议配合 RBAC 限制 Secret 的读取权限或者用外部密钥管理。这里为了演示方便直接用 Secret。三件套准备好之后就可以开始改 traefik-ingress 的部署配置了。下面的 YAML 都是可复制的你只需要把 Key 和地址替换成自己的。3. 可复制配置把 traefik-ingress 的 endpoint 指向 TaoToken这一节是核心给出完整的 traefik-ingress 部署 YAML重点是把需要访问外部依赖的 endpoint 改到 TaoToken。先看 RBAC 部分这部分和官方基本一致但要注意 apiVersion 的版本老版本 K8S 用v1beta1新版本用v1--- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: traefik-ingress-controller rules: - apiGroups: - resources: - services - endpoints - secrets verbs: - get - list - watch - apiGroups: - extensions - networking.k8s.io resources: - ingresses verbs: - get - list - watch --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 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-systemRBAC 跑通后接下来是 Deployment。这里的关键改动在容器启动参数和环境变量里把外部依赖的 endpoint 指向 TaoToken--- apiVersion: v1 kind: ServiceAccount metadata: name: traefik-ingress-controller namespace: kube-system --- kind: Deployment apiVersion: apps/v1 metadata: name: traefik-ingress-controller namespace: kube-system labels: k8s-app: traefik-ingress-lb spec: replicas: 1 selector: matchLabels: k8s-app: traefik-ingress-lb template: metadata: labels: k8s-app: traefik-ingress-lb name: traefik-ingress-lb spec: serviceAccountName: traefik-ingress-controller terminationGracePeriodSeconds: 60 containers: - image: traefik:v2.10 name: traefik-ingress-lb env: - name: TAOTOKEN_API_KEY valueFrom: secretKeyRef: name: taotoken-credentials key: api-key - name: TAOTOKEN_BASE_URL valueFrom: secretKeyRef: name: taotoken-credentials key: base-url ports: - name: http containerPort: 80 - name: admin containerPort: 8080 args: - --api - --api.insecure - --providers.kubernetesingress - --log.levelINFO - --entrypoints.web.address:80 - --entrypoints.traefik.address:8080 - --serversTransport.insecureSkipVerifytrue resources: requests: cpu: 100m memory: 128Mi limits: cpu: 500m memory: 256Mi --- kind: Service apiVersion: v1 metadata: name: traefik-ingress-service namespace: kube-system spec: type: NodePort selector: k8s-app: traefik-ingress-lb ports: - protocol: TCP name: web targetPort: 80 port: 80 nodePort: 30080 - protocol: TCP name: admin targetPort: 8080 port: 8080 nodePort: 30081这里有几个点要说明。镜像我用的是traefik:v2.10比裸traefik更可控避免 latest 漂移。环境变量TAOTOKEN_API_KEY和TAOTOKEN_BASE_URL从 Secret 注入这样 traefik 内部如果需要访问外部依赖可以直接读这两个变量拼请求。--serversTransport.insecureSkipVerifytrue是跳过后端 TLS 校验内网环境常用生产环境按需开启。如果你用的是 traefik v3参数名有变化--providers.kubernetesingress变成--providers.kubernetesIngress注意大小写。另外 v3 的 entrypoint 配置也略有不同建议先确认版本再套用。接下来是 dashboard 的 Ingress 配置把 host 改成你自己的--- apiVersion: v1 kind: Service metadata: name: traefik-web-ui namespace: kube-system spec: selector: k8s-app: traefik-ingress-lb ports: - name: web targetPort: 8080 port: 80 --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: traefik-web-ui namespace: kube-system annotations: kubernetes.io/ingress.class: traefik traefik.ingress.kubernetes.io/router.rule-type: PathPrefix spec: rules: - host: traefik.example.com http: paths: - path: /dashboard pathType: Prefix backend: service: name: traefik-web-ui port: number: 80注意 v2 的 annotation 是traefik.ingress.kubernetes.io/router.rule-type老版本是traefik.ingress.kubernetes.io/rule-type别混用。host 换成你自己的域名没有域名就用 NodePort 直接访问。把这些 YAML 保存成文件按顺序 applykubectl apply -f traefik-rbac.yaml kubectl apply -f traefik-deployment.yaml kubectl apply -f traefik-ui.yamlapply 完之后检查 Pod 状态kubectl get pods -n kube-system -l k8s-apptraefik-ingress-lb正常应该是Running。如果卡在ImagePullBackOff说明镜像拉取有问题检查节点是否能访问镜像仓库或者把镜像换成内部 registry 地址。如果卡在CrashLoopBackOff看日志kubectl logs -n kube-system -l k8s-apptraefik-ingress-lb --tail50日志里如果出现连接 apiserver 失败检查 RBAC 和 ServiceAccount 是否绑定正确。如果出现外部依赖超时检查 Secret 里的 base-url 是否指向了 TaoToken。4. 验证请求curl 连通性与 dashboard 检查配置 apply 完之后不能只看 Pod Running 就完事要做两层验证一层是 traefik 自身是否正常另一层是外部依赖通道是否通。先验证 traefik 的 dashboard 能不能访问。如果你配了 Ingress 和域名直接浏览器打开http://traefik.example.com/dashboard。如果没有域名用 NodePort# 获取节点 IP kubectl get nodes -o wide # 访问 dashboard curl -s http://节点IP:30081/dashboard/ | head -20返回 HTML 说明 dashboard 正常。dashboard 里能看到 Routers、Services、Middlewares 这些面板如果 Routers 里能看到你配置的 Ingress 规则说明 traefik 已经成功 watch 到 K8S 资源。接下来验证外部依赖通道。在 traefik 的 Pod 里直接 curl TaoToken 的 API确认网络和 Key 都通# 进入 traefik Pod kubectl exec -it -n kube-system $(kubectl get pods -n kube-system -l k8s-apptraefik-ingress-lb -o jsonpath{.items[0].metadata.name}) -- sh # 在 Pod 内执行 curl -s -o /dev/null -w %{http_code} \ -X POST $TAOTOKEN_BASE_URL/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d {model:claude-sonnet-4-20250514,messages:[{role:user,content:ping}],max_tokens:10}如果返回200说明 Pod 内能正常访问 TaoToken 通道Key 和 Base URL 都生效了。如果返回401检查 Secret 里的 Key 是否正确注入可以用echo $TAOTOKEN_API_KEY看一下。如果返回000或超时说明 Pod 到 TaoToken 的网络不通检查集群的出口策略或 DNS 解析。再验证一个完整的 Ingress 转发链路。部署一个测试服务配一个 Ingress 规则看 traefik 能不能正确转发# 部署测试服务 kubectl create deployment echo --imagehashicorp/http-echo -- /http-echo -texthello from traefik kubectl expose deployment echo --port5678 # 创建 Ingress cat EOF | kubectl apply -f - apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: echo-ingress annotations: kubernetes.io/ingress.class: traefik spec: rules: - host: echo.example.com http: paths: - path: / pathType: Prefix backend: service: name: echo port: number: 5678 EOF然后用 curl 带 Host 头访问 traefik 的 NodePortcurl -s -H Host: echo.example.com http://节点IP:30080/返回hello from traefik说明整条链路通了请求到 traefiktraefik 根据 Ingress 规则转发到 echo 服务。这一步跑通说明 traefik-ingress 的安装和 endpoint 配置都没问题。如果这一步失败先看 traefik 日志里有没有对应的路由匹配记录再看 echo 服务的 Endpoints 是否正常kubectl get endpoints echoEndpoints 为空说明 Service selector 和 Pod label 不匹配检查一下。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth安装 traefik-ingress 并把 endpoint 改到 TaoToken 的过程中几个报错出现频率最高这里逐个对照排查。401 Unauthorized。这个最直接Key 不对或没注入。先确认 Secret 里的 Key 和你在 TaoToken 控制台创建的一致kubectl get secret taotoken-credentials -n kube-system -o jsonpath{.data.api-key} | base64 -d输出的字符串和你控制台里的 Key 对比注意有没有多余空格或换行。如果 Secret 对但 Pod 里echo $TAOTOKEN_API_KEY是空检查 Deployment 里env的secretKeyRef名字和 key 是否写对。还有一种情况是 Key 被禁用或额度用完去 https://taotoken.net/api-keys 看一下状态。local proxy failed。这个报错通常出现在 traefik 尝试访问外部依赖时网络层没通。先确认 Pod 的 DNS 能解析taotoken.netkubectl exec -it -n kube-system traefik-pod -- nslookup taotoken.net解析失败说明集群 DNS 有问题检查 CoreDNS 是否正常。解析成功但连接超时检查节点或 Pod 的出口网络策略有没有限制 443 端口。如果是内网集群确认有没有配 NAT 或出口网关。reading choices 相关报错。这个一般出现在你调用模型接口时返回体解析失败。常见原因是 Base URL 拼错了比如写成了https://taotoken.net/api/v1又在代码里拼了/v1/chat/completions变成/api/v1/v1/chat/completions。正确做法是 Base URL 只写到https://taotoken.net/api具体路径在请求时拼。另外检查请求头Content-Type: application/json有没有带body 是不是合法 JSON。OAuth 相关报错。如果你在 traefik 的中间件里配了 OAuth 鉴权报错通常是回调地址不匹配或 token 端点配错。检查 OAuth 配置里的authorizationEndpoint和tokenEndpoint是否指向了正确的地址。如果这些端点也要走 TaoToken 通道确保 Base URL 拼接正确。另外 OAuth 的 redirect URI 要和你在提供方注册的一致差一个斜杠都会失败。除了这四个还有一个容易忽略的是 traefik 版本和 K8S 版本不匹配。比如 K8S 1.22 之后extensions/v1beta1的 Ingress 被移除必须用networking.k8s.io/v1。如果你套用老 YAMLapply 时会报no matches for kind Ingress in version extensions/v1beta1。解决办法是把 apiVersion 改成networking.k8s.io/v1同时backend的写法也要从serviceName/servicePort改成service.name/service.port.number。排查的时候养成看日志的习惯traefik 的日志级别调到DEBUG能看到更详细的路由匹配和转发记录kubectl logs -n kube-system -l k8s-apptraefik-ingress-lb -f日志里如果看到Skipping service或no matching route说明 Ingress 规则没被正确解析检查 annotation 和 path 配置。6. 长期编码与 Agent 场景把 TaoToken 通道固化到运维流程traefik-ingress 装好只是第一步后面你会不断加 Ingress 规则、调中间件、接新的后端服务。每次改动如果都手动配 endpoint迟早会乱。我的做法是把 TaoToken 的通道配置固化到运维流程里用一套 Key 和 Base URL 管理所有外部依赖。具体来说把 Secret 的创建也纳入版本管理用 SealedSecret 或者外部密钥管理工具避免明文 Key 进 Git。然后在 traefik 的中间件配置里统一引用环境变量TAOTOKEN_BASE_URL这样换环境只需要改 Secret不用动 YAML。如果你后面要跑长期的编码任务或者 Agent 工作流比如让 traefik 对接一个自动扩缩容的 Agent或者用模型做流量分析可以考虑用 Coding Plan 来管理调用额度。在 https://taotoken.net/coding-plan 可以看到适合长期任务的套餐比按次调用更划算。另外traefik 的 dashboard 本身也可以作为一个入口把模型对话的能力集成进去方便运维时直接查。模型对话入口在 https://taotoken.net/chat 你可以用它快速验证 Key 和模型是否可用不用每次都写 curl。接入文档在 https://taotoken.net/doc 里面有各种语言的 SDK 示例和 endpoint 说明遇到不确定的路径拼接问题可以查。API Keys 管理在 https://taotoken.net/api-keys 定期轮换 Key 是个好习惯。最后说一个实操技巧在 traefik 的 Deployment 里加一个 initContainer启动前先 curl 一下 TaoToken 的 API确认通道通了再启动主容器。这样能避免 traefik 起来了但外部依赖不通导致的隐性故障initContainers: - name: check-taotoken image: curlimages/curl:8.5.0 command: - sh - -c - | until curl -s -o /dev/null -w %{http_code} \ -X POST $TAOTOKEN_BASE_URL/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d {model:claude-sonnet-4-20250514,messages:[{role:user,content:ping}],max_tokens:5} \ | grep -q 200; do echo waiting for taotoken... sleep 5 done env: - name: TAOTOKEN_API_KEY valueFrom: secretKeyRef: name: taotoken-credentials key: api-key - name: TAOTOKEN_BASE_URL valueFrom: secretKeyRef: name: taotoken-credentials key: base-url这个 initContainer 会循环检查直到 TaoToken 返回 200 才放行主容器启动时外部依赖一定是通的。实测下来这个做法能省掉很多「Pod 起来了但功能不正常」的排查时间。把这段加到 Deployment 的spec.template.spec里就行注意缩进和主容器平级。
返回列表