将外部 HTTPS 负载均衡器与公开为区域 NEG

问题描述

我想要完成的事情

我正在尝试将外部 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 负载平衡器

我使用以下设置创建了一个外部 HTTPS 负载平衡器:

什么不起作用

设置外部负载均衡器后不久,我可以看到 GCP 在其中一个地区 NEG 下创建了一个新端点。但这显示为“不健康”。对外部 HTTPS 负载平衡器的请求返回 502 错误

  • 我不确定从哪里开始在 GCP 日志记录中调试此配置。我已启用运行状况检查的日志记录,但日志中未显示任何内容

  • 我在 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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...