首充送50%
续费低至5折
AWS CDN 1折购
免费代充值
免费选购指南
免费协助迁移

使用 Ingress 设置外部应用负载均衡器

2023-07-24


背景

Google Kubernetes Engine (GKE) 为可公开访问的应用提供了对两种类型的 Cloud Load Balancing 的集成支持:

  1. 入站流量
  2. 外部直通式网络负载均衡器

在本教程中,您将使用 Ingress

Ingress

在资源清单中指定 kind: Ingress 时,您需要指示 GKE 来创建 Ingress 资源。通过添加注释并支持工作负载和 Service,您可以创建自定义 Ingress 控制器。否则,GKE 会进行适当的 Google Cloud API 调用,以创建外部应用负载均衡器。负载均衡器的网址映射的主机规则和路径匹配器会引用一个或多个后端服务,其中,每个后端服务对应于一个类型为 NodePort 的 GKE Service,如 Ingress 中引用的那样。每个后端服务的后端是实例组或网络端点组 (NEG)。在配置 Ingress 的过程中,配置容器原生负载均衡时,系统会创建 NEG。对于每个后端服务,GKE 都会根据相应 GKE Service 引用的工作负载的就绪性探测设置创建 Google Cloud 健康检查。

如果要公开在 GKE 上托管的 HTTP(S) 服务,则建议使用 HTTP(S) 负载平衡方法来实现负载平衡。

注意:GKE 创建的负载均衡器按照常规 Cloud Load Balancing 价格计费。

注意:如需使用 Ingress,您必须启用外部应用负载均衡器插件。GKE 集群默认启用了外部应用负载均衡器;您不得将其停用。

注意:Google Kubernetes Engine 依赖于健康检查机制来确定后端服务的健康状况。此机制无法用于执行黑盒监控。如需执行黑盒监控,请创建一个正常运行时间检查。如需了解详情,请参阅(可选)监控服务的可用性和延迟时间。


目标

  • 创建 GKE 集群。
  • 将示例 Web 应用部署到集群。
  • 将外部应用负载均衡器后的示例应用公开到互联网。

费用

在本文档中,您将使用 Google Cloud 的以下收费组件:

您可使用价格计算器根据您的预计使用情况来估算费用。


完成本文档中描述的任务后,您可以通过删除所创建的资源来避免继续计费。如需了解详情,请参阅清理


准备工作请按照以下步骤启用 Kubernetes Engine API:

  1. 访问 Google Cloud 控制台中的 Kubernetes Engine 页面
  2. 创建或选择项目。
  3. 稍作等待,让 API 和相关服务完成启用过程。 此过程可能耗时几分钟。
  4. 确保您的 Google Cloud 项目已启用结算功能。了解如何检查项目是否已启用结算功能。

安装本教程中使用的以下命令行工具:

  • gcloud 用于创建和删除 Kubernetes Engine 集群。gcloud 包含在 gcloud CLI 中。
  • kubectl 用于管理 Kubernetes(即 Kubernetes Engine 使用的集群编排系统)。您可以使用 gcloud 安装 kubectl

从 GitHub 克隆示例代码:


git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
cd kubernetes-engine-samples/load-balancing

为 gcloud 命令行工具设置默认值如需节省在 gcloud 命令行工具中输入项目 IDCompute Engine 地区选项的时间,您可以设置以下默认值:


gcloud config set project project-id
gcloud config set compute/zone compute-zone

创建容器集群

通过运行以下命令创建名为 loadbalancedcluster 的容器集群:


gcloud container clusters create loadbalancedcluster

注意:如果您使用的是现有 Google Kubernetes Engine 集群,或者已通过 Google Cloud 控制台创建集群,则需要运行以下命令来检索集群凭据,并使用这些凭据配置 kubectl 命令行工具:

gcloud container clusters get-credentials loadbalancedcluster如果您已使用上面列出的 gcloud container clusters create 命令创建集群,则无需执行此步骤。

部署 Web 应用

下面的清单描述了了一个在端口 8080 的 HTTP 服务器上运行示例 Web 应用容器映像的 Deployment

load-balancing/web-deployment.yaml

在 GitHub 上查看


# Copyright 2021 Google LLC## Licensed under the Apache License, Version 2.0 (the 'License');# you may not use this file except in compliance with the License.# You may obtain a copy of the License at##      http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an 'AS IS' BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.apiVersion: apps/v1kind: Deploymentmetadata:  name: web  namespace: defaultspec:  selector:    matchLabels:      run: web  template:    metadata:      labels:        run: web    spec:      containers:      - image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0        imagePullPolicy: IfNotPresent        name: web        ports:        - containerPort: 8080          protocol: TCP---

将资源应用到集群:


kubectl apply -f web-deployment.yaml

