为何GKE集群中基于Contour的配置会出现2个可用外部IP?
嘿,我来帮你拆解下这个问题~ 结合你用Contour替代默认Ingress控制器的场景,大概率是以下几个原因导致的:
1. 两个Ingress控制器同时在集群中工作
GKE默认自带一个名为glbc(Google Load Balancer Controller)的Ingress控制器,当你部署Contour后,如果没有明确指定Ingress资源由Contour处理,那么glbc和Contour会同时盯上你创建的Ingress对象,各自创建一个外部负载均衡器,自然就产生了两个外部IP。
验证方法:
- 查看kube-system命名空间下的控制器Pod:
如果两者都存在,说明双控制器在运行。kubectl get pods -n kube-system | grep -E "glbc|contour"
解决办法:
在你的Ingress资源中添加注解,明确指定由Contour接管:
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: helloworld-ingress annotations: kubernetes.io/ingress.class: contour # 关键注解 spec: rules: - host: your-domain.com http: paths: - path: / backend: serviceName: helloworld-nodeport servicePort: 80
2. Contour部署时的双重暴露配置
有些Contour部署教程会同时配置两种暴露Envoy的方式:比如先给Envoy创建LoadBalancer类型的Service,同时又用Ingress资源来路由流量。这种情况下,Envoy的LoadBalancer会分配一个外部IP,而如果Ingress又被默认控制器处理,就会再生成一个IP。
验证方法:
查看集群中的Service:
kubectl get svc
如果看到两个LoadBalancer类型的Service(一个是Envoy的,一个是GKE默认Ingress创建的),就符合这个情况。
解决办法:
调整Contour的部署配置,让Envoy只通过一种方式暴露:
- 如果用Ingress路由,把Envoy的Service改成
NodePort或ClusterIP类型,只通过Ingress提供外部访问入口; - 如果直接用Envoy的LoadBalancer IP访问,就不需要再创建Ingress资源。
3. 检查你的资源关联是否正确
你提到用NodePort Service暴露helloworld Pod,再通过Ingress暴露。要确认Ingress的backend是指向这个NodePort Service,并且Ingress的ingress.class注解正确,避免默认控制器误接管。
内容的提问来源于stack exchange,提问作者James Healy

