You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kubernetes多Ingress Controller抢占Ingress地址问题求助

问题解决:Ingress Controller抢占所有Ingress地址的修复

基础设施背景

我的Kubernetes(K3s)集群包含4个节点:

k3s-server location=home   (VM) 主要用于etcd复制
k3s-agent  location=home   (VM) 运行大多数Pod
mercury    location=home   (RPI4) 重要Pod的备份节点
moon       location=cloud  (Cloud VM) 在公有云中运行特定工作负载

我在两个命名空间中部署了两个不同的ingress-nginx Helm实例:

  • 家庭本地服务用:ingressClassName=nginx,loadBalancerIP: 192.168.113.230,运行在nginx-ingres-home命名空间
  • 云环境用:ingressClassName=nginx-cloud,loadBalancerIP: 91.x.x.x,运行在nginx-ingress-cloud命名空间

问题现象

定义了多个使用不同IngressClass的Ingress资源,但执行kubectl get ingress -A发现所有Ingress的ADDRESS字段始终显示其中一个控制器的地址,且会周期性切换:

NAMESPACE              NAME                   CLASS         HOSTS                        ADDRESS           PORTS     AGE
kubernetes-dashboard   kubernetes-dashboard   nginx         k3s.local.example.com        192.168.113.230   80, 443   4d3h
longhorn-system        longhorn-ingress       nginx         longhorn.local.example.com   192.168.113.230   80, 443   10d
mailu                  mailu                  nginx-cloud   mail.example.com             192.168.113.230   80, 443   2d23h
pihole                 pihole                 nginx         dns.local.example.com        192.168.113.230   80, 443   10d
ubiquiti               unifi-web-interface     nginx         unifi.local.example.com       192.168.113.230   80, 443   24h

nginx-ingress-home日志显示控制器每隔1分钟就会更新所有Ingress的地址:

I0510 19:46:12.087815       7 status.go:300] "updating Ingress status" namespace="pihole" ingress="pihole" currentValue=[{IP:91.x.x.x Hostname: Ports:[]}] newValue=[{IP:192.168.113.230 Hostname: Ports:[]}]
I0510 19:46:12.087857       7 status.go:300] "updating Ingress status" namespace="ubiquiti" ingress="unifi-web-interface" currentValue=[{IP:91.x.x.x Hostname: Ports:[]}] newValue=[{IP:192.168.113.230 Hostname: Ports:[]}]
I0510 19:46:12.088485       7 status.go:300] "updating Ingress status" namespace="mailu" ingress="mailu" currentValue=[{IP:91.x.x.x Hostname: Ports:[]}] newValue=[{IP:192.168.113.230 Hostname: Ports:[]}]
I0510 19:46:12.088782       7 status.go:300] "updating Ingress status" namespace="longhorn-system" ingress="longhorn-ingress" currentValue=[{IP:91.x.x.x Hostname: Ports:[]}] newValue=[{IP:192.168.113.230 Hostname: Ports:[]}]
I0510 19:46:12.090051       7 status.go:300] "updating Ingress status" namespace="kubernetes-dashboard" ingress="kubernetes-dashboard" currentValue=[{IP:91.x.x.x Hostname: Ports:[]}] newValue=[{IP:192.168.113.230 Hostname: Ports:[]}]

nginx-ingress-cloud也会执行相同操作,将地址替换为91.x.x.x。需要让每个控制器只更新匹配自身IngressClass的Ingress资源。

配置信息

nginx-ingress-home的Helm配置值

controller:
  ingressClass: "nginx"
  ingressClassResource:
    name: nginx
    enabled: yes
    default: yes
  service:
    type: "LoadBalancer"
    loadBalancerIP: 192.168.113.230
  nodeSelector:
    location: home
  tolerations: #允许在备份节点上运行
    - key: "backup"
      operator: "Equal"
      value: "true"
      effect: "NoSchedule"
  affinity: #优先调度到标记为type=power的节点
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 1
          preference:
            matchExpressions:
              - key: type
                operator: In
                values:
                  - power

nginx-ingress-cloud的Helm配置值

controller:
  ingressClass: "nginx-cloud"
  ingressClassResource:
    name: nginx-cloud
    enabled: yes
    default: no
  service:
    type: "LoadBalancer"
    loadBalancerIP: 91.x.x.x
  nodeSelector:
    location: cloud

家庭环境Ingress示例(Kubernetes Dashboard)

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - k3s.local.example.com
      secretName: kubernetes-dashboard-tls
  rules:
    - host: k3s.local.example.com
      http:
        paths:
          - backend:
              service:
                name: kubernetes-dashboard
                port:
                  number: 443

            path: /
            pathType: Prefix

解决方案

问题出在两个Ingress Controller默认会处理所有Ingress资源,哪怕这些资源的IngressClass不匹配。需要给每个控制器添加IngressClass过滤规则,让它们只关注对应IngressClass的资源。

1. 更新Helm配置,添加watchIngressClassOnly参数

在每个Ingress Controller的Helm values中,加入controller.watchIngressClassOnly: true,这个参数会让控制器只处理与自身配置的ingressClass匹配的Ingress资源。

更新后的nginx-ingress-home配置

controller:
  ingressClass: "nginx"
  ingressClassResource:
    name: nginx
    enabled: yes
    default: yes
  watchIngressClassOnly: true # 新增过滤规则
  # 其他原有配置保持不变

更新后的nginx-ingress-cloud配置

controller:
  ingressClass: "nginx-cloud"
  ingressClassResource:
    name: nginx-cloud
    enabled: yes
    default: no
  watchIngressClassOnly: true # 新增过滤规则
  # 其他原有配置保持不变

2. 重新部署Helm实例

执行Helm upgrade命令更新两个控制器:

# 更新家庭环境控制器
helm upgrade nginx-ingress-home ingress-nginx/ingress-nginx -n nginx-ingres-home -f home-values.yaml

# 更新云环境控制器
helm upgrade nginx-ingress-cloud ingress-nginx/ingress-nginx -n nginx-ingress-cloud -f cloud-values.yaml

3. 验证效果

等待控制器重启后,执行kubectl get ingress -A,每个Ingress的ADDRESS应该会显示对应IngressClass控制器的IP,且不会再出现周期性切换的情况。同时查看控制器日志,应该只会看到匹配自身IngressClass的Ingress状态更新。


内容的提问来源于stack exchange,提问作者Florian7843

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 14:18:01