1. 先把问题说清楚:Ingress 和 APISIX 到底差在哪
很多刚接触 Kubernetes 的朋友会卡在同一个地方:集群里跑了一堆 Service,外部流量怎么进来?这时候就会遇到 Ingress 和 APISIX 这两个词。Ingress 是 Kubernetes 内置的一套 L7 路由规范,它只定义“请求应该怎么走”,比如api.example.com/v1转发到哪个 Service,但它自己不干活,必须配一个 Ingress Controller 来真正执行路由。APISIX 则是一个完整的高性能 API 网关产品,它不仅能当 Ingress Controller 用,还自带认证、限流、熔断、灰度发布、可观测性等一整套能力。
这篇文章面向的是需要在 Kubernetes 里做 API 网关选型的开发者。我会把两者的配置骨架都拆开给你看,包括 Ingress 的 YAML、APISIX 的config.yaml和apisix.yaml,然后演示怎么通过 TaoToken 统一 Key 和 API 通道完成接入与验证。读完你至少能判断:什么场景用标准 Ingress 就够了,什么场景必须上 APISIX。
先给一个不绕弯的结论:Ingress 是“交通规则”,APISIX 是“带导航和安防的整车”。规则本身不会开车,车可以遵守规则,也可以自己定义更复杂的规则。
2. TaoToken 前置准备:统一 Key 与 API 通道
在讲配置之前,先把接入通道准备好。TaoToken 在这里的角色是统一管理模型调用的 Key 和 API 入口,让你在验证网关路由时不用到处散落密钥。官网入口是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 基础地址是 https://taotoken.net/api 。
你需要先拿到一个可用的 API Key。操作路径是进入控制台,在 API Keys 页面创建一个新 Key。控制台地址带上下面的参数,方便你直接跳转:
https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=console创建完 Key 之后,建议先不要急着往网关里塞,而是用最直接的方式验证一下通道是否通。你可以用模型对话页面做一次快速测试:
https://taotoken.net/model-chat?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=model-chat如果你后续要做的是长期编码或 Agent 类任务,而不是单次验证,那更适合走 Coding Plan 通道,配置方式在:
https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=coding-plan接入文档在 https://taotoken.net/doc ,API Keys 管理页在 https://taotoken.net/api-keys 。这几个地址建议先收藏,后面配置网关的 upstream 和 header 时会反复用到。
注意:Key 只放在服务端环境变量或 Secret 里,不要写进前端代码或提交到 Git。网关层做转发时,用 header 注入的方式传递,而不是把 Key 硬编码在路由规则里。
3. 可复制配置骨架:Ingress 与 APISIX 各来一份
3.1 标准 Ingress 配置骨架
先看 Ingress。下面这个 YAML 定义了一个最基础的路由:把api.demo.local/v1/chat转发到名为taotoken-proxy的 Service 的 80 端口。
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: taotoken-ingress namespace: default annotations: nginx.ingress.kubernetes.io/rewrite-target: / nginx.ingress.kubernetes.io/proxy-body-size: "10m" spec: ingressClassName: nginx rules: - host: api.demo.local http: paths: - path: /v1/chat pathType: Prefix backend: service: name: taotoken-proxy port: number: 80 tls: - hosts: - api.demo.local secretName: demo-tls这里有几个点值得展开。ingressClassName: nginx表示用 Nginx Ingress Controller 来执行。rewrite-target: /是注解,把外部路径重写后再转发给后端。proxy-body-size控制请求体大小,默认 1m,调大一点避免大 payload 被截断。
对应的 Service 和 Deployment 骨架如下,后端指向 TaoToken 的 API 地址:
apiVersion: v1 kind: Service metadata: name: taotoken-proxy spec: selector: app: taotoken-proxy ports: - port: 80 targetPort: 8080 --- apiVersion: apps/v1 kind: Deployment metadata: name: taotoken-proxy spec: replicas: 2 selector: matchLabels: app: taotoken-proxy template: metadata: labels: app: taotoken-proxy spec: containers: - name: proxy image: nginx:1.25-alpine ports: - containerPort: 8080 env: - name: TAOTOKEN_API_BASE value: "https://taotoken.net/api" - name: TAOTOKEN_API_KEY valueFrom: secretKeyRef: name: taotoken-secret key: api-keySecret 这样创建,Key 从环境变量注入,不落盘到镜像里:
kubectl create secret generic taotoken-secret \ --from-literal=api-key='你的_TaoToken_Key'Ingress 的局限在这里已经能看出来:注解是 Controller 私有的,换一个 Controller 注解可能就不生效;改配置要kubectl apply,底层 Nginx 往往要 reload,高并发下会有短暂抖动。
3.2 APISIX 配置骨架
APISIX 的配置分两层:静态的config.yaml管进程和 etcd 连接,动态的路由通过 Admin API 或apisix.yaml下发。先看config.yaml的关键片段:
apisix: node_listen: 9080 enable_ipv6: false enable_admin: true admin_key: - name: admin key: your_admin_key_here role: admin deployment: role: traditional role_traditional: config_provider: etcd etcd: host: - "http://etcd:2379" prefix: /apisix timeout: 30 plugin_attr: prometheus: export_addr: ip: 0.0.0.0 port: 9091node_listen是数据面监听端口,admin_key是 Admin API 的凭证,etcd是配置存储。APISIX 所有路由和插件配置都放 etcd,变更毫秒级同步到网关节点,不需要 reload。
路由配置可以用声明式文件apisix.yaml,适合 GitOps 场景:
routes: - uri: /v1/chat/* name: taotoken-chat methods: - POST upstream: type: roundrobin nodes: "taotoken.net:443": 1 scheme: https pass_host: node plugins: proxy-rewrite: regex_uri: - "^/v1/chat/(.*)" - "/api/$1" limit-req: rate: 20 burst: 10 rejected_code: 429 key-auth: {}这里proxy-rewrite把/v1/chat/前缀重写成/api/,limit-req做限流,key-auth开启密钥认证。插件是热插拔的,改完通过 Admin API 推送即可生效。
用 Admin API 推送路由的命令如下:
curl -X PUT http://127.0.0.1:9180/apisix/admin/routes/1 \ -H "X-API-KEY: your_admin_key_here" \ -H "Content-Type: application/json" \ -d '{ "uri": "/v1/chat/*", "methods": ["POST"], "upstream": { "type": "roundrobin", "scheme": "https", "pass_host": "node", "nodes": { "taotoken.net:443": 1 } }, "plugins": { "proxy-rewrite": { "regex_uri": ["^/v1/chat/(.*)", "/api/$1"] } } }'对比一下就很清楚:Ingress 的配置是声明式 YAML 加 Controller 私有注解,APISIX 是 etcd 驱动的动态配置加原生插件。前者简单但能力受限于 Controller,后者复杂但扩展性和动态性明显更强。
4. 验证请求与成功结果
配置写完必须验证,不然你不知道流量到底有没有按预期走。先验证 Ingress 这条链路。
假设你已经把上面的 Ingress 和 Service 都 apply 了,本地做一下 hosts 映射:
echo "127.0.0.1 api.demo.local" | sudo tee -a /etc/hosts然后用 curl 打一次请求,看返回:
curl -i -X POST http://api.demo.local/v1/chat \ -H "Content-Type: application/json" \ -H "Authorization: Bearer 你的_TaoToken_Key" \ -d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"ping"}]}'如果路由和重写都正确,你会看到 HTTP 200,响应体里是模型返回的内容。如果看到 404,大概率是rewrite-target或 path 匹配写错了;如果看到 502,检查 Service 的 selector 和 Pod 是否 Ready。
再验证 APISIX 这条链路。先确认 APISIX 数据面在跑:
curl -i http://127.0.0.1:9080/apisix/status返回{"status":"ok"}说明数据面正常。然后打一次带 key-auth 的请求,注意 APISIX 的 key-auth 默认从apikeyheader 取:
curl -i -X POST http://127.0.0.1:9080/v1/chat/completions \ -H "Content-Type: application/json" \ -H "apikey: 你的_TaoToken_Key" \ -d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"ping"}]}'成功的话同样是 200 加模型响应。这里有个容易混的点:APISIX 的key-auth插件校验的是网关自己的消费者 key,而转发到 TaoToken 时用的Authorizationheader 是另一层。你可以在proxy-rewrite的headers里补上:
proxy-rewrite: regex_uri: - "^/v1/chat/(.*)" - "/api/$1" headers: set: Authorization: "Bearer 你的_TaoToken_Key"这样网关校验一层,上游认证一层,职责分开。实测下来这种分层在多人协作时更清晰,Key 轮换也不用动路由。
5. 本篇常见错排查
5.1 Ingress 返回 404 或 503
404 通常是 path 或 host 不匹配。检查pathType是Prefix还是Exact,rewrite-target有没有把路径改没。503 多半是后端 Service 没有可用 Endpoint,用kubectl get endpoints taotoken-proxy确认一下。如果 Endpoint 是空的,说明 Pod 的 label 和 Service selector 对不上。
5.2 APISIX Admin API 报 401
X-API-KEY和config.yaml里的admin_key不一致。注意 APISIX 3.x 默认 Admin API 端口是 9180,不是 9080,别打错端口。另外admin_listen如果只绑了 127.0.0.1,从集群外访问会连不上,需要改成0.0.0.0并配合网络策略限制来源。
5.3 etcd 连接超时导致路由不生效
APISIX 启动时如果连不上 etcd,会一直重试,数据面可能起来但路由为空。检查config.yaml里的etcd.host是否可达,prefix是否和其他实例冲突。用curl http://etcd:2379/health确认 etcd 本身健康。
5.4 转发到 TaoToken 时 TLS 握手失败
APISIX upstream 的scheme要设成https,pass_host设成node,否则 SNI 可能不对。如果上游证书校验严格,确认容器内 CA 证书是最新的。Ingress 侧则检查后端 Service 是否真的支持 HTTPS,很多代理容器默认只监听 80。
5.5 限流插件把正常请求也拦了
limit-req的rate是每秒请求数,burst是突发容量。如果设成rate: 1,正常并发也会被 429。先用rate: 20, burst: 10这种宽松值跑通,再按实际压测结果收紧。APISIX 的限流是按 route 或 consumer 维度生效的,确认你绑定的维度对不对。
6. 选型建议与接入通道
把两条链路跑通之后,选型其实就变成一个边界判断问题。如果你的需求只是把几个域名和路径映射到 Service,团队又不想引入新组件,标准 Ingress 加 Nginx Ingress Controller 完全够用,配置简单,学习成本低。但如果你需要认证、限流、熔断、灰度、多协议代理,或者配置变更频繁且不能接受 reload 抖动,那 APISIX 作为 Ingress Controller 是更合适的选择,它兼容标准 Ingress 资源,同时提供 CRD 和 Admin API 做更细的控制。
无论选哪个,上游的 Key 和 API 通道都可以统一走 TaoToken。接入文档在 https://taotoken.net/doc ,API Keys 在 https://taotoken.net/api-keys ,需要长期编码或 Agent 任务的话看 Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=coding-plan 。把网关的职责和 Key 的管理职责分开,后面换网关或者加节点时,你只需要动路由,不用碰密钥。