多集群 Ingress


多集群 Ingress 是 Google Kubernetes Engine (GKE) 集群的云托管控制器。它是 Google 托管的一项服务,支持跨集群和区域部署共享的负载平衡资源。如需在多个集群中部署多集群 Ingress,请完成设置多集群 Ingress,然后参阅跨多个集群部署 Ingress

如需查看多集群 Ingress (MCI)、多集群网关 (MCG) 与使用独立网络端点组(LB 和独立 NEG)的负载均衡器之间的详细比较,请参阅选择适用于 GKE 的多集群负载均衡 API

多集群网络

很多因素都有助于多集群拓扑,包括应用离用户很近、集群和区域的高可用性、安全性和组织隔离、集群迁移以及数据本地化。这些用例很少孤立出现。随着使用多集群的理由变多,使用按产品分类的正式多集群平台的需求变得更加迫切。

多集群 Ingress 旨在满足多集群、多区域环境的负载均衡需求。它是外部 HTTP(S) 负载均衡器的控制器,可为一个或多个集群中来自互联网的流量提供入站流量。

多集群 Ingress 的多集群支持可满足许多使用场景的需求,其中包括:

  • 应用的单个一致虚拟 IP (VIP) 地址,与应用的全球部署位置无关。
  • 通过健康检查和流量故障切换实现的多区域、多集群可用性。
  • 通过公共任播 VIP 地址实现的基于邻近度的路由,可缩短客户端延迟时间。
  • 透明的集群迁移,用于升级或集群重建。

默认配额

多集群 Ingress 具有以下默认配额:

  • 如需详细了解舰队的成员限制,请参阅舰队管理配额,了解舰队支持的成员数。
  • 每个项目有 100 个 MultiClusterIngress 资源和 100 个 MultiClusterService 资源。您可以在配置集群中为任意数量的后端集群(最高可达每个项目的集群数上限)创建多达 100 个 MultiClusterIngress 和 100 个 MultiClusterService 资源。

价格和试用期

如需了解多集群 Ingress 价格,请参阅多集群 Ingress 价格

多集群 Ingress 的工作原理

多集群 Ingress 以全球外部应用负载均衡器的架构为基础。全球外部应用负载均衡器是一个全球分布式负载均衡器,全球 100 多个 Google 接入点 (PoP) 都部署了其代理。这些被称为 Google Front Ends (GFEs)的代理,位于 Google 网络边缘处,靠近客户端。多集群 Ingress 在高级层级中创建外部应用负载均衡器。这些负载均衡器使用通过 anycast 通告的全球外部 IP 地址。请求由 GFE 和最靠近客户端的集群处理。网络流量会流向最近的 Google PoP,并使用 Google 骨干网进入 GKE 集群。此负载均衡配置可缩短从客户端到 GFE 的延迟时间。您还可以通过在离客户端最近的区域运行 GKE 集群来缩短服务 GKE 集群和 GFE 之间的延迟时间。

通过在边缘终止 HTTP 和 HTTPS 连接,Google 负载平衡器可在流量进入数据中心或区域之前确定后端可用性,从而确定路由流量的位置。这样可让流量采用最高效的路径从客户端传入后端,同时还能兼顾后端的运行状况和容量。

多集群 Ingress 是一种使用网络端点组 (NEG) 对外部 HTTP (S) 负载均衡器进行编程的 Ingress 控制器。创建 MultiClusterIngress 资源时,GKE 会部署 Compute Engine 负载均衡器资源,并在各个集群中将相应的 Pod 配置为后端。NEG 用于动态跟踪 Pod 端点,以便 Google 负载均衡器拥有一组正常运行的适当后端。

多集群 Ingress 流量流

在 GKE 的各集群中部署应用时,多集群 Ingress 可确保负载均衡器与集群中发生的事件同步:

  • 使用适当的匹配标签创建 Deployment。
  • Pod 的进程终止且健康检查失败。
  • 从后端池中移除集群。

多集群 Ingress 会更新负载均衡器,使其与 Kubernetes 资源的环境和所需的状态保持一致。

多集群 Ingress 架构

多集群 Ingress 使用集中式 Kubernetes API 服务器跨多个集群部署 Ingress。此集中式 API 服务器称为配置集群。任何 GKE 集群都可以充当配置集群。配置集群使用两种自定义资源类型:MultiClusterIngressMultiClusterService。通过在配置集群上部署这些资源,多集群 Ingress 控制器可以跨多个集群部署负载均衡器。