在集群内公开 Deployment

下面的清单描述了了使 web 部署可在容器集群中访问的 Service

load-balancing/web-service.yaml

在 GitHub 上查看


# Copyright 2021 Google LLC## Licensed under the Apache License, Version 2.0 (the 'License');# you may not use this file except in compliance with the License.# You may obtain a copy of the License at##      http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an 'AS IS' BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.apiVersion: v1kind: Servicemetadata:  name: web  namespace: defaultspec:  ports:  - port: 8080    protocol: TCP    targetPort: 8080  selector:    run: web  type: NodePort---
  1. 将资源应用到集群:kubectl apply -f web-service.yaml 使用此命令创建 NodePort 类型的 Service 时,GKE 会使您的 Service 在集群中所有节点上随机选择的较大端口号(例如 32640)上可用。
  2. 输出:

要使 HTTP(S) 网络服务器应用可公开访问,您必须创建 Ingress 资源。

创建 Ingress 资源

Ingress 是一种 Kubernetes 资源,它封装了一系列规则和配置,可将外部 HTTP(S) 流量路由到内部服务。

在 GKE 上,Ingress 是使用 Cloud Load Balancing 实现的。当您在集群中创建 Ingress 时,GKE 会创建一个 HTTP(S) 负载均衡器,并将其配置为将流量路由到您的应用。

下面的清单描述了将流量定向到 web Service 的 Ingress 资源:

load-balancing/basic-ingress.yaml

在 GitHub 上查看


# Copyright 2021 Google LLC## Licensed under the Apache License, Version 2.0 (the 'License');# you may not use this file except in compliance with the License.# You may obtain a copy of the License at##      http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an 'AS IS' BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.apiVersion: networking.k8s.io/v1kind: Ingressmetadata:  name: basic-ingressspec:  defaultBackend:    service:      name: web      port:        number: 8080---

将资源应用到集群:


kubectl apply -f basic-ingress.yaml

部署此清单后,Kubernetes 会在您的集群上创建一个 Ingress 资源。GKE Ingress 控制器根据 Ingress 中的信息创建并配置 HTTP(S) 负载均衡器,将端口 80 上的所有外部 HTTP 流量路由到您公开的 web NodePort Service。

注意:如需使用 Ingress,您必须启用外部应用负载均衡器插件。GKE 集群默认启用了外部应用负载均衡器;您不得将其停用。

访问应用

通过运行以下命令找出为应用提供服务的负载均衡器的外部 IP 地址:


kubectl get ingress basic-ingress
输出:

NAME            HOSTS     ADDRESS         PORTS     AGE
basic-ingress   *         203.0.113.12    80        2m

注意:在负载均衡器准备好处理应用之前,GKE 可能需要几分钟的时间来分配外部 IP 地址和设置转发规则。在全球范围传播负载均衡器配置之前,您可能会收到 HTTP 404 或 HTTP 500 等错误。

在浏览器中打开应用的外部 IP 地址,查看纯文本 HTTP 响应,如下所示:


Hello, world!
Version: 1.0.0
Hostname: web-6498765b79-fq5q5

您可以访问 Google Cloud 控制台上的负载均衡,并检查 GKE Ingress 控制器创建的网络资源。

(可选)配置静态 IP 地址

在域名上公开网络服务器时,您需要确保应用的外部 IP 地址是不会更改的静态 IP。

默认情况下,GKE 会为通过 Ingress 公开的 HTTP 应用分配临时外部 IP 地址。 临时地址随时可能更改。如果您打算长时间运行应用,则必须使用静态外部 IP 地址

请注意,为 Ingress 资源配置静态 IP 地址后,删除 Ingress 时将不会删除与之关联的静态 IP 地址。如果不再打算再次使用所配置的静态 IP 地址,请务必清理该 IP 地址。

警告:以下说明会创建一个静态 IP 地址,然后在 Ingress 清单中引用该 IP 地址。如果您修改现有 Ingress 以使用静态 IP 地址而不是临时 IP 地址,则 GKE 可能会在 GKE 重新创建负载均衡器的转发规则时更改负载均衡器的 IP 地址。

