AKS中Nginx Ingress如何区分引用公、私网LoadBalancer?
当你在AKS中部署了同时带公网和私网LoadBalancer的Nginx Ingress Controller后,无需额外部署多个控制器,只需通过特定注解或IngressClass来区分Ingress关联的LB类型,即可满足你的两种业务场景:
1. 场景1:服务同时通过公网和私网LB访问
这种场景下无需额外添加特殊注解,只需确保Ingress关联到你的Nginx Ingress Controller即可。注意现在推荐使用spec.ingressClassName替代已弃用的kubernetes.io/ingress.class注解:
修改后的Ingress配置示例:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: some-service-public-private namespace: shared labels: app.kubernetes.io/component: udp app.kubernetes.io/instance: some-service app.kubernetes.io/name: some-service annotations: cert-manager.io/cluster-issuer: letsencrypt-dev clusterIssuerEnv: dev meta.helm.sh/release-name: some-service meta.helm.sh/release-namespace: shared kubernetes.io/tls-acme: "true" spec: ingressClassName: nginx # 替换原有的kubernetes.io/ingress.class注解 tls: - hosts: - some-service.my-domain.com secretName: wildcard.x.my-domain-tls-some-service rules: - host: some-service.my-domain.com http: paths: - path: / pathType: Prefix backend: service: name: some-service port: number: 12201
此时公网LB(x.x.x.x)和私网LB(y.y.y.y)都会转发该Ingress的流量,服务可通过两个LB访问。
2. 场景2:服务仅通过私网LB访问
给Ingress添加注解nginx.ingress.kubernetes.io/internal-ingress: "true",控制器会仅将该Ingress的路由规则绑定到私网LB对应的Service,公网LB不会处理这个Ingress的请求:
配置示例:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: some-service-private-only namespace: shared labels: app.kubernetes.io/component: udp app.kubernetes.io/instance: some-service app.kubernetes.io/name: some-service annotations: cert-manager.io/cluster-issuer: letsencrypt-dev clusterIssuerEnv: dev nginx.ingress.kubernetes.io/internal-ingress: "true" # 关键注解 meta.helm.sh/release-name: some-service meta.helm.sh/release-namespace: shared kubernetes.io/tls-acme: "true" spec: ingressClassName: nginx tls: - hosts: - some-service-internal.my-domain.com secretName: wildcard.x.my-domain-tls-some-service-internal rules: - host: some-service-internal.my-domain.com http: paths: - path: / pathType: Prefix backend: service: name: some-service port: number: 12201
3. 场景3:服务仅通过公网LB访问
若需明确限制仅公网LB可访问,可添加注解nginx.ingress.kubernetes.io/internal-ingress: "false"(默认即为false,不加也可),确保Ingress规则仅应用到公网LB:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: some-service-public-only namespace: shared labels: app.kubernetes.io/component: udp app.kubernetes.io/instance: some-service app.kubernetes.io/name: some-service annotations: cert-manager.io/cluster-issuer: letsencrypt-dev clusterIssuerEnv: dev nginx.ingress.kubernetes.io/internal-ingress: "false" # 明确指定仅公网LB生效 meta.helm.sh/release-name: some-service meta.helm.sh/release-namespace: shared kubernetes.io/tls-acme: "true" spec: ingressClassName: nginx tls: - hosts: - some-service.my-domain.com secretName: wildcard.x.my-domain-tls-some-service rules: - host: some-service.my-domain.com http: paths: - path: / pathType: Prefix backend: service: name: some-service port: number: 12201
原理说明
你部署的双LB Nginx Ingress Controller本质是同一个控制器实例管理两个Service资源:
- 一个默认的公网LoadBalancer Service(对应IP x.x.x.x)
- 一个启用
internal.enabled: true后生成的私网LoadBalancer Service(对应IP y.y.y.y)
控制器通过nginx.ingress.kubernetes.io/internal-ingress注解判断Ingress规则需要绑定到哪个Service:
- 注解值为
true:仅绑定私网Service - 注解值为
false或无该注解:绑定公网+私网Service(同时生效)
另外建议将原有kubernetes.io/ingress.class注解替换为spec.ingressClassName字段,这是Kubernetes v1版本Ingress资源的标准配置方式,原注解已被标记为弃用。
内容的提问来源于stack exchange,提问作者Nick

