多集群 Ingress

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

多集群网络

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

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

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

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

价格和试用期

多集群 Ingress 需要所有参与 MCI 后端的集群具有 Anthos on Google Cloud 许可。每个注册集群都根据其 vCPU 容量收费。

MCI 可以按需使用,也可通过 Anthos 订阅许可使用。标准 Compute Engine 负载平衡器价格适用于通过 Ingress 创建的入站流量和转发规则。

如果您是新 Anthos 客户,可免费试用 GKE on Google Cloud,免费使用金额最高可为 900 欧元,或者最长免费使用 30 天(以先到者为准)。在此试用期期间,系统会计算适用费用,同时使用赠金抵扣这些费用(最高 $900)。如需注册试用,请转至 Cloud Marketplace 中的 Anthos 页面,然后点击开始试用

多集群 Ingress 的工作原理

多集群 Ingress 以外部 HTTP(S) 负载平衡的架构为基础。HTTP(S) 负载平衡是一个全球分布式负载平衡器,全球 100 多个 Google 接入点 (PoP) 都部署了其代理。这些被称为 Google Front Ends (GFEs)的代理,位于 Google 网络边缘处,靠近客户端。多集群 Ingress 在付费级中创建外部 HTTP(S) 负载平衡器。这些负载平衡器使用通过 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。通过在配置集群上部署这些资源,Anthos Ingress 控制器可以跨多个集群部署负载平衡器。

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

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

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

  • Environ - Environ 环境是一个网域,用于对集群和基础架构进行分组、管理资源以及在资源之间保持一致的政策。MCI 使用 Environ 环境概念来表示跨不同集群应用 Ingress 的方式。您注册到 Environ 的集群对 MCI 可见,因此它们可以用作 Ingress 的后端。

  • 成员集群 - 注册到 Environ 环境的集群称为成员集群。Environ 中的成员集群包含 MCI 所知道的所有后端。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 (MCS) 是多集群 Ingress 使用的自定义资源,它是跨多个集群的 Service 的逻辑表示。MCS 与核心 Service 类型既相似又有显著区别。MCS 仅存在于配置集群中,并且会在目标集群中生成派生 Service。MCS 不会像 ClusterIP、LoadBalancer 或 NodePort Service 那样路由任何内容。它仅允许 MCI 引用单个分布式资源。以下是 foo 应用的简单 MCS:

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

与 Service 一样,MCS 是 Pod 的选择器,但它也可以选择标签和集群。它选择的一组集群称为成员集群,这些集群全部都是注册到 Environ 环境的集群。此 MCS 会使用选择器 app: foo 在所有成员集群中部署派生 Service。如果相应集群中存在 app: foo Pod,则这些 Pod IP 地址将添加为 MCI 的后端。

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

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-frontend
  ports:
  - name: web
    protocol: TCP
    port: 80
    targetPort: 80

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

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

MultiClusterIngress 资源

MultiClusterIngress (MCI) 资源的行为方式在很多方面与核心 Ingress 资源相同。两者在定义主机、路径、协议终止和后端方面具有相同的规范。以下是一个简单的 MCI 资源示例,该资源根据 HTTP 主机标头将流量路由到 foo 和 bar 后端。

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

请注意,此 MCI 会将此流量发送到名为 foo 和 bar 的 MultiClusterService (MCS) 资源,从而将流量传输到 foo.example.combar.example.com 上的 VIP 地址。此 MCI 具有与所有其他流量匹配的默认后端,并将该流量发送到默认后端 MCS。

主机标头匹配

跨集群的 Ingress 资源

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

Ingress 资源模型示意图

命名空间相同性

已注册的 GKE 集群将成为 Environ 的成员。

Environ 环境具有一个特性,即命名空间相同性,该特性假定各个集群中具有相同名称和相同命名空间的资源是同一资源的实例。实际上,这意味着从多集群 Ingress 的角度来看,不同集群的 ns1 命名空间中带有标签 app: foo 的 Pod 都被视为同一组应用后端的一部分。

这会对不同的开发团队在一组集群中的运作方式产生影响。不同的团队仍然可以使用命名空间对跨集群边界的工作负载进行细分,从而利用同一组集群;不过,每个团队都需要在其Environ 环境中的所有集群上明确或隐式预留各自的命名空间。

在以下示例中,蓝色团队有权在跨一组集群的所有蓝色命名空间中进行部署。蓝色在每个集群中被视为相同的命名空间。多集群 Ingress 配置集群中也包含蓝色命名空间。由蓝色团队部署的 MultiClusterService 资源只能在同时存在于不同集群的蓝色命名空间中的 Pod 之间进行选择。MCI 和 MCS 资源没有对不同集群中的命名空间的可见性或访问权限,因此资源的重要性和“相同性”会保留在集群中。

展示命名空间相同性的示意图

命名空间相同性存在设计差异。以下原则有助于用户获得成功:

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

配置集群设计

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

配置集群可用性

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

以下是关于如何使用和管理配置集群的一些设计原则:

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

选择和迁移配置集群

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

在下图中,集中式 CI/CD 系统对配置集群 (gke-us) 和备份集群 (gke-eu) 的 GKE API 服务器始终应用 MCI 和 MCS 资源,因此这两个集群中的资源是相同的。如果您需要更改配置集群以应对紧急情况或计划内停机时间,则可以更新配置集群而不会产生任何影响,因为 MCI 和 MCS 资源是相同的。

应用 MCI 和 MCS 资源的集中式 CI/CD 系统

集群选择

MCS 资源能够明确选择集群。默认情况下,MCS 会将派生 Service 调度到每个目标集群上。集群选择可以为给定 MCS 定义明确的集群列表;在该 MCS 中,应调度派生 Service 并将忽略所有其他目标集群。请参阅设置多集群 Ingress 以配置集群选择。

在多种使用场景中,您可能需要将入站流量规则应用于特定集群:

  • 隔离配置集群以防止 MCS 选择配置集群。
  • 以蓝绿方式迁移应用时,控制集群之间的流量。
  • 路由到仅存在于部分集群中的应用后端。
  • 使用单个 L7 VIP 地址将主机/路径路由到不同集群上的后端。

集群选择是通过 MCS 中的 clusters 字段完成的。集群由 <region | zone>/<name> 明确引用。同一 Environ 和区域中的成员集群应具有独一无二的名称,这样就不会存在命名冲突。

在以下示例中,foo MCS 有一个引用 europe-west1-c/gke-euasia-northeast1-a/gke-asiaclusters 字段。因此,您可以将 gke-asia 和 gke-eu 集群中具有匹配标签的 Pod 添加为给定 MCI 的后端。这会从 Ingress 中排除 gke-us 集群,即使该集群具有带 app: foo 标签的 Pod 也是如此。这对于独立于 Pod 部署来启动新集群或迁移到新集群以及控制流量非常有用。

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-eu、gke-asia-1、gke-asia-2。即使具有匹配标签的 Pod 已放置在其中,gke-asia-2 也会作为后端被排除在外。这样可以使集群在进行维护或其他操作时不接收流量。请注意,如果从 MCS 中省略“clusters”字段,则系统会隐式选择所有成员集群。

显示已排除的后端的示意图

后续步骤