如需配置静态 IP 地址,请完成以下步骤:

  1. 预留名为 web-static-ip 的静态外部 IP 地址:gcloudConfig Connectorgcloud compute addresses create web-static-ip --global
  2. basic-ingress-static.yaml 清单会在 Ingress 中添加注释,以使用名为 web-static-ip 的静态 IP 地址资源:load-balancing/basic-ingress-static.yaml在 GitHub 上查看# Copyright 2021 Google LLC## Licensed under the Apache License, Version 2.0 (the 'License');# you may not use this file except in compliance with the License.# You may obtain a copy of the License at## http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an 'AS IS' BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: basic-ingress annotations: kubernetes.io/ingress.global-static-ip-name: 'web-static-ip'spec: defaultBackend: service: name: web port: number: 8080---查看清单:cat basic-ingress-static.yaml
  3. 将资源应用到集群:kubectl apply -f basic-ingress-static.yaml
  4. 检查外部 IP 地址:kubectl get ingress basic-ingress 等待应用的 IP 地址发生更改,以使用 web-static-ip 资源的预留 IP 地址。更新现有 Ingress 资源、重新配置负载均衡器并在全球范围传播负载均衡规则可能需要几分钟的时间。完成此操作后,GKE 会释放之前分配给应用的临时 IP 地址。
  5. 注意:未用的静态外部 IP 地址按常规 IP 地址结算计费。

(可选)在负载均衡器上处理多个应用

您可以通过对 Ingress 配置路由规则,在单个负载均衡器和公共 IP 上运行多个服务。通过在同一 Ingress 上托管多个服务,您就不必为公开给互联网的每一个 Service 创建额外的负载均衡器(此为计费资源)。

下面的清单描述了同一 Web 应用的 2.0 版 Deployment:

load-balancing/web-deployment-v2.yaml

在 GitHub 上查看


# Copyright 2021 Google LLC## Licensed under the Apache License, Version 2.0 (the 'License');# you may not use this file except in compliance with the License.# You may obtain a copy of the License at##      http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an 'AS IS' BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.apiVersion: apps/v1kind: Deploymentmetadata:  name: web2  namespace: defaultspec:  selector:    matchLabels:      run: web2  template:    metadata:      labels:        run: web2    spec:      containers:      - image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0        imagePullPolicy: IfNotPresent        name: web2        ports:        - containerPort: 8080          protocol: TCP---

将资源应用到集群:


kubectl apply -f web-deployment-v2.yaml

下面的清单描述了一个在内部将 web2 公开给名为 web2 的 NodePort Service 上的集群:

load-balancing/web-service-v2.yaml

在 GitHub 上查看


# Copyright 2021 Google LLC## Licensed under the Apache License, Version 2.0 (the 'License');# you may not use this file except in compliance with the License.# You may obtain a copy of the License at##      http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an 'AS IS' BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.apiVersion: v1kind: Servicemetadata:  name: web2  namespace: defaultspec:  ports:  - port: 8080    protocol: TCP    targetPort: 8080  selector:    run: web2  type: NodePort---

将资源应用到集群:


kubectl apply -f web-service-v2.yaml

下面的清单描述了具备以下特点的 Ingress 资源:

# Copyright 2021 Google LLC## Licensed under the Apache License, Version 2.0 (the 'License');# you may not use this file except in compliance with the License.# You may obtain a copy of the License at##      http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an 'AS IS' BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.apiVersion: networking.k8s.io/v1kind: Ingressmetadata:  name: fanout-ingressspec:  rules:  - http:      paths:      - path: /*        pathType: ImplementationSpecific        backend:          service:            name: web            port:              number: 8080      - path: /v2/*        pathType: ImplementationSpecific        backend:          service:            name: web2            port:              number: 8080---

将资源应用到集群:


kubectl create -f fanout-ingress.yaml

部署 Ingress 后,请运行 kubectl get ingress fanout-ingress 来查找集群的公共 IP 地址。

注意:GKE 分配外部 IP 地址和准备负载均衡器可能需要几分钟的时间。在负载均衡器准备好处理流量之前,您可能会收到 HTTP 404 和 HTTP 500 等错误。

然后,访问该 IP 地址,确定能否在同一负载均衡器上访问这两个应用:

  • 访问 http://<IP_ADDRESS>/ 并注意响应包含 Version: 1.0.0(因为该请求被路由到 web Service)
  • 访问 http://<IP_ADDRESS>/v2/ 并注意响应包含 Version: 2.0.0(因为该请求被路由到 web2 Service)

