资讯动态

在 Kubernetes 中运行多个 Ingress 控制器:ingress-nginx 的 IngressClass 隔离部署指南

发布时间:2026/9/14 6:50:19 来源:尧图企业网站定制
在 Kubernetes 中运行多个 Ingress 控制器ingress-nginx 的 IngressClass 隔离部署指南【免费下载链接】ingress-nginxIngress NGINX Controller for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/in/ingress-nginx本篇技术指南聚焦于 ingress-nginx 项目中多 Ingress 控制器共存的经典难题系统讲解通过 Kubernetes 原生IngressClass机制推荐方案与已弃用的kubernetes.io/ingress.class注解兼容方案将多个 Ingress 控制器如内部/外部 ingress-nginx、GCE 等隔离共存、各司其职的完整部署方法与参数配置。读完本文你将掌握--controller-class、--ingress-class、--election-id等关键启动参数的作用原理能够安全地在一个集群中同时运行两套甚至多套 ingress-nginx 控制器并理解其底层判类逻辑依据 pkg/flags/flags.go 与 internal/ingress/controller/ingressclass/ingressclass.go 的源码实现。问题的根源多个控制器互相抢 Ingress在默认情况下如果在一个集群中部署多个 Ingress 控制器例如同时部署ingress-nginx与gce由于它们都没有经过任何类隔离配置所有控制器都会同时监听集群中的全部 Ingress 对象并竞相更新 Ingress 的status.loadBalancer字段产生令人困惑的互相覆盖、反复改写现象例如 A 控制器写入自己的负载均衡地址B 控制器随即又改写成自己的。这是多控制器共存必须首先解决的问题。为解决这一问题官方推荐使用 Kubernetes 的IngressClass机制。而传统的kubernetes.io/ingress.class注解不再被推荐使用[IN DEPRECATION]见 pkg/flags/flags.go 中的参数注释因为它未来可能被弃用更优的做法是使用 Ingress 规范中的字段spec.ingressClassName。需要注意一个例外场景当通过 Helm 以scope.enabled限制控制器只监听某个命名空间方式部署时IngressClass 资源中的spec.controller字段不会被用于判类此时判定逻辑另走命名空间作用域路径scope配置见 charts/ingress-nginx/values.yaml。方案一使用 IngressClass 隔离多个控制器推荐如果所有 Ingress 控制器都支持 IngressClass例如多个 ingress-nginx v1.0 实例可以部署两套控制器分别授权它们管理两个不同的 IngressClass然后通过ingressClassName字段在 Ingress 上显式选择由哪套控制器接管。第一步为每个控制器分配不同的启动参数在每套控制器的 Deployment / StatefulSet 中确保--controller-class与--ingress-class设置为互不相同的值。如果新部署的控制器所在命名空间已经存在一个或多个 ingress-nginx 控制器还必须为新实例指定一个唯一的--election-id避免多个实例共用同一个 Leader Election 标识导致状态更新异常。# ingress-nginx Deployment/Statefulset spec: template: spec: containers: - name: ingress-nginx-internal-controller args: - /nginx-ingress-controller - --election-idingress-controller-leader - --controller-classk8s.io/internal-ingress-nginx - --ingress-classk8s.io/internal-nginx ...参数含义默认值均可在 pkg/flags/flags.go 中确认启动参数默认值作用--controller-classk8s.io/ingress-nginx本控制器满足的 IngressClassspec.controller取值用于匹配 Ingress 引用的 IngressClass 资源--ingress-classnginx已弃用路径本控制器满足的注解类名对应kubernetes.io/ingress.class注解值--election-idingress-controller-leader用于 Ingress 状态更新的 Leader Election 标识多实例共存时必须唯一第二步创建与--controller-class对应的 IngressClass 资源IngressClass 的spec.controller字段值必须与控制器启动参数--controller-class完全一致这样该控制器才会接管引用此 IngressClass 的 Ingress# ingress-nginx IngressClass apiVersion: networking.k8s.io/v1 kind: IngressClass metadata: name: internal-nginx spec: controller: k8s.io/internal-ingress-nginx ...第三步在 Ingress 中通过ingressClassName引用目标类apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-ingress spec: ingressClassName: internal-nginx ...使用 Helm 安装时的等价配置如果通过 Helm Chart 安装对应 Chart 位置 charts/ingress-nginx使用以下 values 片段即可达到与上述手工配置相同的效果controller: electionID: ingress-controller-leader ingressClass: internal-nginx # default: nginx ingressClassResource: name: internal-nginx # default: nginx enabled: true default: false controllerValue: k8s.io/internal-ingress-nginx # default: k8s.io/ingress-nginx这里需要特别说明 Chart 中两个易混淆字段的关系依据 charts/ingress-nginx/values.yaml 的注释ingressClassResource.controllerValue创建 IngressClass 资源时写入spec.controller的值同时也会作为--controller-class参数传入控制器ingressClassResource.name创建的 IngressClass 资源的名称ingressClass向后兼容ingress.class注解时使用的类名默认nginx。判类算法为优先考虑ingressClassName字段若不存在再回退查找ingress.class注解ingressClassResource.default: true将此类标记为集群默认 IngressClass使未指定ingressClassName的 Ingress 在创建时被自动分配但若存在多个默认类Ingress 的创建会被拒绝。重要无类注解 Ingress 的处理规则在多控制器场景下必须理解未设置类的 Ingress 会被谁处理这一点直接决定了隔离是否生效当运行多个 ingress-nginx 控制器时只有使用了默认--controller-class即k8s.io/ingress-nginx的控制器才会处理未设置类注解的 Ingress否则类注解/类字段变成必填项对应internal/ingress/controller/ingressclass/ingressclass.go中的Configuration结构及其常量DefaultControllerName k8s.io/ingress-nginx、DefaultAnnotationValue nginx当--controller-class保持默认值k8s.io/ingress-nginx时该控制器会同时监控无类注解的 Ingress与类注解设置为nginx的 Ingress若希望控制器只接管特定类的 Ingress就必须把--controller-class设为非默认值如上述示例中的k8s.io/internal-ingress-nginx从而确保它仅满足指定类别的 Ingress。从源码实现看判类逻辑在 internal/ingress/controller/store/store.go 中收口当启用--watch-ingress-without-class对应 Helm 的controller.watchIngressWithoutClass默认false见 values.yaml时无类 Ingress 会以_作为通配符名称被接受否则将返回ingress does not contain a valid IngressClass错误即该 Ingress 不被任何严格按类隔离的控制器接管。方案二使用 kubernetes.io/ingress.class 注解已弃用仅作兼容如果同时运行的多个 Ingress 控制器中有一个或多个尚不支持 IngressClass 机制例如较老版本的 GCE 控制器则必须退回到注解方式在所有希望由 ingress-nginx 接管的 Ingress 上显式标注kubernetes.io/ingress.class: nginx。例如下面的 Ingress 会命中 GCE 控制器从而被 Ingress-NGINX 控制器主动忽略metadata: name: foo annotations: kubernetes.io/ingress.class: gce而下面的 Ingress 则会命中 Ingress-NGINX 控制器使 GCE 控制器忽略它metadata: name: foo annotations: kubernetes.io/ingress.class: nginx自定义注解类名默认的类名nginx可以通过--ingress-class启动参数改为任意其他值spec: template: spec: containers: - name: ingress-nginx-internal-controller args: - /nginx-ingress-controller - --ingress-classinternal-nginx然后在 Ingress 上设置与之对应的注解metadata: name: foo annotations: kubernetes.io/ingress.class: internal-nginx注解方式的关键行为注解值不匹配任何有效类 ⇒ 控制器忽略该 Ingress将注解设置为任何与有效 ingress class 不匹配的值都会强制 Ingress-NGINX 控制器忽略该 Ingress单控制器场景下的用法如果你只运行一个 Ingress-NGINX 控制器但仍希望与其他 Ingress 控制器同时使用可将注解设置为除nginx或空字符串以外的任意值即可让 NGINX 控制器跳过该 Ingress该注解方式本质上依赖 internal/ingress/controller/ingressclass/ingressclass.go 中定义的注解键IngressKey kubernetes.io/ingress.class与默认值DefaultAnnotationValue nginx其注解参数在 pkg/flags/flags.go 中被明确标注为[IN DEPRECATION]且注解判定优先级低于--controller-class源码注释原文The parameter --controller-class has precedence over this.。补充辅助判定参数与验证手段相关启动参数速查除上述三个核心参数外多控制器隔离场景下还常涉及以下参数完整参数表见 docs/user-guide/cli-arguments.md参数默认值说明--watch-ingress-without-classfalse是否额外监控不带 IngressClass / 注解的 Ingress--ingress-class-by-namefalse是否除spec.controller外再按 IngressClass 的.metadata.name进行匹配--disable-leader-electionfalse禁用 Leader Election多实例共存时谨慎使用测试用例佐证仓库在 test/e2e/settings/ingress_class.go 中提供了针对 IngressClass 行为的端到端测试覆盖无类 Ingress 处理、WatchWithoutClass等场景同时在 internal/ingress/controller/store/store_test.go 中通过单元测试验证了WatchWithoutClass: true/false两种配置下 Ingress 过滤逻辑的差异可作为理解判类行为与回归验证的参考。总结与最佳实践场景推荐做法所有控制器均支持 IngressClass如同为 ingress-nginx v1.0使用--controller-classingressClassName隔离避免使用注解同命名空间部署第二个 ingress-nginx 控制器额外设置唯一的--election-id存在不支持 IngressClass 的旧控制器如 GCE使用kubernetes.io/ingress.class注解隔离希望某个控制器只处理特定类将--controller-class设为非默认值并配套创建对应 IngressClass单控制器但想与其他控制器共存在被忽略的 Ingress 上设置非nginx/ 非空字符串的类注解限制控制器仅监听单个命名空间开启scope.enabled注意此时 IngressClass 的spec.controller不参与判类核心结论可以概括为多控制器共存的本质是类隔离 选举隔离——类隔离决定哪个控制器接管哪个 IngressIngressClass 优先、注解回退选举隔离唯一的--election-id保证同一状态更新不被多个控制器互相覆盖。在部署时优先采用 IngressClass 机制并始终为非默认控制器使用非默认的--controller-class值即可获得清晰、可预期的多控制器行为。【免费下载链接】ingress-nginxIngress NGINX Controller for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/in/ingress-nginx创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价