升级 Kubernetes 1.22 后 ingress-nginx 现有 Ingress 不生效时如何配置 IngressClass 与 ingressClassName
升级 Kubernetes 1.22 后 ingress-nginx 现有 Ingress 不生效时如何配置 IngressClass 与 ingressClassName【免费下载链接】ingress-nginxIngress NGINX Controller for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/in/ingress-nginx如果你的集群之前运行在 Kubernetes 1.22 以下版本且已通过 ingress-nginx 暴露过 Ingress升级到 1.22 及以后版本后可能出现一种典型现象已有的 Ingress 对象不再被 controller 处理站点访问不生效。原因是两件事叠加从 Kubernetes 1.22 起Ingress API 只能通过稳定的networking.k8s.io/v1版本访问extensions/v1beta1和networking.k8s.io/v1beta1等旧版本被移除同时从 1.0.0 版本开始ingress-nginx controller 要求集群中存在 IngressClass 对象而旧版集群里大量 Ingress 既没有spec.ingressClassName字段也依赖已被废弃的kubernetes.io/ingress.class注解。这篇文章给出在升级后恢复 Ingress 生效的配置路径依据是 k8s-122 迁移 FAQ 与 项目 FAQ。先确认你属于哪种场景配置方式取决于集群里 ingress-nginx controller 的数量集群中只有一个 ingress-nginx controller需要让 controller 识别没有指定类的旧 Ingress主路径是给 IngressClass 设置默认类注解或给 Ingress 补spec.ingressClassName字段。集群中有多套 controller需要为每套 controller 创建独立的 IngressClass并用--controller-class让每套 controller 只监听属于自己的类。可以用kubectl get ingressclass -A查看当前集群已有哪些 IngressClassIngressClass 是集群级资源再结合各 controller Pod 的启动参数判断归属。单个 controller 的配置主路径第一步确保存在正确的 IngressClass文档推荐创建一个带默认类注解的 IngressClass--- apiVersion: networking.k8s.io/v1 kind: IngressClass metadata: labels: app.kubernetes.io/component: controller name: nginx annotations: ingressclass.kubernetes.io/is-default-class: true spec: controller: k8s.io/ingress-nginx这里spec.controller: k8s.io/ingress-nginx与 controller 启动参数--controller-class的值必须一致。使用 Helm chart 安装时chart 默认就会创建该对象values.yaml 中controller.ingressClassResource.enabled默认为truename默认为nginxcontrollerValue默认为k8s.io/ingress-nginx。而default默认是false即默认安装不会加is-default-class注解如果希望新建的、未指定类的 Ingress 自动归到这个类需要在 values 中设置.controller.ingressClassResource.default: true对应模板 controller-ingressclass.yaml 会在 IngressClass 上写入ingressclass.kubernetes.io/is-default-class: true注解。第二步让存量 Ingress 被 controller 接管对升级前就存在、且没有设置类的 Ingress 对象文档给出三种可选做法任选其一也可组合手动补字段在存量 Ingress 清单中设置spec.ingressClassName例如apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: example # 替换为你的 Ingress 名 namespace: default # 替换为你的命名空间 spec: ingressClassName: nginx # 值对应 IngressClass 的 metadata.name # 其余 rules/tls 等配置保持原有内容注意优先级规则.spec.ingressClassName字段优先于废弃注解kubernetes.io/ingress.class当两者同时存在且取值不同时controller 可能发出警告。先设置默认类注解再重建先给 IngressClass 加上is-default-class: true注解然后重建re-create这些 Ingress 对象。启动参数方式给 controller 加上--watch-ingress-without-classtrue让它接管没有ingressClassName字段的 Ingress。使用 Helm 时在 values 中设置.controller.watchIngressWithoutClass: truevalues.yaml 中该项默认为false。chart 的 _params.tpl 会据此把--watch-ingress-without-classtrue注入 controller 容器的args最终 Pod 中的参数形如args: - /nginx-ingress-controller - --watch-ingress-without-classtrue - --controller-classk8s.io/ingress-nginx # ...如果集群中有大量未配置类的 Ingress文档建议直接用这个 flag 的方式避免逐个改清单。多个 controller 时的配置方式多套 controller 共存时需要创建多个 IngressClass关键是让每个 IngressClass 的spec.controller与对应 controller 的--controller-class参数严格相等。文档中的例子IngressClassingress-nginx-onespec.controller为example.com/ingress-nginx1IngressClassingress-nginx-twospec.controller为example.com/ingress-nginx2部署 controller 时分别把--controller-class设为相同值。这样一个ingressClassName指向ingress-nginx-two的 Ingress 只会由监听example.com/ingress-nginx2的那套 controller 提供服务另一套会忽略它。私有环境下 controller 值也可以不带/例如ingress-nginx1。项目 FAQ 给出了用 Helm 在第二个命名空间加装一套 controller 的完整命令kubectl create namespace ingress-nginx-2 helm install ingress-nginx-2 ingress-nginx/ingress-nginx \ --namespace ingress-nginx-2 \ --set controller.ingressClassResource.namenginx-two \ --set controller.ingressClassnginx-two \ --set controller.ingressClassResource.controllerValueexample.com/ingress-nginx-2 \ --set controller.ingressClassResource.enabledtrue \ --set controller.ingressClassByNametrue其中controller.ingressClassResource.name用于创建 IngressClass 对象controller.ingressClass用于修改 controller Deployment 的启动参数。如果要装第三套重复上述步骤并替换名字即可。如果多套 controller 必须装在同一个命名空间则还要为每套指定不同的--set controller.electionID例如nginx-two-leader否则会因 leader 选举冲突而互相干扰。还有一个需要留意的限制如果两套 controller 都开着--watch-ingress-without-classtrue它们都会接管未指定类的 Ingress很可能发生冲突一套开、另一套保持false则是文档明确支持的配置。结果验证与日志排查配置完成后按以下方式核对确认 IngressClass 存在且类名、controller 值正确kubectl get ingressclass查看名称如nginx文档中也给出了参考命令kubectl explain ingressclass与kubectl explain ingress.spec.ingressClassName可用于核对字段语义。确认 controller 启动参数查看 controller Pod 的args应包含--controller-class...值与 IngressClass 的spec.controller一致启用了对无类 Ingress 的接管时还应看到--watch-ingress-without-classtrue。Helm chart 安装后的 NOTES.txt 也会提示创建 Ingress 时使用的ingressClassName取值即controller.ingressClassResource.name的值。确认存量 Ingress 已被接管多 controller 场景下文档描述的判定行为是——只有--controller-class与 IngressClassspec.controller匹配的 controller 才会处理该对象其余 controller 会忽略它单 controller 场景下设置了默认类注解后未指定类的新 Ingress 会被自动分配到该类。检查 controller 日志中的典型报错如果日志里出现ingress class annotation is not equal to the expected by Ingress Controller并且同一行信息带有具体 Ingress 资源名文档指出这通常意味着清单里还在使用废弃注解kubernetes.io/ingress.class。虽然 controller 目前仍理解该注解升级前已在用注解的多 controller 用户应该继续工作但强烈建议测试推荐做法是改用spec.ingressClassName字段迁移掉该注解。限制与注意事项IngressClass 一经创建是不可变的chart 注释明确 IngressClasses are immutable and cannot be changed after creation命名或spec.controller写错时不要指望原地修改需要删除重建并同步调整 controller 参数。controller.ingressClassByNamechart values默认false控制 controller 是否除按spec.controller外还按名字匹配 IngressClass多实例 FAQ 中的安装命令把它设为true单实例场景按文档默认值使用即可。本文的操作路径基于 k8s-122 迁移 FAQ 与 项目 FAQ如需逐项核对启动参数含义可参考 CLI 参数文档 中--controller-class、--ingress-class-by-name、--watch-ingress-without-class的说明。【免费下载链接】ingress-nginxIngress NGINX Controller for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/in/ingress-nginx创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考