Ingress 的 path 字段唯一支持的通配符是 * 字符。* 字符必须紧跟在正斜线 (/) 之后,并且必须是格式中的最后一个字符。例如,/*/foo/*/foo/bar/* 是有效格式,但 */foo/bar*/foo/*/bar 不是有效格式。

较具体的格式优先于不太具体的格式。如果您同时拥有 /foo/*/foo/bar/*,则选择 /foo/bar/bat 来匹配 /foo/bar/*

如需详细了解路径限制和格式匹配,请参阅网址映射文档

(可选)监控服务的可用性和延迟时间

Google Cloud 拨测从用户的角度对应用进行黑盒监控,确定从多个外部 IP 到负载均衡器 IP 地址的延迟时间和可用性。相比之下,Google Cloud 健康检查会对 Pod IP 执行内部检查,确定实例级层的可用性。这两项检查是相辅相成的,它们可让您全面了解应用的运行状况。

您可以使用 Google Cloud 控制台、Cloud Monitoring API 或使用 Cloud Monitoring 客户端库来创建拨测。 如需了解相关信息,请参阅管理拨测。 如需使用 Google Cloud 控制台创建拨测,请执行以下操作:

  1. 转到 Google Cloud 控制台中的 Service 和 Ingress 页面。打开“Service 和 Ingress”
  2. 点击要为其创建拨测的 Service 的名称。
  3. 点击创建拨测。
  4. 在创建拨测窗格中,输入拨测的标题,然后点击下一步前往目标设置。拨测的目标字段自动填充 Service 负载平衡器中的信息。如需查看有关拨测中所有字段的完整文档,请参阅创建拨测。
  5. 点击下一步前往响应验证设置。
  6. 点击下一步前往提醒和通知部分。如需监控拨测,您可以创建一个提醒政策或查看拨测信息中心。如果您的正常运行时间检查失败,提醒政策可以通过电子邮件或其他渠道通知您。如需了解有关提醒政策的常规信息,请参阅提醒简介。注意:在创建正常运行时间检查的过程中,您可以为正常运行时间检查创建提醒政策。创建提醒政策是可选操作,但建议您这样做。如需了解如何以独立操作的形式创建提醒政策,请参阅拨测提醒
  7. 点击创建。

备注

默认情况下,Ingress 通过在 / 路径上发出 GET 请求来执行定期健康检查,以确定应用的健康状况,并预期获得 HTTP 200 响应。如果要检查其他路径或预期获得其他响应代码,您可以使用自定义健康检查路径

Ingress 支持更高级的用例,例如:

  • 基于名称的虚拟托管:您可以使用 Ingress 对多个域名、子域名重复使用负载均衡器,并在单个 IP 地址和负载均衡器上公开多个 Service。如需了解如何为这些任务配置 Ingress,请查看简单扇出和基于名称的虚拟托管示例。
  • HTTPS 终止:您可使用 Cloud Load Balancing 负载均衡器配置 Ingress 来终止 HTTPS 流量。
  • 注意:请始终通过 Ingress 对象修改负载均衡器的属性。如果直接在负载均衡资源上进行更改,则可能导致更改丢失或被 GKE Ingress 控制器替换。

删除 Ingress 后,GKE Ingress 控制器会自动清理相关资源(预留的静态 IP 地址除外)。


清理

为避免因本教程中使用的资源导致您的 Google Cloud 帐号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。

  1. 删除所有手动创建的转发规则和引用 Ingress 的目标代理:注意:仅当使用 Google Kubernetes Engine API 或 Google Cloud 控制台手动更新与 Ingress 关联的负载平衡器时,才需要执行此步骤。引用 Ingress 控制器托管的网址映射的悬垂目标代理将导致 GKE 1.15.4-gke.22+ 版本中的 GKE Ingress 删除失败。您可以检查 Ingress 资源,以查找包含类似于以下内容的错误消息的事件: Error during GC: error running load balancer garbage collection routine: googleapi: Error 400: The url_map resource 'projects/project-id/global/urlMaps/k8s2-um-tlw9rhgp-default-my-ingress-9ifnni82' is already being used by 'projects/project-id/global/targetHttpsProxies/k8s2-um-tlw9rhgp-default-my82-target-proxy', resourceInUseByAnotherResource 在上面的错误消息中,k8s2-um-tlw9rhgp-default-my82-target-proxy 是一个手动创建的目标 https 代理,该代理仍然引用由 Ingress 控制器创建和管理的网址映射 k8s2-um-tlw9rhgp-default-my-ingress-9ifnni82。在删除 Ingress 之前,必须先删除这些手动创建的前端资源(包括转发规则和目标代理)。
  2. 删除 Ingress:此步骤将释放临时外部 IP 地址和与您的应用关联的负载均衡资源:kubectl delete ingress basic-ingress如果您遵循可选的步骤创建 Ingress 以按路径路由请求,则请删除 Ingress:kubectl delete ingress fanout-ingress
  3. 删除静态 IP 地址:仅在您遵循了可选步骤来创建静态 IP 地址时,才需要完成此步骤。如果您已按照“选项 1”将现有临时 IP 地址转换为静态 IP 地址,请访问 Google Cloud 控制台来删除该静态 IP 地址。如果您已按照“选项 2”创建新的静态 IP 地址,请运行以下命令来删除静态 IP 地址:gcloud compute addresses delete web-static-ip --global
  4. 删除集群:此步骤将删除容器集群的计算节点以及集群中的 Deployment 等其他资源:gcloud container clusters delete loadbalancedcluster