多集群 Ingress 包含以下概念和组件:

  • 多集群 Ingress 控制器 - 这是一个全球分布式控制平面,在集群外部作为服务运行。这样可使控制器的生命周期和操作与 GKE 集群无关。

  • 配置集群 - 这是选定的在 Google Cloud 上运行的 GKE 集群,其中部署了 MultiClusterIngressMultiClusterService 资源。这是这些多集群资源的集中控制点。这些多集群资源存在于单个逻辑 API 中并可通过该 API 供用户访问,从而保持所有集群之间的一致性。Ingress 控制器会监控配置集群并协调负载平衡基础架构。

  • 借助舰队,您可以对 GKE 集群进行逻辑分组和标准化,从而简化基础架构的管理,并使用多集群功能(如多集群 Ingress)。您可以阅读舰队管理文档,详细了解舰队的优势及其创建方法。一个集群只能是单个舰队的成员。

  • 成员集群 - 注册到舰队的集群称为成员集群。舰队中的成员集群包含多集群 Ingress 所知道的所有后端。Google Kubernetes Engine 集群管理视图提供了一个安全的控制台,用于查看所有注册集群的状态。

多集群 Ingress 架构

部署工作流

以下步骤演示了在多个集群中使用多集群 Ingress 的简要工作流。

  1. 将 GKE 集群注册到所选项目中的舰队。

  2. 将 GKE 集群配置为中央配置集群。 此集群可以是专用控制平面,也可以运行其他工作负载。

  3. 将应用部署到需要运行它们的 GKE 集群。

  4. 在配置集群中部署一个或多个 MultiClusterService 资源,它们具有匹配的标签和集群用来选择被视为给定服务的后端的集群、命名空间和 Pod。这会在 Compute Engine 中创建 NEG,进而开始注册和管理服务端点。

  5. 在配置集群中部署一个 MultiClusterIngress 资源,它会引用一个或多个 MultiClusterService 资源作为负载均衡器的后端。这会部署 Compute Engine 外部负载均衡器资源,并通过单个负载均衡器 VIP 在集群中公开端点。

Ingress 概念

多集群 Ingress 使用集中式 Kubernetes API 服务器跨多个集群部署 Ingress。以下部分介绍了多集群 Ingress 资源模型、如何部署 Ingress,以及管理此高可用性网络控制平面的重要概念。

MultiClusterService 资源

MultiClusterService 是供多集群 Ingress 用来表示跨集群共享服务的自定义资源。与 Service 资源类似,MultiClusterService 资源会选择 Pod,但 MultiClusterService 也可以选择标签和集群。MultiClusterService 选择的集群池称为“成员集群”。向舰队注册的所有集群都是成员集群。

MultiClusterService 仅存在于配置集群中,并且不会像 ClusterIP、LoadBalancer 或 NodePort Service 那样路由任何内容。它允许多集群 Ingress 控制器引用单个分布式资源。

以下示例清单描述了应用 fooMultiClusterService

apiVersion: networking.gke.io/v1
kind: MultiClusterService
metadata:
  name: foo
  namespace: blue
spec:
  template:
    spec:
      selector:
        app: foo
      ports:
      - name: web
        protocol: TCP
        port: 80
        targetPort: 80

此清单会使用选择器 app: foo 在所有成员集群中部署 Service。如果相应集群中存在 app: foo Pod,则这些 Pod IP 地址将添加为 MultiClusterIngress 的后端。

以下 mci-zone1-svc-j726y6p1lilewtu7 是在目标集群之一中生成的派生 Service。此 Service 会创建一个 NEG,用于跟踪与此集群中的指定标签选择器匹配的所有 Pod 的 Pod 端点。对于每个 MultiClusterService,每个目标集群中都会存在一个派生 Service 和 NEG(除非使用集群选择器)。如果目标集群中不存在匹配的 Pod,则 Service 和 NEG 将为空。派生 Service 完全由 MultiClusterService 管理,而不是由用户直接管理。

