
1. 先分清这一层 404 是谁返回的curl 172.25.254.3:30549 返回 404 时先别急着怀疑 ingress-nginx-controller 没起来。这个 404 页面里带了 nginx/1.19.0 的版本号说明流量已经到了 Ingress Controller。TaoToken 官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 先放一边我们得先把这一层 404 的来路分清Controller 正在工作只是没找到可转发的后端 Service。这一层 404 和处理业务应用的 404 含义不同。接下来的排障过程里TaoToken 负责给 Codex 提供一条可用的模型 API 通道让 Codex 理解你贴过来的 ingress.yaml再结合 curl 返回逐项核对 Ingress 规则的 serviceName、servicePort 与后端 Pod 的 selector 是否匹配。1.1 curl 打 NodePort 的 404 是 ingress-nginx 的默认欢迎页在原文的部署流程里应用 ingress-nginx-controller 之后用kubectl -n ingress-nginx describe svc ingress-nginx-controller可以看到 NodePort 被映射成了 30549。此时从集群外的 client 执行curl 172.25.254.3:30549返回的不是 connection refused而是一个完整的 HTML 页面内容包含 404 Not Found页面底部还带着 nginx/1.19.0 的版本号。看到这里很多读者会下意识认为“是不是 NodePort 没配好服务根本不通”。但恰恰相反这条 404 是 ingress-nginx 返回的默认兜底响应。它证明流量已经经过 NodePort进入了 Ingress Controller 的 PodController 正常启动并监听请求只是没有找到可以匹配的后端。换句话说链路的前半段是通的问题出在后半段的 Ingress 规则上。1.2 这一层 404 与 Service 后端的 404 有什么区别集群里常见的失败有三种表现。第一种是 curl 直接拒绝连接通常是因为 NodePort 没有监听或者 Service 没有关联到任何 Podkube-proxy 找不到转发目标。第二种是 502 Bad Gateway说明请求已经到了后端 Service但后端的 Pod 没有响应。第三种就是当前场景里的 404 默认页页面由 ingress-nginx 本身生成表示 Controller 收到了请求但在 Ingress 对象里找不到匹配的 host 或 path或者匹配到了规则而规则指向的 Service 不在同一个命名空间、Service 下没有 Ready 的 Endpoints。所以排障的第一步不是反复重建 Service而是先问自己这份 404 是什么进程返回的。响应体里带 nginx/1.19.0说明来自 ingress-nginx响应体里没有版本号才需要考虑业务应用本身的问题。带着这个结论去看 ingress.yaml思路会比直接重装 Controller 清晰很多。2. 给 Codex 接上 TaoToken 通道再开工2.1 先到 TaoToken 拿 API Key要把 Ingress 规则交给 Codex 分析先得让 Codex 有一条能用的模型通道。打开 TaoToken 注册并登录进入控制台创建一个 API Key。注意这个 Key 就是后面配置里的 YOUR_API_KEY不要直接提交到 Git 仓库。模型 ID 不用靠记忆以 TaoToken 模型广场 当时列出的名称为准不同时期的模型列表会有调整。这里顺便把两个地址拆开记官网落地页 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 只用于注册、创建 Key、查看模型广场和用量而 Codex 真正填的接口地址是 https://taotoken.net/api末尾没有 /v1。两个地址的用途不同混用是后面踩坑的高发区。2.2 Codex 的 config.toml 里 Base URL 这样改Codex CLI 读取的是 ~/.codex/config.toml这和 Claude Code 的 settings.json 是两套配置。不要在 Codex 的环境变量里塞 ANTHROPIC_BASE_URLCodex 认的是 config.toml 里的 model_provider。下面是一个最小可用的 provider 配置model 你的模型ID model_provider taotoken [model_providers.taotoken] name TaoToken base_url https://taotoken.net/api env_key ANTHROPIC_AUTH_TOKEN接着把 Key 放进环境变量export ANTHROPIC_AUTH_TOKENYOUR_API_KEYWindows 用户可以编辑%USERPROFILE%\.codex\config.toml再在 PowerShell 里执行$env:ANTHROPIC_AUTH_TOKENYOUR_API_KEY。注意base_url 不要带 /v1也不要顺手把官网链接填进去。官网给人操作接口给工具调。保存之后先发一条最简单的消息确认 Codex 能正常回复。如果报 401检查 Key 是否替换了占位符报 404检查 base_url 是不是多写了 /v1报 model not found回模型广场重新复制一个模型 ID。这三类错误都确认无误再开始贴 Ingress 相关的 yaml否则排障时会把模型通道的问题和 Ingress 的问题混在一起。3. 把 curl 404 和 ingress.yaml 一起交给 Codex3.1 先整理最小复现信息Codex 不是神仙你只丢一句“我的 Ingress 404 了”它也只能泛泛而谈。要让它给出准确判断至少准备四份上下文curl 命令和完整响应体包括 404 Not Found 以及 nginx/1.19.0 那几行。kubectl -n ingress-nginx describe svc ingress-nginx-controller输出的 NodePort 端口。当前的 ingress.yaml 文件内容。Service 定义里 selector 与 Deployment 中 Pod labels 的对应关系。原文中创建的 Ingress 对象名字是 ingress-myserviceahost 是 www1.westos.orgpath 是 /backend 的 serviceName 是 myserviceservicePort 是 80。如果你在自己的集群里复现时curl 172.25.254.3:30549 返回 404先别急着改 Ingress Controller重点检查 myservice 是否存在、是否真的暴露了 80 端口、以及它后面有没有 Ready 的 Pod。3.2 让 Codex 核对 serviceName 与 selector给 Codex 的提示词不要写得像“帮我修好”而是让它做静态核对例如这样这是 ingress-nginx 通过 NodePort 暴露后的 404 现象。请检查 ingress.yaml 里的 backend 是否与 Service 定义匹配 1. serviceName 是否存在是否拼错 2. servicePort 对应 Service 定义里的 port 还是 targetPort 3. Service 的 selector 与 Deployment 的 labels 是否一致 4. 如果 Service 一切正常为什么 curl NodePort 仍然是 404。 只分析不修改 yaml。Codex 拿到这几段信息后会按顺序核对 serviceName、servicePort、selector。例如当 Codex 看到 service.yml 后它会先看 spec.selector 和 deployment.yml 中 template.labels 是否完全一致再看 endpoints 列表是否非空。如果两个标签完全一致但 endpoints 为空它会提醒你检查 Pod 是否处于 Running 状态以及是否有资源配额导致 Pod 调度失败。如果 endpoints 正常但 curl 仍返回 404它会把注意力转到 ingress-nginx-controller 的启动参数和 annotations比如 kubernetes.io/ingress.class 是否写成了 nginxIngress 对象是否真的被 Controller watch 到。需要特别说明的是Codex 在这个环节里只做代码和配置分析不会直接连接你的 Kubernetes 集群也不会替你执行 kubectl apply。ingress.yaml 的任何改动、kubectl 命令的执行都必须在你的 master 节点或本地跳板机上手动完成。改完以后把新的 curl 输出贴回对话Codex 会根据前后两次输出差异判断问题是否已经解决。TaoToken 在这条链路里与 Kubernetes 没有任何交集它只是让 Codex 通过 https://taotoken.net/api 消耗 Token 的模型通道。4. 实践中最容易配错的四个点4.1 serviceName 拼写或命名空间不一致Ingress 默认和 Service 处于同一个命名空间。如果 Service 在 default 空间Ingress 也在 default 空间serviceName 填 myservice 没问题一旦 Service 建在其它命名空间而 ingress.yaml 里没有指定 backend 的命名空间Controller 就会找不到后端。这个错误在 describe 命令里不会直接报错只会以 404 的形式沉默出现。Codex 在分析时通常会先让你贴出kubectl get svc -A的输出来确认命名空间。4.2 servicePort 填了 targetPort另一个高频错误是拿 targetPort 当 servicePort 填。假如 Pod 内的容器监听 8080Service 定义中 port 是 80targetPort 是 8080那么 Ingress 的 servicePort 应该填 80而不是 8080。ingress-nginx 把流量转到 Service 的 port再由 kube-proxy 转发到 Pod 的 targetPort。填成 8080 后Controller 可以匹配到规则但上游连接落到错误端口上表现可能是 404也可能是 502。4.3 Pod 的 labels 和 selector 没对齐再核对 service.yml 和 deployment.yml 的标签。原文里 myservice 的 selector 是 app: myappdeployment-myapp-v1 模板里的 labels 也是 app: myapp所以这条链路是正常的。如果你复制了 deployment 只改镜像忘了改 labels或者 Service 的 selector 里多写了一个字段Pod 就不会进入 Service 的 Endpoints 列表。此时可以在本地执行kubectl get endpoints myservice如果 ENDPOINTS 列是空的说明根本没有 Pod 被选中。返回去对比 Service selector 与 Pod labels而不是继续修改 Ingress。4.4 host 字段不匹配导致的隐蔽 404当 Service 与 selector 都没问题时还有一个容易遗漏的点curl 请求里的 Host 头必须能匹配到 Ingress 规则中的 host 字段。原始环境里 Ingress 规则写的是 www1.westos.org而你如果执行curl -H Host: www1.westos.org http://172.25.254.3:30549/会因为 Host 匹配成功而正常转发如果 Host 头拼写多了斜杠、带上了端口或者直接访问 IPingress-nginx 就找不到对应规则返回默认 404。Codex 在分析时会继续追问你 curl 的完整命令而不仅仅是响应体这个细节需要你提前准备好。5. 验证这次调用并做最后确认5.1 修改后重新测试访问方式把 ingress.yaml 修正并重新 apply 之后不要直接依赖 /etc/hosts 里的域名解析建议先用带 Host 头的命令测试curl -H Host: www1.westos.org http://172.25.254.3:30549/如果返回业务应用页面说明 Ingress 和 Service 的关联恢复。如果仍然返回 nginx/1.19.0 的 404 页面再把最新的 describe svc 输出和 endpoints 列表贴回 Codex它会继续缩小范围比如检查 Ingress 对象是否真的被 Controller 加载、annotations 里的 ingress.class 是否写对。注意如果你的集群版本高于 1.19原本的 networking.k8s.io/v1beta1 已经不能继续使用ingress.yaml 需要改写成 v1 的格式backend 字段从 serviceName/servicePort 变成 service.name/service.port.number。Codex 在你贴出 kubectl apply 的报错后通常也会第一时间提醒你升级 API 版本。这属于正常的配置迁移不要把 v1beta1 的字段硬塞到新版本集群里。5.2 回到 TaoToken 控制台核对这次 Codex 调用配通之后Codex 每分析一轮都会消耗 Token。调试结束后建议去 TaoToken 控制台的用量页面确认这次调用是否正常计费。也可以在模型对话页面用同一把 Key 发一条测试消息排除 Codex 配置层面的偶发问题。后续如果长期用 Codex 排查集群配置按量套餐比临时充值更省心模型对话快速验证 Key 和模型 ID 是否真实可用。Coding Plan给 Codex 的持续调用选一个更划算的套餐。创建 Key多环境共用时分别建 Key方便分别限额和审计。以后再遇到 Ingress 返回 404先看响应体里有没有 nginx 版本号再查 Ingress 规则指向的 Service 是否真的有 Endpoints。这两步做完剩下的无非是让 Codex 帮你对照 yaml 找拼写和标签映射问题。这次排障的思路很简单TaoToken 的 Base URL 不带 /v1Codex 的 provider 认的是 config.toml而 Kubernetes 的 404 先查 serviceName 和 selector。