GKE Nginx Ingress Controller 前面的全局负载均衡器(HTTPS 负载均衡器)

2023-11-25

我有一个 GKE 集群,它使用 Nginx Ingress Controller 作为其入口引擎。目前,当我设置 Nginx Ingress Controller 时,我定义了一个服务kind: LoadBalancer并将其指向先前在 GCP 上保留的外部静态 IP。问题是它只绑定到区域静态 IP 地址(如果我没记错的话,是 L4 负载均衡器)。我想要一个全局负载均衡器。

我知道我可以通过使用 GKE 入口控制器而不是 Nginx 入口控制器来实现这一点。但我仍然想使用 Nginx Ingress,因为它具有强大的注释功能,例如根据条件重写标头等; GKE Ingress 注释不可用的内容。

最后,有没有办法将全局负载均衡器与 nginx 入口控制器结合起来,或者将全局负载均衡器放在 Nginx 创建的 L4 负载均衡器前面?

我们需要有全局负载均衡器才能受到 Cloud Armor 的保护。


我终于成功地让 Nginx Ingress Controller 和 L7 HTTP(S) 负载均衡器一起工作。

根据 @rrob 的回复和他自己的问题,我设法让它发挥作用。唯一的区别是他的解决方案将安装经典的 HTTP(S) LoadBalancer,而不是新版本,并且我还介绍了 IP 地址的创建、自签名证书以及从 HTTP 到 HTTPS 的 HTTP 代理重定向。我将在这里列出对我有用的详细步骤。

此步骤假设我们已经创建了一个集群VPC-native traffic routing已启用。

在需要之前HTTP(S) 负载均衡器,我只需应用 Nginx DOCS 页面提供的清单来安装 Nginx Ingress Controller,它将创建一个类型的服务LoadBalancer然后,这将自动创建一个区域 L4 LoadBalancer。

但现在我需要有Cloud Armor和WAF,L4负载均衡器不支持它。 Cloud Armor 需要 HTTPS(S) 负载均衡器才能正常工作。

为了有Nginx 入口控制器与新人合作HTTPS(S) 负载均衡器我们需要改变type: LoadBalancer on the Nginx 入口控制器服务于ClusterIP相反,并添加NEG对其进行注释cloud.google.com/neg: '{"exposed_ports": {"80":{"name": "ingress-nginx-80-neg"}}}'。有了这个net注解,GCP 将自动创建一个网络端点组,该组将指向在 GKE 中运行的 Nginx Ingress Controller 服务。该网络端点组将作为我们的 HTTPS 负载均衡器的后端。

注意:使用时cloud.google.com/neg注释,GCP 将创建一个网络端点组对于每个region包含节点Nginx Ingress 控制器 Pod。例如,如果您将节点池设置为分布在美国中央1-a, 美国中央1-b and us-central1-f,如果每个节点中有一个入口控制器副本,GCP 将创建三个网络端点组。因此,当您设置负载均衡器的后端时,您需要将它们全部添加为后端,如步骤 5 中所述。

apiVersion: v1
kind: Service
metadata:
  annotations:
  labels:
    helm.sh/chart: ingress-nginx-4.0.15
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 1.1.1
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: controller
  name: ingress-nginx-controller
  namespace: ingress-nginx
  annotations:
    cloud.google.com/neg: '{"exposed_ports": {"80":{"name": "ingress-nginx-80-neg"}}}'
spec:
  type: ClusterIP
  ipFamilyPolicy: SingleStack
  ipFamilies:
    - IPv4
  ports:
    - name: http
      port: 80
      protocol: TCP
      targetPort: http
      appProtocol: http
    - name: https
      port: 443
      protocol: TCP
      targetPort: https
      appProtocol: https
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/component: controller

如果您使用 HELM 安装 Nginx Ingress Controller,则需要覆盖配置以将 NEG 注释添加到服务中。所以values.yaml看起来像这样:

controller:
  service:
    type: ClusterIP
    annotations:
      cloud.google.com/neg: '{"exposed_ports": {"80":{"name": "ingress-nginx-80-neg"}}}'

要安装它,请将 ingress-nginx 添加到 helm 存储库:

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update

然后安装它:

helm install -f values.yaml ingress-nginx ingress-nginx/ingress-nginx

接下来的步骤将是:

PROJECT_ID=<project-id>
ZONE=us-central1-a
CLUSTER_NAME=<cluster-name>
HEALTH_CHECK_NAME=nginx-ingress-controller-health-check
NETWORK_NAME=<network-name>
CERTIFICATE_NAME=self-managed-exp-<day>-<month>-<year>
GKE_NODE_METADATA=$(kubectl get nodes -o jsonpath='{.items[0].metadata}')
GKE_SAMPLE_NODE_NAME=$(echo $GKE_NODE_METADATA | jq -r .name)
GKE_SAMPLE_NODE_ZONE=$(echo $GKE_NODE_METADATA | jq -r .labels | jq -r '."topology.kubernetes.io/zone"')
NETWORK_TAGS=$(gcloud compute instances describe \
    $GKE_SAMPLE_NODE_NAME --project $PROJECT_ID \
    --zone=$GKE_SAMPLE_NODE_ZONE --format="value(tags.items[0])")
  1. 创建静态 IP 地址(如果已有,请跳过):