apiVersion: v1
kind: Service
metadata:
  annotations:
    cloud.google.com/neg: '{"exposed_ports":{"8080":{}}}'
    cloud.google.com/neg-status: '{"network_endpoint_groups":{"8080":"k8s1-a6b112b6-default-mci-zone1-svc-j726y6p1lilewt-808-e86163b5"},"zones":["us-central1-a"]}'
    networking.gke.io/multiclusterservice-parent: '{"Namespace":"default","Name":"zone1"}'
  name: mci-zone1-svc-j726y6p1lilewtu7
  namespace: blue
spec:
  selector:
    app: foo
  ports:
  - name: web
    protocol: TCP
    port: 80
    targetPort: 80

下面是关于派生 Service 的一些说明:

  • 它的功能是作为多集群 Ingress 后端的端点的逻辑分组。
  • 它会管理给定集群和应用的 NEG 的生命周期。
  • 它是作为无头 Service 创建的。请注意,只有 SelectorPorts 字段会从 MultiClusterService 沿用到派生服务。
  • Ingress 控制器会管理其生命周期。

MultiClusterIngress 资源

MultiClusterIngress 资源的行为方式在很多方面与核心 Ingress 资源相同。两者在定义主机、路径、协议终止和后端方面具有相同的规范。

以下清单描述了将流量路由到 foobar 后端的 MultiClusterIngress,具体取决于 HTTP 主机标头:

apiVersion: networking.gke.io/v1
kind: MultiClusterIngress
metadata:
  name: foobar-ingress
  namespace: blue
spec:
  template:
    spec:
      backend:
        serviceName: default-backend
        servicePort: 80
      rules:
      - host: foo.example.com
        backend:
          serviceName: foo
          servicePort: 80
      - host: bar.example.com
        backend:
          serviceName: bar
          servicePort: 80

MultiClusterIngress 资源会将此流量发送到名为 foobarMultiClusterService 资源,从而将流量匹配到 foo.example.combar.example.com 上的虚拟 IP 地址。此 MultiClusterIngress 具有与所有其他流量匹配的默认后端,并将该流量发送到默认后端 MultiClusterService

下图展示了流量如何从 Ingress 流向集群:

图中有两个集群:gke-usgke-eu。流量从 foo.example.com 流向在两个集群中都具有标签 app:foo 的 Pod。从 bar.example.com 中,流量会流向在两个集群中都具有标签 app:bar 的 Pod。

跨集群的 Ingress 资源

配置集群是唯一可以具有 MultiClusterIngressMultiClusterService 资源的集群。具有与 MultiClusterService 标签选择器匹配的 Pod 的每个目标集群上也会调度相应的派生 Service。如果 MultiClusterService 未明确选择集群,则系统不会在该集群中创建相应的派生 Service。

命名空间相同性

命名空间相同性是 Kubernetes 集群的属性,借助该属性,命名空间可跨集群扩展,并视为同一命名空间。

在下图中,命名空间 blue 存在于 GKE 集群 gke-cfggke-eugke-us 中。命名空间相同性会将命名空间 blue 视为在所有集群中都相同。这意味着用户对每个集群的 blue 命名空间中的资源具有相同的权限。命名空间相同性也意味着命名空间 blue 中跨多个集群的同名 Service 资源会被视为是同一 Service。

网关会将该 Service 视为所含端点跨三个集群的单个端点池。由于路由和 MultiClusterIngress 资源只能路由到同一命名空间中的 Service,因此可在舰队的所有集群中提供一致的多租户配置。舰队提供高度可移植性,因为资源可以跨集群部署或移动,而无需更改其配置。部署到同一舰队命名空间可确保集群之间的一致性。

请为命名空间相同性考虑以下设计原则:

  • 各个集群中用于不同目的的命名空间不得具有相同的名称。
  • 应为舰队中的团队和集群明确预留命名空间(通过分配命名空间来实现)或隐式预留命名空间(通过带外政策来实现)。
  • 各个集群中用于相同目的的命名空间应共用同一个名称。
  • 应严格控制用户跨集群访问命名空间的权限,以防止未经授权的访问。
  • 不应将默认的命名空间或通用命名空间(例如“prod”或“dev”)用于普通应用部署。用户很容易意外地将资源部署到默认的命名空间并违反命名空间的细分原则。
  • 应在给定团队或用户群组必须部署资源的不同集群中创建相同的命名空间。

配置集群设计

