必须使用 networking.k8s.io/v1 版本创建 Ingress,client-go ≥ v0.22.0,结构体字段首字母大写,更新需先 Get 获取 ResourceVersion 再 Modify 并全量 Update,ingressClassName 和 service.name 大小写敏感且须同 namespace,pathType 需显式设置为 Prefix 或 Exact。

用 client-go 创建 Ingress 必须指定 networking.k8s.io/v1
直接 new 一个 networkingv1.Ingress 结构体却用错 API 版本,是 90% 的“创建失败”根源。Kubernetes ≥ 1.22 已彻底移除 extensions/v1beta1,继续用它会报 the server could not find the requested resource 或静默忽略字段。
关键点:
-
apiVersion必须写成"networking.k8s.io/v1",不是"extensions/v1beta1"或"networking.k8s.io/v1beta1" - client-go 依赖版本必须 ≥
v0.22.0,否则NetworkingV1().Ingresses()接口不可用 - 结构体字段名首字母必须大写(如
Spec、Rules),小写(如spec)会导致序列化后字段为空 -
ObjectMeta.Name和ObjectMeta.Namespace都不能省略,空 namespace 字符串""会被当 default,但显式写"default"更安全
更新 Ingress 时 ResourceVersion 缺失必报 409 Conflict
很多人以为 Update() 是“局部更新”,结果 new 一个新对象就调用,立刻返回 409 Conflict。Ingress 的 Update 是全量替换语义,不是 patch。
正确流程只有三步:
- 先调用
Get()拉取当前资源,拿到完整的ResourceVersion - 只修改你需要的字段:比如往
Spec.Rules切片里append一条新 host 规则,或改Spec.IngressClassName - 把整个对象(含原始
ResourceVersion)传给Update()
常见错误:直接覆盖 Spec 字段导致 TLS、Annotations、pathType 全丢;或漏掉 ResourceVersion 导致冲突。
host 和 service.name 大小写敏感且必须同 namespace
Ingress 更新成功不代表路由通了。大量 503/404 来自后端 Service 名写错——它不跨 namespace,也不自动 lowercase。
检查要点:
-
spec.rules[].host是纯字符串匹配,不查 DNS;本地测试用curl -H "Host: example.com" http://INGRESS_IP/绕过 DNS -
spec.rules[].http.paths[].backend.service.name必须和Service.metadata.name**逐字符一致**(包括大小写),且两者在同一个 namespace 下 - 用
kubectl get svc -n确认 Service 存在;用kubectl get ingress -n看生成对象是否真包含你写的 host 和 service.name-o yaml - 如果 Service 是 headless 或 ClusterIP 类型但没 endpoint,Ingress Controller 会标记为 unhealthy,流量被拒绝
pathType 不设默认值容易踩 nginx-ingress 行为坑
Kubernetes v1 默认 pathType 是 "ImplementationSpecific",但 nginx-ingress 实际按 "Prefix" 解释。写成 /api 会匹配 /api/users,但不会匹配 /apis;若你想要精确匹配,必须显式设置。
正确写法:
- 用常量而非字符串字面量:
pathType := networkingv1.PathTypeExact(不是"Exact") - 路径末尾斜杠影响行为:
Path: "/api"+PathType: Exact只匹配/api,不匹配/api/ - nginx-ingress 的
rewrite-targetannotation 仅对Prefix生效,Exact下无效 - traefik 等其他 controller 对
pathType支持更严格,不设或设错直接拒收规则
最易忽略的是:IngressRule 里每个 HTTPIngressPath 都要单独设 PathType,不能只设一个。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