必须Premium层级和全球

gcloud compute addresses create ${CLUSTER_NAME}-loadbalancer-ip \
    --global \
    --ip-version IPV4
  1. 创建防火墙规则,允许 L7 HTTP(S) 负载均衡器访问我们的集群
gcloud compute firewall-rules create ${CLUSTER_NAME}-allow-tcp-loadbalancer \
    --allow tcp:80 \
    --source-ranges 130.211.0.0/22,35.191.0.0/16 \
    --target-tags $NETWORK_TAGS \
    --network $NETWORK_NAME
  1. 为我们即将创建的后端服务创建健康检查
gcloud compute health-checks create http ${CLUSTER_NAME}-nginx-health-check \
  --port 80 \
  --check-interval 60 \
  --unhealthy-threshold 3 \
  --healthy-threshold 1 \
  --timeout 5 \
  --request-path /healthz
  1. 创建一个后端服务,用于通知负载均衡器如何连接 Pod 并将流量分配给 Pod。
gcloud compute backend-services create ${CLUSTER_NAME}-backend-service \
    --load-balancing-scheme=EXTERNAL \
    --protocol=HTTP \
    --port-name=http \
    --health-checks=${CLUSTER_NAME}-nginx-health-check \
    --global
  1. 现在是时候将 Nginx NEG 服务(前面注释的那个)添加到上一步中创建的后端服务中了:

如前所述,将为包含 Nginx Ingress Controller Pod 的每个区域创建一个网络端点组。所以我的设置的当前布局是:

a. **Node Pool** configured to span across **us-central1-a** and **us-central1-c**.
b. **Nginx Ingress Controller** configured to have 4 replicas.
c. **Node 1** in **us-central1-a** will have 2 replicas.
d. **Node 2** in **us-central1-c** will have 2 replicas.
e. GCP generated two Network Endpoint Groups. One for **us-central1-a** and other for **us-central1-c**.

因此,对于下面的示例,我为每个区域绑定两个 NEG,作为负载均衡器的后端服务。

# us-central1-a
gcloud compute backend-services add-backend ${CLUSTER_NAME}-backend-service \
  --network-endpoint-group=ingress-nginx-80-neg \
  --network-endpoint-group-zone=us-central1-a \
  --balancing-mode=RATE \
  --capacity-scaler=1.0 \
  --max-rate-per-endpoint=100 \
  --global

# us-central1-c
gcloud compute backend-services add-backend ${CLUSTER_NAME}-backend-service \
  --network-endpoint-group=ingress-nginx-80-neg \
  --network-endpoint-group-zone=us-central1-c \
  --balancing-mode=RATE \
  --capacity-scaler=1.0 \
  --max-rate-per-endpoint=100 \
  --global
  
  1. 创建负载均衡器本身(URL MAPS)
gcloud compute url-maps create ${CLUSTER_NAME}-loadbalancer \
    --default-service ${CLUSTER_NAME}-backend-service

  1. 创建自我管理证书(可能是 Google 管理的证书,但这里我们将介绍自我管理的证书)。也可以从控制台创建HERE.
gcloud compute ssl-certificates create $CERTIFICATE_NAME \
    --certificate=my-cert.pem \
    --private-key=my-privkey.pem \
    --global

最后,我将通过控制台界面设置负载均衡器前端,这要容易得多。

  1. 要创建 LoadBalancer 前端,请在控制台上输入 Loadbalancer,然后单击“编辑”。

  2. The Frontend configuration tab will be incomplete. Go there image

  3. 点击“添加前端IP和端口”

  4. 为其命名并选择HTTPS现场协议。

  5. On IP地址改变自短暂的到您之前分配的静态IP

  6. Select your certificate and mark Enable HTTP to HTTPS redirect if you want. (I did)image

  7. Save the LoadBalancer. The entering the LoadBalancer page we should see our nginx instance(s) healthy and green. In my case I've setup the Nginx Ingress Controller to have 4 replicas: image

最后,我们只需将我们的域指向 LoadBalancer IP 并创建我们的 Ingress 文件。

注意:Ingress 现在不会处理证书。该证书现在将由 LoadBalancer 在外部进行管理。所以 Ingress 不会有tls定义:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/upstream-fail-timeout: "1200"
    nginx.ingress.kubernetes.io/configuration-snippet: |
      set $http_origin "${scheme}://${host}";
      more_set_headers "server: hide";
      more_set_headers "X-Content-Type-Options: nosniff";
      more_set_headers "Referrer-Policy: strict-origin";
  name: ingress-nginx
  namespace: prod

spec:
  rules:
  - host: app.mydomain.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: frontend
            port:
              number: 80
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