多集群 Ingress 配置集群是一个 GKE 集群,用于托管 MultiClusterIngressMultiClusterService 资源,并充当目标 GKE 集群组中的单个 Ingress 控制点。您在启用多集群 Ingress 时选择配置集群。您可以选择任何 GKE 集群作为配置集群,并且可以随时更改配置集群。

配置集群可用性

由于配置集群是单个控制点,因此,如果配置集群 API 不可用,则无法创建或更新多集群 Ingress 资源。负载均衡器及其正在处理的流量不会受配置集群故障的影响,但在配置集群再次可用之前,控制器不会协调 MultiClusterIngressMultiClusterService 资源的更改。

请为配置集群考虑以下设计原则:

  • 应选择可用性高的配置集群。 区域级集群优先于可用区级集群。
  • 如果要启用多集群 Ingress,配置集群不必是专用集群。配置集群可以托管管理工作负载,甚至可以托管应用工作负载,但您应确保托管应用不会影响配置集群 API 服务器的可用性。配置集群可以是托管 MultiClusterService 资源后端的目标集群,但如果需要额外的预防措施,则也可以通过集群选择将配置集群作为后端排除在外。
  • 配置集群应具有目标集群后端使用的所有命名空间。MultiClusterService 资源只能跨集群引用同一命名空间中的 Pod,因此命名空间必须存在于配置集群中。
  • 跨多个集群部署 Ingress 的用户必须有权访问配置集群才能部署 MultiClusterIngressMultiClusterService 资源。不过,用户只应访问他们有权使用的命名空间。

选择和迁移配置集群

您在启用多集群 Ingress 时,必须选择配置集群。可以选择任何队列的任何成员集群作为配置集群。您可以随时更新配置集群,但必须小心谨慎,以确保更新操作不会导致服务中断。Ingress 控制器将协调配置集群中存在的任何资源。将配置集群从当前集群迁移到下一个集群时,MultiClusterIngressMultiClusterService 资源必须相同。如果资源不同,则 Compute Engine 负载平衡器可能会在配置集群更新后进行更新或销毁。

下图展示了集中式 CI/CD 系统如何将 MultiClusterIngressMultiClusterService 资源应用于配置集群 (gke-us) 和备份集群 (gke-eu) 的 GKE API 服务器,以使两个集群中的资源相同。您可以随时更改配置集群以应对紧急情况或计划内停机时间,而不会产生任何影响,因为 MultiClusterIngressMultiClusterService 资源是相同的。

集群选择

MultiClusterService 资源可以跨集群选择。默认情况下,控制器会在每个目标集群上安排派生 Service。如果您不想在每个目标集群上都使用派生 Service,则可以使用 MultiClusterService 清单中的 spec.clusters 字段定义集群列表。

如果您需要执行以下操作,建议定义集群列表:

  • 隔离配置集群以防止 MultiClusterService 资源选择配置集群。
  • 控制集群之间的流量以执行应用迁移。
  • 路由到仅存在于部分集群中的应用后端。
  • 使用单个 HTTP(S) 虚拟 IP 地址来路由到不同集群上的后端。

您必须确保同一舰队和区域中的成员集群具有唯一名称,以防止命名冲突。

如需了解如何配置集群选择,请参阅设置多集群 Ingress

以下清单描述了一个 MultiClusterService,其 clusters 字段对 europe-west1-c/gke-euasia-northeast1-a/gke-asia 进行引用:

apiVersion: networking.gke.io/v1
kind: MultiClusterService
metadata:
  name: foo
  namespace: blue
spec:
  template:
    spec:
      selector:
        app: foo
      ports:
      - name: web
        protocol: TCP
        port: 80
        targetPort: 80
  clusters:
  - link: "europe-west1-c/gke-eu"
  - link: "asia-northeast1-a/gke-asia-1"

此清单指定在 gke-asiagke-eu 集群中具有匹配标签的 Pod 可以添加为 MultiClusterIngress 的后端。排除任何其他集群,即使它们的 Pod 具有 app: foo 标签也是如此。

下图展示了使用上述清单的示例 MultiClusterService 配置:

图中有三个集群:gke-eugke-asia-1gke-asia-2。即使存在具有匹配标签的 Pod,gke-asia-2 集群也不会作为后端包括在内,因为该集群未包括在清单 spec.clusters 列表中。集群不会因维护或其他运维而接收流量。

后续步骤