问题描述
我想要完成的事情
我正在尝试将外部 HTTPS (L7) 负载平衡器与公开为区域网络端点组 (NEG) 的 Nginx Ingress 连接。我的 Kubernetes 集群(在 GKE 中)包含几个我作为 ClusterIP 服务公开的 Web 应用程序部署。
我知道 Nginx Ingress 对象可以直接暴露为 TCP 负载均衡器。但是,这不是我想要的。相反,在我的架构中,我想使用外部 HTTPS 负载平衡器对 HTTPS 请求进行负载平衡。我希望此外部负载平衡器提供 SSL/TLS 终止并将 HTTP 请求转发到我的 Ingress 资源。
理想的架构应该是这样的:
HTTPS 请求 --> 外部 HTTPS 负载均衡器 --> HTTP 请求 --> Nginx Ingress 区域 NEG --> 适当的 Web 应用程序
我想添加来自 Nginx Ingress 的区域 NEG 作为 HTTPS 负载平衡器的后端。这就是事情分崩离析的地方。
我做了什么
Nginx Ingress 配置
我使用来自官方 kubernetes/ingress-Nginx 项目的默认 Nginx Ingress 配置。具体来说,这个 YAML 文件 https://github.com/kubernetes/ingress-nginx/blob/master/deploy/static/provider/cloud/deploy.yaml。 请注意,我已将 Nginx 控制器服务部分更改如下:
-
添加了 NEG 注释
-
将服务类型从
LoadBalancer
更改为ClusterIP
。
# Source: ingress-Nginx/templates/controller-service.yaml
apiVersion: v1
kind: Service
Metadata:
annotations:
# added NEG annotation
cloud.google.com/neg: '{"exposed_ports": {"80":{"name": "Nginx_NEG"}}}'
labels:
helm.sh/chart: ingress-Nginx-3.30.0
app.kubernetes.io/name: ingress-Nginx
app.kubernetes.io/instance: ingress-Nginx
app.kubernetes.io/version: 0.46.0
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: controller
name: ingress-Nginx-controller
namespace: ingress-Nginx
spec:
type: ClusterIP
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
- name: https
port: 443
protocol: TCP
targetPort: https
selector:
app.kubernetes.io/name: ingress-Nginx
app.kubernetes.io/instance: ingress-Nginx
app.kubernetes.io/component: controller
---
Nginx 入口路由
我已经独立测试了 Nginx Ingress 到我的 Web 应用程序的基于路径的路由规则。这在 Nginx Ingress 配置了 TCP 负载均衡器时有效。我已经按照通常的方式设置了我的应用程序部署和服务配置。
外部 HTTPS 负载平衡器
- 后端:添加了名为
Nginx_NEG
的区域 NEG 作为后端。后端配置为在端口 80 上接受 HTTP 请求。我通过 TCP 协议在服务端口上配置了健康检查。我添加了防火墙规则以允许来自130.211.0.0/22
和35.191.0.0/16
的传入流量,如此处所述https://cloud.google.com/kubernetes-engine/docs/how-to/standalone-neg#traffic_does_not_reach_the_endpoints
什么不起作用
设置外部负载均衡器后不久,我可以看到 GCP 在其中一个地区 NEG 下创建了一个新端点。但这显示为“不健康”。对外部 HTTPS 负载平衡器的请求返回 502 错误。
-
我在 Nginx Ingress 控制器的
/healthz
路径上配置了健康检查。这似乎也不起作用。
有关如何使其工作的任何提示将不胜感激。谢谢!
编辑 1:根据要求,我运行了 kubectl get svcneg -o yaml --namespace=<namespace>
,这是输出
apiVersion: networking.gke.io/v1beta1
kind: ServiceNetworkEndpointGroup
Metadata:
creationTimestamp: "2021-05-07T19:04:01Z"
finalizers:
- networking.gke.io/neg-finalizer
generation: 418
labels:
networking.gke.io/managed-by: neg-controller
networking.gke.io/service-name: ingress-Nginx-controller
networking.gke.io/service-port: "80"
name: Nginx_NEG
namespace: ingress-Nginx
ownerReferences:
- apiVersion: v1
blockOwnerDeletion: false
controller: true
kind: Service
name: ingress-Nginx-controller
uid: <unique ID>
resourceVersion: "2922506"
selfLink: /apis/networking.gke.io/v1beta1/namespaces/ingress-Nginx/servicenetworkendpointgroups/Nginx_NEG
uid: <unique ID>
spec: {}
status:
conditions:
- lastTransitionTime: "2021-05-07T19:04:08Z"
message: ""
reason: NegInitializationSuccessful
status: "True"
type: Initialized
- lastTransitionTime: "2021-05-07T19:04:10Z"
message: ""
reason: NegSyncSuccessful
status: "True"
type: Synced
lastSyncTime: "2021-05-10T15:02:06Z"
networkEndpointGroups:
- id: <id1>
networkEndpointType: GCE_VM_IP_PORT
selfLink: https://www.googleapis.com/compute/v1/projects/<project>/zones/us-central1-a/networkEndpointGroups/Nginx_NEG
- id: <id2>
networkEndpointType: GCE_VM_IP_PORT
selfLink: https://www.googleapis.com/compute/v1/projects/<project>/zones/us-central1-b/networkEndpointGroups/Nginx_NEG
- id: <id3>
networkEndpointType: GCE_VM_IP_PORT
selfLink: https://www.googleapis.com/compute/v1/projects/<project>/zones/us-central1-f/networkEndpointGroups/Nginx_NEG
解决方法
根据我的理解,您的问题是 - “设置外部负载均衡器后,GCP 会在其中一个区域 NEG 下创建一个新端点,并显示“不健康”并向外部 HTTPS 负载均衡器请求返回一个502 错误”。
本质上,服务的注释 cloud.google.com/neg: '{"ingress": true}' 支持容器原生负载平衡。创建 Ingress 后,会在项目中创建一个 HTTP(S) 负载均衡器,并在集群运行的每个区域中创建 NEG。 NEG 中的端点和服务的端点保持同步。 请参阅链接 [1]。
新端点通常在将它们附加到负载均衡器后变得可以访问,前提是它们响应运行状况检查。如果流量无法到达端点,您可能会遇到 502 错误或拒绝连接。
您在地区 NEG 中的一个终端节点显示不正常,因此请确认其他终端节点的状态以及后端中跨区域分布的终端节点数量。 如果所有后端都不正常,那么您的防火墙、Ingress 或服务可能配置错误。
您可以运行以下命令来检查您的端点是否健康,并参考链接 [2] 相同 - gcloud 计算网络端点组列表网络端点名称 \ --zone=ZONE
要对未到达端点的流量进行故障排除,请验证运行状况检查防火墙规则是否允许传入 TCP 流量到达 130.211.0.0/22 和 35.191.0.0/16 范围内的端点。但是正如您所提到的,您已正确配置了此规则。健康检查配置请参考链接[3]。
针对您的 LB IP 运行 Curl 命令以检查响应 -
卷曲 [LB IP]
[1] https://cloud.google.com/kubernetes-engine/docs/concepts/ingress-xlb
[2] https://cloud.google.com/load-balancing/docs/negs/zonal-neg-concepts#troubleshooting
[3] https://cloud.google.com/kubernetes-engine/docs/concepts/ingress#health_checks