GKE Nginx Ingress Controller 前面的全局负载均衡器(HTTPS 负载均衡器) 的相关文章

  • 解压 R 数据框中的列表

    我有一个dataframe其中一个字段包含不同长度的列表 我想将该字段中列表的每个元素提取到其自己的字段中 以便我可以将结果收集到一个很长的字段中dataframe每个列表元素都有一个 id 这是一个例子dataframe dat lt s
  • 如何在 C# 中播放在线资源中的 .mp3 文件?

    我的问题与此非常相似question https stackoverflow com questions 7556672 mp3 play from stream on c sharp 我有音乐网址 网址如http site com aud
  • 更改显示的 DPI 缩放大小使 Qt 应用程序的字体大小渲染得更大

    我使用 Qt 创建了一些 GUI 应用程序 我的 GUI 应用程序包含按钮和单选按钮等控件 当我运行应用程序时 按钮内的按钮和字体看起来正常 当我将显示器的 DPI 缩放大小从 100 更改为 150 或 200 时 无论分辨率如何 控件的
  • 通用类不会将委托调用转发给具体子类

    鉴于以下情况 protocol EntityType var displayString String get extension String EntityType var displayString String return self
  • Visual Studio 2017/2019/2022 gitsync/pull/push/fetch 操作卡住,并且无法停止

    我从 Visual Studio 中的 Git Changes 选项卡启动同步 获取 拉取或推送 但操作只是挂起 没有选项可以停止它 我必须点击 X 才能关闭 Visual Studio 如果操作是同步的 它会在其他所有操作上打开一个模式对
  • ARM 的内核 Oops 页面错误错误代码

    Oops 之后的错误代码给出了有关 ARM EX 中的恐慌的信息 Oops 17 1 PREEMPT SMP在这种情况下 17 给出了信息 在 x86 中它代表 bit 0 0 no page found 1 protection faul
  • 如何将字符串“07:35”(HH:MM) 转换为 TimeSpan

    我想知道是否有办法将 24 小时时间格式的字符串转换为 TimeSpan 现在我有一种 旧时尚风格 string stringTime 07 35 string values stringTime Split TimeSpan ts new
  • php56 - CentOS - Remi 仓库

    我刚刚在测试盒上安装了 php 5 6 正常的 cli php 解释器似乎不存在 gt php v bash php command not found gt php56 v PHP 5 6 13 cli built Sep 3 2015
  • 是否可以将 Cypress e2e 测试与 firebase auth 项目结合使用?

    我正在探索 Cypress 进行 e2e 测试 看起来是很棒的软件 问题在于身份验证 Cypress 文档解释了为什么使用 UI 非常糟糕here https docs cypress io guides getting started t
  • 本地权威声明和外部提供商声明的混淆

    我正在创建一个简单的 WebApi 它允许用户与 Facebook 连接 当我从 facebook 获取 accessToken 时 我调用 RegisterExternal 创建 Asp Net Identity 记录并存储令牌中的声明
  • 修改 ADW Android 启动器?

    我想更改和修改开源 ADW 启动器 启动器可在此处获取 https github com AnderWeb android packages apps Launcher https github com AnderWeb android p
  • 如何移动 Zend_Layout 的“视图”

    通常它会是这样的结构 application modules somemodule views scripts index index phtml 我如何将其移动到 application templates somemodule temp
  • 期望最大化算法的数值示例[重复]

    这个问题在这里已经有答案了 由于我不确定给出的公式 有人可以提供 EM 算法的简单数字示例吗 一个非常简单的具有 4 或 5 个笛卡尔坐标的坐标就可以了 那这个呢 http en wikibooks org wiki Data Mining
  • 使用 eclipse IDE 配置 angularjs

    我想开始使用 AngularJs 和 Java Spring 进行开发 我使用 Eclipse 作为 IDE 我想配置我的 Eclipse 以使这些框架无缝工作 我知道我可能要求太多 但相信我 我已经做了很多研究 你们是我最后的选择 任何帮
  • Rails 7 缺失部分

    我正在升级到 Rails 7 1 并在使用 JS 部分的视图中遇到奇怪的错误 缺少部分 account stripe js erb application stripe js erb 与 locale gt fr formats gt ht
  • 如何连接字符串和常量字符?

    我需要将 hello world 放入c中 我怎样才能做到这一点 string a hello const char b world const char C string a hello const char b world a b co
  • 如何显示 PHP 对象

    我有这样的代码 dataRecord1 client gt GetRecord token table filter echo pre print r dataRecord1 echo pre foreach dataRecord1 gt
  • 如何为React hooks(useState等)做流类型注解?

    我们应该如何将 Flow 类型注释与 React hooks 一起使用 例如useState 我尝试寻找一些如何实施它们的示例 但找不到任何东西 我试过这个 const allResultsVisible setAllResultsVisi
  • 不同类型的指针可以互相分配吗?

    考虑到 T1 p1 T2 p2 我们可以将 p1 分配给 p2 或反之亦然吗 如果是这样 是否可以不使用强制转换来完成 或者我们必须使用强制转换 首先 让我们考虑不进行强制转换的分配 C 2018 6 5 16 1 1 列出了简单赋值的约束
  • 与文件名中的冒号“:”作斗争

    我有以下代码 用于加载大量 csv gz 并将它们转储到其他文件夹中 并将源文件名作为一列 object DailyMerger extends App def allFiles path File List File val parts

随机推荐