不同集群中nginx-ingress-controller配置存在差异的原因是什么
在Ingress资源的多路由配置中统一使用pathType: ImplementationSpecific,两个集群部署的nginx-ingress-controller版本完全一致,且所有Ingress资源均未添加use-regex注解,最终生成的nginx location规则存在明显差异:
# 集群1 生成规则(符合预期) location ~* /some/route/(?!one|two|three).{1,} # 集群2 生成规则(异常) location /some/route/(?!one|two|three).{1,}
集群2的规则缺失正则匹配修饰符~*,路径中携带的负向前瞻正则语法被当成普通字符串做前缀匹配,路由完全失效。按照官方文档描述,ImplementationSpecific的匹配行为由IngressClass绑定的控制器逻辑决定,但常规Ingress层面的配置排查找不到对应差异参数。
配置差异来自nginx-ingress-controller的全局正则开关配置不一致,和Ingress资源本身的配置没有关系:
nginx-ingress-controller处理ImplementationSpecific类型路径时,是否自动识别路径中的正则语法、是否自动给location块添加正则修饰符,完全由全局配置项控制,和Ingress上的注解无关:
- 全局配置开启正则匹配时(对应启动参数
--enable-regex-matching=true,或ConfigMapnginx-configuration中enable-regex: "true"),控制器会自动检测路径中的正则语法,命中正则规则的路径会自动添加~*大小写不敏感正则修饰符,也就是集群1的正常表现。 - 全局配置关闭正则匹配时(该配置在部分自定义部署包、旧版本升级场景下默认值为false),控制器不会解析路径中的任何正则语法,会直接把路径字符串作为普通前缀匹配规则写入nginx配置,不会添加任何正则修饰符,也就是集群2的异常表现。
很多场景下运维会直接复用不同来源的helm values部署ingress-nginx,哪怕镜像版本完全一致,只要部署时的全局参数、关联ConfigMap配置有差异,就会出现同版本控制器生成规则完全不同的情况,这类全局配置不属于Ingress、IngressClass资源的可配置字段,只在控制器部署层生效,因此排查业务侧Ingress配置时找不到差异点。
二选一即可:
- 全局修复:给异常集群的nginx-ingress-controller添加
--enable-regex-matching=true启动参数,或在nginx-configurationConfigMap的data段增加enable-regex: "true"配置,等待控制器重载后规则会自动恢复正常。 - 单Ingress修复:如果不想修改全局配置,可以直接给对应Ingress资源添加注解
nginx.ingress.kubernetes.io/use-regex: "true",该注解优先级高于全局开关,会强制控制器解析该Ingress下所有路径的正则语法,无需重启控制器即可生效。
内容的提问来源于stack exchange,提问作者Gabriel Stein

