部署高可用性容器应用

本页面提供了建议的部署策略,以在 Google Distributed Cloud (GDC) 空气隔离环境中构建稳健的高可用性 (HA) Kubernetes 容器应用。您必须在多个 GDC 可用区中部署容器应用,并配置异步存储复制,以便在发生意外停机或本地灾难时恢复应用及其数据。

本页面适用于应用运维人员群组中的开发者,他们负责为组织创建应用工作负载。如需了解详情,请参阅 GDC 气隙环境文档的受众群体

目标

  • 在 GDC 全球范围内创建位于两个或更多可用区中的 Kubernetes 集群。
  • 配置全球负载均衡。
  • 将容器工作负载部署到每个区域 Kubernetes 集群。
  • 预配存储空间并将其附加到您的 pod。
  • 配置异步存储复制,使用块存储或对象存储。

准备工作

  • 验证您是否在具有多个可用可用区的 GDC 世界中工作。运行 gdcloud zones list 可列出您的全球组织中可用的可用区。如需了解详情,请参阅列出宇宙中的可用区

  • 请让您的组织 IAM 管理员为您授予以下角色:

    • Namespace Admin (namespace-admin) 角色,用于创建和管理容器工作负载。

    • 用户集群管理员 (user-cluster-admin) 和用户集群开发者 (user-cluster-developer) 角色,用于创建和管理 Kubernetes 集群及其节点池。

    • Load Balancer Admin (load-balancer-admin) 和 Global Load Balancer Admin (global-load-balancer-admin) 角色。您必须拥有这些角色才能创建和管理负载平衡器。

    • 卷复制全局管理员角色 (app-volume-replication-admin-global)。您必须拥有此角色才能管理卷复制。

    • Global PNP Admin (global-project-networkpolicy-admin) 角色,用于跨可用区创建和管理项目网络政策。

    • Harbor Instance Admin (harbor-instance-admin)、Harbor Instance Viewer(harbor-instance-viewer) 和 Harbor Project Creator (harbor-project-creator) 角色。创建和管理制品注册表中的容器映像需要这些角色。

    • Volume Replication Global Admin (app-volume-replication-admin-global) 角色,用于管理块存储资源之间的卷复制关系。

    • Project Bucket Object Admin (project-bucket-object-admin) 和 Project Bucket Admin (project-bucket-admin) 角色,用于创建和管理存储分区。

    如需了解详情,请参阅角色说明

  • 安装并配置 gdcloud CLI,然后配置您的可用区级和全局上下文。如需了解详情,请参阅跨可用区管理资源

  • 安装并配置 kubectl CLI,并为全局 API 服务器、管理 API 服务器和 Kubernetes 集群设置适当的 kubeconfig 文件。如需了解详情,请参阅手动生成 kubeconfig 文件

在多个可用区中创建 Kubernetes 集群

Kubernetes 集群是可用区级资源,因此您必须在每个地区中单独创建一个集群。

控制台

  1. 在导航菜单中,依次选择 Kubernetes Engine > 集群

  2. 点击创建集群

  3. 名称字段中,指定集群的名称。

  4. 选择集群的 Kubernetes 版本。

  5. 选择要在其中创建集群的可用区。

  6. 点击附加项目,然后选择要附加到集群的现有项目。然后,点击保存。您可以在创建集群后,通过项目详情页面附加或分离项目。您必须先将项目附加到集群,然后才能在其中部署容器工作负载。

  7. 点击下一步

  8. 为集群配置网络设置。创建集群后,您将无法更改这些网络设置。Kubernetes 集群的默认且唯一受支持的互联网通信协议是互联网通信协议第四版 (IPv4)。

    1. 指定负载平衡器 IP 地址池大小,例如 20

    2. 选择要使用的服务 CIDR(无类别域间路由)。您的已部署服务(例如负载平衡器)会从此范围中分配 IP 地址。

    3. 选择要使用的 pod CIDR。集群会从此范围中为您的 Pod 和虚拟机分配 IP 地址。

    4. 点击下一步

  9. 查看为集群自动生成的默认节点池的详细信息。点击 修改以修改默认节点池。

  10. 如需创建其他节点池,请选择添加节点池。在修改默认节点池或添加新节点池时,您可以使用以下选项对其进行自定义:

    1. 为节点池分配名称。创建节点池后,您将无法修改其名称。
    2. 指定要在节点池中创建的工作器节点数。
    3. 选择最符合工作负载要求的机器类。 查看以下设置的列表:

      • 机器类型
      • CPU
      • 内存
    4. 点击保存

    5. 点击创建以创建集群。

  11. 针对 GDC 宇宙中的每个可用区重复执行上述步骤。确保您希望用于实现高可用性策略的每个可用区中都有一个 Kubernetes 集群。

API

如需使用 API 直接创建新的 Kubernetes 集群,请将自定义资源应用于每个 GDC 可用区。

  1. 创建 Cluster 自定义资源并将其部署到相应地区的 Management API 服务器:

    kubectl --kubeconfig MANAGEMENT_API_SERVER apply -f - <<EOF \
    apiVersion: cluster.gdc.goog/v1
    kind: Cluster
    metadata:
      name: CLUSTER_NAME
      namespace: platform
    spec:
      clusterNetwork:
        podCIDRSize: POD_CIDR
        serviceCIDRSize: SERVICE_CIDR
      initialVersion:
        kubernetesVersion: KUBERNETES_VERSION
      loadBalancer:
        ingressServiceIPSize: LOAD_BALANCER_POOL_SIZE
      nodePools:
      - machineTypeName: MACHINE_TYPE
        name: NODE_POOL_NAME
        nodeCount: NUMBER_OF_WORKER_NODES
        taints: TAINTS
        labels: LABELS
        acceleratorOptions:
          gpuPartitionScheme: GPU_PARTITION_SCHEME
      releaseChannel:
        channel: UNSPECIFIED
    EOF
    

    替换以下内容:

    • MANAGEMENT_API_SERVER:区域管理 API 服务器的 kubeconfig 路径。如需了解详情,请参阅切换到地区背景
    • CLUSTER_NAME:集群的名称。 集群名称不得以 -system 结尾。-system 后缀专为 GDC 创建的集群预留。
    • POD_CIDR:分配 pod 虚拟 IP 地址 (VIP) 的网络范围的大小。如果未设置,则使用默认值 21
    • SERVICE_CIDR:分配服务 VIP 的网络范围的大小。如果未设置,则使用默认值 23
    • KUBERNETES_VERSION:集群的 Kubernetes 版本,例如 1.26.5-gke.2100。如需列出可供配置的 Kubernetes 版本,请参阅列出集群的可用 Kubernetes 版本
    • LOAD_BALANCER_POOL_SIZE:负载均衡器服务使用的不重叠 IP 地址池的大小。如果未设置,则使用默认值 20
    • MACHINE_TYPE:节点池的工作器节点的机器类型。查看可用机器类型,了解可配置的资源。
    • NODE_POOL_NAME:节点池的名称。
    • NUMBER_OF_WORKER_NODES:要在节点池中预配的工作器节点数。
    • TAINTS:要应用于此节点池的节点的污点。这是一个可选字段。
    • LABELS:要应用于此节点池的节点的标签。它包含一个键值对列表。此字段为可选字段。
    • GPU_PARTITION_SCHEME:GPU 分区方案(如果您运行 GPU 工作负载),例如 mixed-2。如果未设置此字段,则 GPU 不会进行分区。如需了解可用的多实例 GPU (MIG) 配置文件,请参阅支持的 MIG 配置文件
  2. 对于您希望托管容器应用以实现高可用性策略的每个可用区,重复执行上一步骤。

配置负载平衡器

如需在不同可用区中的 Pod 之间分配流量,请创建负载平衡器。您可以选择创建外部负载平衡器 (ELB) 和内部负载平衡器 (ILB),这两种负载平衡器都可以配置为区域级或全球级。在此示例中,为容器应用配置全球 ILB 和全球 ELB。

创建全球内部负载均衡器

内部负载平衡器 (ILB) 通过分配给组织的内部 IP 地址池公开组织内的服务。ILB 服务永远无法从组织外部的任何端点访问。

完成以下步骤,为容器工作负载创建全球 ILB。

gdcloud

使用 gdcloud CLI 创建以 pod 工作负载为目标的 ILB。

此 ILB 针对的是项目中与 Backend 对象中定义的标签匹配的所有工作负载。Backend 自定义资源必须限定到某个可用区。

如需使用 gcloud CLI 创建 ILB,请按以下步骤操作:

  1. 在每个运行 pod 的可用区中创建一个可用区级 Backend 资源,以定义 ILB 的端点:

    gdcloud compute backends create BACKEND_NAME \
        --labels=LABELS \
        --project=PROJECT \
        --cluster=CLUSTER_NAME \
        --zone=ZONE
    

    替换以下内容:

    • BACKEND_NAME:为后端资源选择的名称,例如 my-backend
    • LABELS:用于定义此后端资源要使用哪些 pod 之间的端点的选择器,例如 app=web
    • PROJECT:您的项目的名称。
    • CLUSTER_NAME:所定义选择器的范围所限定到的 Kubernetes 集群。如果未指定此字段,则会选择具有指定标签的所有端点。此字段是可选字段。
    • ZONE:要用于此调用的可用区。如需为需要设置时区的全部命令预设时区标志,请运行 gdcloud config set core/zone ZONE。可用区标志仅在多可用区环境中可用。此字段是可选字段。

    针对 GDC 宇宙中的每个区域重复执行此步骤。

  2. 创建全局 BackendService 资源:

    gdcloud compute backend-services create BACKEND_SERVICE_NAME \
        --project=PROJECT \
        --target-ports=TARGET_PORTS \
        --global
    

    替换以下内容:

    • BACKEND_SERVICE_NAME:后端服务的名称。
    • PROJECT:您的项目的名称。
    • TARGET_PORTS:此后端服务转换的目标端口的英文逗号分隔列表,其中每个目标端口都指定了协议、转发规则中的端口和后端实例中的端口。您可以指定多个目标端口。 此字段必须采用 protocol:port:targetport 格式,例如 TCP:80:8080。此字段是可选字段。
  3. BackendService 资源添加到之前在每个可用区中创建的 Backend 资源:

    gdcloud compute backend-services add-backend BACKEND_SERVICE_NAME \
        --backend-zone=ZONE \
        --backend=BACKEND_NAME \
        --project=PROJECT \
        --global
    

    替换以下内容:

    • BACKEND_SERVICE_NAME:全局后端服务的名称。
    • ZONE:后端的可用区。
    • BACKEND_NAME:可用区级后端的名称。
    • PROJECT:您的项目的名称。

    针对您之前创建的每个区域后端完成此步骤。

  4. 创建内部 ForwardingRule 资源,用于定义服务可用的虚拟 IP 地址 (VIP):

    gdcloud compute forwarding-rules create FORWARDING_RULE_INTERNAL_NAME \
        --backend-service=BACKEND_SERVICE_NAME \
        --cidr=CIDR \
        --ip-protocol-port=PROTOCOL_PORT \
        --load-balancing-scheme=INTERNAL \
        --project=PROJECT \
        --global
    

    替换以下内容:

    • FORWARDING_RULE_INTERNAL_NAME:转发规则的名称。
    • CIDR:要用于转发规则的 CIDR。此字段是可选字段。 如果未指定,系统会自动从全局 IP 地址池中预留一个 IPv4/32 CIDR。指定与相应转发规则位于同一命名空间中的 Subnet 资源的名称。Subnet 资源表示全球子网的请求和分配信息。如需详细了解 Subnet 资源,请参阅管理子网
    • PROTOCOL_PORT:要在转发规则中公开的协议和端口。此字段必须采用 ip-protocol=TCP:80 格式。公开的端口必须与实际应用在容器内公开的端口相同。
  5. 如需验证配置的 ILB,请确认每个已创建对象的 Ready 条件。通过向 VIP 发送 curl 请求来验证流量:

    1. 如需获取分配的 VIP,请描述转发规则:

      gdcloud compute forwarding-rules describe FORWARDING_RULE_INTERNAL_NAME --global
      
    2. 通过向转发规则中相应字段指定的端口上的 VIP 发送 curl 请求来验证流量:

      curl http://FORWARDING_RULE_VIP:PORT
      

    替换以下内容:

    • FORWARDING_RULE_VIP:转发规则的 VIP。
    • PORT:转发规则的端口号。

API

使用 KRM API 创建以容器工作负载为目标的 ILB。此 ILB 针对的是项目中与 Backend 对象中定义的标签匹配的所有工作负载。如需使用 KRM API 创建全球 ILB,请按以下步骤操作:

  1. 创建 Backend 资源以定义 ILB 的端点。为放置容器工作负载的每个可用区创建 Backend 资源:

    kubectl --kubeconfig MANAGEMENT_API_SERVER apply -f - <<EOF
    apiVersion: networking.gdc.goog/v1
    kind: Backend
    metadata:
      namespace: PROJECT
      name: BACKEND_NAME
    spec:
      clusterName: CLUSTER_NAME
      endpointsLabels:
        matchLabels:
          app: APP_NAME
    EOF
    

    替换以下内容:

    • MANAGEMENT_API_SERVER:区域管理 API 服务器的 kubeconfig 路径。如需了解详情,请参阅切换到地区性上下文
    • PROJECT:您的项目的名称。
    • BACKEND_NAMEBackend 资源的名称。
    • CLUSTER_NAME:所定义选择器的范围所限定到的 Kubernetes 集群。如果未指定此字段,则会选择具有指定标签的所有端点。此字段是可选字段。
    • APP_NAME:容器应用的名称。

    您可以为每个可用区使用相同的 Backend 资源,也可以为每个可用区创建具有不同标签集的 Backend 资源。

  2. 使用之前创建的 Backend 资源创建一个 BackendService 对象。请务必添加 HealthCheck 资源:

    kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF
    apiVersion: networking.global.gdc.goog/v1
    kind: BackendService
    metadata:
      namespace: PROJECT
      name: BACKEND_SERVICE_NAME
    spec:
      backendRefs:
      - name: BACKEND_NAME
        zone: ZONE
      healthCheckName: HEALTH_CHECK_NAME
      targetPorts:
      - port: PORT
        protocol: PROTOCOL
        targetPort: TARGET_PORT
    EOF
    

    替换以下内容:

    • GLOBAL_API_SERVER:全局 API 服务器的 kubeconfig 路径的 kubeconfig 路径。
    • PROJECT:您的项目的名称。
    • BACKEND_SERVICE_NAME:为 BackendService 资源选择的名称。
    • HEALTH_CHECK_NAME:您之前创建的 HealthCheck 资源的名称。
    • BACKEND_NAME:可用区级 Backend 资源的名称。
    • ZONEBackend 资源所在的可用区。您可以在 backendRefs 字段中指定多个后端。例如:

      - name: my-backend-1
        zone: us-east1-a
      - name: my-backend-2
        zone: us-east1-b
      

      targetPorts 字段为可选字段。此资源列出了 BackendService 资源转换的端口。如果您使用的是此对象,请为以下各项提供值:

    • PORT:服务公开的端口。

    • PROTOCOL:流量必须匹配的第 4 层协议。仅支持 TCP 和 UDP。

    • TARGET_PORT:转换后的值所对应的端口,例如 8080。相应对象中的值不得重复。

      targetPorts 的示例可能如下所示:

      targetPorts:
        - port: 80
          protocol: TCP
          targetPort: 8080
      
  3. 创建内部 ForwardingRule 资源,用于定义服务可用的虚拟 IP 地址 (VIP)。

    kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF
    apiVersion: networking.global.gdc.goog/v1
    kind: ForwardingRuleInternal
    metadata:
      namespace: PROJECT
      name: FORWARDING_RULE_INTERNAL_NAME
    spec:
      cidrRef: CIDR
      ports:
      - port: PORT
        protocol: PROTOCOL
      backendServiceRef:
        name: BACKEND_SERVICE_NAME
    EOF
    

    替换以下内容:

    • GLOBAL_API_SERVER:全局 API 服务器的 kubeconfig 路径的 kubeconfig 路径。
    • PROJECT:您的项目的名称。
    • FORWARDING_RULE_INTERNAL_NAME:为 ForwardingRuleInternal 资源选择的名称。
    • CIDR:用于转发规则的 CIDR。 此字段是可选字段。如果未指定,系统会自动从全局 IP 地址池中预留一个 IPv4/32 CIDR。指定与相应转发规则位于同一命名空间中的 Subnet 资源的名称。Subnet 资源表示全球子网的请求和分配信息。如需详细了解 Subnet 资源,请参阅管理子网
    • PORT:转发规则中要公开的端口。使用 ports 字段指定一个 L4 端口数组,数据包将转发到根据相应转发规则配置的后端。必须至少指定一个端口。使用 port 字段指定端口号。公开的端口必须与实际应用在容器内公开的端口相同。
    • PROTOCOL:用于转发规则的协议,例如 TCPports 数组中的条目必须如下所示:

      ports:
      - port: 80
        protocol: TCP
      
  4. 如需验证配置的 ILB,请确认每个已创建对象的 Ready 条件。通过向 VIP 发送 curl 请求来验证流量:

    1. 检索 VIP:

      kubectl get forwardingruleinternal -n PROJECT
      

      输出如下所示:

      NAME           BACKENDSERVICE                  CIDR              READY
      ilb-name       BACKEND_SERVICE_NAME            192.0.2.0/32      True
      
    2. 通过向转发规则中相应字段指定的端口上的 VIP 发出 curl 请求来测试流量:

      curl http://FORWARDING_RULE_VIP:PORT
      

      替换以下内容:

      • FORWARDING_RULE_VIP:转发规则的 VIP。
      • PORT:转发规则中相应字段的端口号。

创建全球外部负载均衡器

外部负载平衡器 (ELB) 会公开服务,以便组织外部的用户可以通过分配给组织的 IP 地址池(来自更大的实例外部 IP 地址池)访问这些服务。

完成以下步骤,为容器工作负载创建全球 ELB。

gdcloud

使用 gdcloud CLI 创建一个全局 ELB,该 ELB 以项目中与 Backend 对象中定义的标签匹配的所有工作负载为目标。Backend 自定义资源的范围必须限定为某个可用区。

  1. 为了使 ELB 服务正常运行,您必须在政策中配置并应用自己的自定义 ProjectNetworkPolicy 数据转移,以允许流量流向此 ELB 服务的工作负载。网络政策控制对工作负载的访问,而不是负载均衡器本身。ELB 会将工作负载公开给客户网络,因此需要明确的网络政策来允许外部流量流向工作负载端口(例如 8080)。

    指定外部 CIDR 地址以允许流量流向此 ELB 的工作负载:

    kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF
    apiVersion: networking.global.gdc.goog/v1
    kind: ProjectNetworkPolicy
    metadata:
      namespace: PROJECT
      name: allow-inbound-traffic-from-external
    spec:
      policyType: Ingress
      subject:
        subjectType: UserWorkload
      ingress:
      - from:
        - ipBlock:
            cidr: CIDR
        ports:
        - protocol: TCP
          port: PORT
    EOF
    

    替换以下内容:

    • GLOBAL_API_SERVER:全局 API 服务器的 kubeconfig 路径的 kubeconfig 路径。如果您尚未为全局 API 服务器生成 kubeconfig 文件,请参阅手动生成 kubeconfig 文件了解详情。
    • PROJECT:您的项目的名称。
    • CIDR:需要从哪个外部 CIDR 访问 ELB。此政策是必需的,因为外部负载均衡器使用直接服务器返回 (DSR),该模式会保留来源外部 IP 地址,并在返回路径上绕过负载均衡器。如需了解详情,请参阅为跨组织流量创建全球入站防火墙规则
    • PORT:负载平衡器后面的 pod 上的后端端口。此值位于 Service 资源的清单的 .spec.ports[].targetPortfield 字段中。此字段是可选字段。

    此配置可让项目中的所有资源访问指定的 CIDR 范围。

  2. 在每个可用区中创建一个 Backend 资源,以定义 ELB 的端点:

    gdcloud compute backends create BACKEND_NAME \
      --labels=LABELS \
      --project=PROJECT \
      --cluster=CLUSTER_NAME \
      --zone=ZONE
    

    替换以下内容:

    • BACKEND_NAME:后端资源的名称,例如 my-backend
    • LABELS:一个选择器,用于定义要为此后端资源使用哪些 Pod 之间的端点,例如 app=web
    • PROJECT:您的项目的名称。
    • CLUSTER_NAME:所定义选择器的范围所限定到的 Kubernetes 集群。如果未指定此字段,则会选择具有指定标签的所有端点。此字段是可选字段。
    • ZONE:要用于此调用的可用区。如需为需要设置时区的全部命令预设时区标志,请运行 gdcloud config set core/zone ZONE。可用区标志仅在多可用区环境中可用。此字段是可选字段。

    您可以为每个可用区使用相同的 Backend 资源,也可以为每个可用区创建具有不同标签集的 Backend 资源。

  3. 创建全局 BackendService 资源:

    gdcloud compute backend-services create BACKEND_SERVICE_NAME \
      --project=PROJECT \
      --target-ports=TARGET_PORTS \
      --health-check=HEALTH_CHECK_NAME \
      --global
    

    替换以下内容:

    • BACKEND_SERVICE_NAME:相应后端服务的所选名称。
    • PROJECT:您的项目的名称。
    • TARGET_PORTS:此后端服务转换的目标端口的英文逗号分隔列表,其中每个目标端口都指定了协议、转发规则上的端口和后端实例上的端口。您可以指定多个目标端口。此字段必须采用 protocol:port:targetport 格式,例如 TCP:80:8080。此字段是可选字段。
    • HEALTH_CHECK_NAME:健康检查资源的名称。此字段是可选字段。
  4. 将全局 BackendService 资源添加到之前创建的区域级 Backend 资源:

    gdcloud compute backend-services add-backend BACKEND_SERVICE_NAME \
      --backend=BACKEND_NAME \
      --backend-zone=ZONE \
      --project=PROJECT \
      --global
    

    针对您之前创建的每个区域后端完成此步骤。

  5. 创建外部 ForwardingRule 资源,用于定义服务可用的 VIP:

    gdcloud compute forwarding-rules create FORWARDING_RULE_EXTERNAL_NAME \
      --backend-service=BACKEND_SERVICE_NAME \
      --cidr=CIDR \
      --ip-protocol-port=PROTOCOL_PORT \
      --load-balancing-scheme=EXTERNAL \
      --project=PROJECT \
      --global
    

    替换以下内容:

    • FORWARDING_RULE_EXTERNAL_NAME:转发规则的名称。
    • CIDR:要用于转发规则的 CIDR。此字段是可选字段。 如果未指定,系统会自动从全局 IP 地址池中预留一个 IPv4/32 CIDR。指定与相应转发规则位于同一命名空间中的 Subnet 资源的名称。Subnet 资源表示全球子网的请求和分配信息。如需详细了解 Subnet 资源,请参阅管理子网
    • PROTOCOL_PORT:要在转发规则中公开的协议和端口。此字段必须采用 ip-protocol=TCP:80 格式。 公开的端口必须与实际应用在容器内公开的端口相同。
    • PROJECT:您的项目的名称。
  6. 如需验证配置的 ELB,请确认每个已创建对象的 Ready 条件。通过向 VIP 发送 curl 请求来验证流量:

    1. 如需获取分配的 VIP,请描述转发规则:

      gdcloud compute forwarding-rules describe FORWARDING_RULE_EXTERNAL_NAME
      
    2. 通过向转发规则中 PROTOCOL_PORT 字段指定的端口上的 VIP 发送 curl 请求来验证流量:

      curl http://FORWARDING_RULE_VIP:PORT
      

      替换以下内容:

      • FORWARDING_RULE_VIP:转发规则的 VIP。
      • PORT:转发规则中 PROTOCOL_PORT 字段的端口号。

API

使用 KRM API 创建以 pod 工作负载为目标的 ELB。此 ELB 以项目中与 Backend 对象中定义的标签匹配的所有工作负载为目标。如需使用 KRM API 创建可用区级 ELB,请按以下步骤操作:

  1. 为了使 ELB 服务正常运行,您必须在政策中配置并应用自己的自定义 ProjectNetworkPolicy 数据转移,以允许流量流向此 ELB 服务的工作负载。网络政策控制对工作负载的访问,而不是负载均衡器本身。ELB 会将工作负载公开给客户网络,因此需要明确的网络政策来允许外部流量流向工作负载端口(例如 8080)。

    指定外部 CIDR 地址以允许流量流向此 ELB 的工作负载:

    kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF
    apiVersion: networking.global.gdc.goog/v1
    kind: ProjectNetworkPolicy
    metadata:
      namespace: PROJECT
      name: allow-inbound-traffic-from-external
    spec:
      policyType: Ingress
      subject:
        subjectType: UserWorkload
      ingress:
      - from:
        - ipBlock:
            cidr: CIDR
        ports:
        - protocol: TCP
          port: PORT
    EOF
    

    替换以下内容:

    • GLOBAL_API_SERVER:全局 API 服务器的 kubeconfig 路径的 kubeconfig 路径。如果您尚未为全局 API 服务器生成 kubeconfig 文件,请参阅手动生成 kubeconfig 文件了解详情。
    • PROJECT:您的项目的名称。
    • CIDR:需要从哪个外部 CIDR 访问 ELB。此政策是必需的,因为外部负载均衡器使用直接服务器返回 (DSR),该模式会保留来源外部 IP 地址,并在返回路径上绕过负载均衡器。如需了解详情,请参阅为跨组织流量创建全球入站防火墙规则
    • PORT:负载平衡器后面的 pod 上的后端端口。此值位于 Service 资源的清单的 .spec.ports[].targetPortfield 字段中。此字段是可选字段。
  2. 创建 Backend 资源以定义 ELB 的端点。为放置工作负载的每个可用区创建 Backend 资源:

    kubectl --kubeconfig MANAGEMENT_API_SERVER apply -f - <<EOF
    apiVersion: networking.gdc.goog/v1
    kind: Backend
    metadata:
      namespace: PROJECT
      name: BACKEND_NAME
    spec:
      clusterName: CLUSTER_NAME
      endpointsLabels:
        matchLabels:
          app: APP_NAME
    EOF
    

    替换以下内容:

    • MANAGEMENT_API_SERVER:区域管理 API 服务器的 kubeconfig 路径。如果您尚未为目标可用区中的 API 服务器生成 kubeconfig 文件,请参阅手动生成 kubeconfig 文件了解详情。
    • PROJECT:您的项目的名称。
    • BACKEND_NAMEBackend 资源的名称。
    • CLUSTER_NAME:定义的选择器范围所限定的 Kubernetes 集群。如果未指定此字段,则会选择具有指定标签的所有端点。此字段是可选字段。
    • APP_NAME:容器应用的名称。

    您可以为每个可用区使用相同的 Backend 资源,也可以为每个可用区创建具有不同标签集的 Backend 资源。

  3. 使用之前创建的 Backend 资源创建一个 BackendService 对象:

    kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF
    apiVersion: networking.global.gdc.goog/v1
    kind: BackendService
    metadata:
      namespace: PROJECT
      name: BACKEND_SERVICE_NAME
    spec:
      backendRefs:
      - name: BACKEND_NAME
        zone: ZONE
      healthCheckName: HEALTH_CHECK_NAME
    EOF
    

    替换以下内容:

    • BACKEND_SERVICE_NAME:为 BackendService 资源选择的名称。
    • HEALTH_CHECK_NAME:您之前创建的 HealthCheck 资源的名称。如果您要为 Pod 工作负载配置 ELB,请勿添加此字段。
    • ZONEBackend 资源所在的可用区。您可以在 backendRefs 字段中指定多个后端。例如:
    - name: my-backend-1
      zone: us-east1-a
    - name: my-backend-2
      zone: us-east1-b
    

  4. 创建外部 ForwardingRule 资源,用于定义服务可用的 VIP。

    kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF
    apiVersion: networking.global.gdc.goog/v1
    kind: ForwardingRuleExternal
    metadata:
      namespace: PROJECT
      name: FORWARDING_RULE_EXTERNAL_NAME
    spec:
      cidrRef: CIDR
      ports:
      - port: PORT
        protocol: PROTOCOL
      backendServiceRef:
        name: BACKEND_SERVICE_NAME
    EOF
    

    替换以下内容:

    • FORWARDING_RULE_EXTERNAL_NAME:为 ForwardingRuleExternal 资源选择的名称。
    • CIDR:要用于转发规则的 CIDR。此字段是可选字段。 如果未指定,系统会自动从全局 IP 地址池中预留一个 IPv4/32 CIDR。指定与相应转发规则位于同一命名空间中的 Subnet 资源的名称。Subnet 资源表示全球子网的请求和分配信息。如需详细了解 Subnet 资源,请参阅管理子网
    • PORT:转发规则上要公开的端口。使用 ports 字段可指定一个 L4 端口数组,系统会将数据包转发到通过此转发规则配置的后端。必须至少指定一个端口。使用 port 字段指定端口号。公开的端口必须与实际应用在容器内公开的端口相同。
    • PROTOCOL:用于转发规则的协议,例如 TCPports 数组中的条目必须如下所示:
    ports:
    - port: 80
      protocol: TCP
    
  5. 如需验证配置的 ELB,请确认每个已创建对象的 Ready 条件。尝试使用 curl 请求向 VIP 发送流量并进行测试。

    1. 检索项目的 VIP:

      kubectl get forwardingruleexternal -n PROJECT
      

      输出如下所示:

      NAME           BACKENDSERVICE                  CIDR              READY
      elb-name       BACKEND_SERVICE_NAME            192.0.2.0/32      True
      
    2. 通过向转发规则中 PORT 字段指定的端口上的 VIP 发出 curl 请求来验证流量:

      curl http://FORWARDING_RULE_VIP:PORT
      

      FORWARDING_RULE_VIP:PORT 替换为转发规则的 VIP 和端口,例如 192.0.2.0:80

将容器工作负载部署到每个可用区集群

容器工作负载不是全球性资源,这意味着您必须将每个容器应用分别部署到区域 Kubernetes 集群中。

  1. 登录托管 Kubernetes 集群的可用区:

    gdcloud config set core/zone ZONE
    
  2. 验证您的容器映像是否可从受管理的 Harbor 注册表中获取。如需了解详情,请参阅部署容器应用教程。

  3. 为您的容器工作负载创建清单文件,并将其部署到区域 Kubernetes 集群:

    kubectl --kubeconfig KUBERNETES_CLUSTER -n PROJECT \
        apply -f - <<EOF
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: DEPLOYMENT_NAME
    spec:
      replicas: NUMBER_OF_REPLICAS
      selector:
        matchLabels:
          run: APP_NAME
      template:
        metadata:
          labels:
            run: APP_NAME
        spec:
          containers:
          - name: CONTAINER_NAME
            image: HARBOR_INSTANCE_URL/HARBOR_PROJECT_NAME/IMAGE:TAG
    EOF
    

    替换以下内容:

    • KUBERNETES_CLUSTER:您要将容器工作负载部署到的区域 Kubernetes 集群的 kubeconfig 文件。如果您尚未为区域 Kubernetes 集群生成 kubeconfig 文件,请参阅手动生成 kubeconfig 文件了解详情。
    • PROJECT:用于部署容器工作负载的项目命名空间。
    • DEPLOYMENT_NAME:容器部署的名称。
    • NUMBER_OF_REPLICAS:部署管理的复制 Pod 对象的数量。
    • APP_NAME:要在部署中运行的应用的名称。
    • CONTAINER_NAME:容器的名称。
    • HARBOR_INSTANCE_URL:Harbor 实例的网址,例如 harbor-1.org-1.zone1.google.gdc.test.。如需检索 Harbor 实例的网址,请参阅查看 Harbor 注册表实例
    • HARBOR_PROJECT_NAME:Harbor 项目的名称,例如 my-project
    • IMAGE:映像的名称,例如 nginx
    • TAG:要拉取的映像版本的标记,例如 1.0
  4. 针对 GDC 宇宙中的每个可用区重复执行上述步骤。确保您的容器应用位于您希望实现高可用性策略的每个可用区中。

使用 Kubernetes 公开容器应用

您必须公开容器应用,以便 GDC 环境中的其他资源可以访问该应用。

  1. 创建 type: LoadBalancerService 资源。此资源通过网络公开应用的 pod。

    kubectl --kubeconfig KUBERNETES_CLUSTER -n PROJECT \
    apiVersion: v1
    kind: Service
    metadata:
      name: SERVICE_NAME
    spec:
      selector:
        app: APP_NAME
      ports:
        - port: 80
          protocol: TCP
      type: LoadBalancer
    EOF
    

    替换以下内容:

    • KUBERNETES_CLUSTER:您要将容器工作负载部署到的区域 Kubernetes 集群的 kubeconfig 文件。
    • PROJECT:容器工作负载所在的项目的命名空间。
    • SERVICE_NAME:负载均衡器服务的名称。
    • APP_NAME:您为容器应用添加的标签。
  2. 创建 NetworkPolicy 自定义资源,以允许所有网络流量流向默认命名空间:

    kubectl --kubeconfig KUBERNETES_CLUSTER -n PROJECT \
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      annotations:
      name: allow-all
    spec:
      ingress:
      - from:
        - ipBlock:
            cidr: 0.0.0.0/0
      podSelector: {}
      policyTypes:
      - Ingress
    EOF
    

为 Pod 预配永久性存储空间

您必须创建 PersistentVolumeClaim 资源 (PVC),才能为应用 pod 提供持久性存储空间。

以下说明展示了如何使用 GDC standard-rwo StorageClass 创建卷。

  1. 创建 PersistentVolumeClaim 资源。例如,使用 ReadWriteOnce 访问模式和 standard-rwo 存储类对其进行配置:

    kubectl --kubeconfig KUBERNETES_CLUSTER \
        --namespace PROJECT apply -f - <<EOF
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: PVC_NAME
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 10Gi
      storageClassName: standard-rwo
    EOF
    

    替换以下内容:

    • KUBERNETES_CLUSTER:Kubernetes 集群的 kubeconfig 文件。
    • PROJECT:用于创建 PVC 的项目命名空间。
    • PVC_NAMEPersistentVolumeClaim 对象的名称。
  2. PersistentVolume (PV) 对象是动态预配的。检查 Kubernetes 集群中新 PV 的状态:

    kubectl get pv --kubeconfig KUBERNETES_CLUSTER
    

    输出类似于以下内容:

    NAME       CAPACITY   ACCESS MODES   STATUS      CLAIM     STORAGECLASS   AGE
    pvc-uuidd  10Gi       RWO            Bound       pvc-name  standard-rwo   60s
    
  3. 将容器工作负载配置为使用 PVC。以下是使用 standard-rwo PVC 的 pod 清单示例:

    kubectl --kubeconfig KUBERNETES_CLUSTER \
        --namespace PROJECT apply -f - <<EOF
    apiVersion: apps/v1
    kind: Pod
    metadata:
      name: web-server-deployment
      labels:
        app: APP_LABEL
    spec:
      containers:
      - name: CONTAINER_NAME
        image: HARBOR_INSTANCE_URL/HARBOR_PROJECT_NAME/IMAGE:TAG
        volumeMounts:
        - mountPath: MOUNT_PATH
          name: data
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: PVC_NAME
    EOF
    

    替换以下内容:

    • KUBERNETES_CLUSTER:您要将容器工作负载部署到的 Kubernetes 集群的 kubeconfig 文件。
    • PROJECT:PVC 所在的项目的命名空间。
    • APP_LABEL:您为容器应用添加的标签。
    • CONTAINER_NAME:容器的名称。
    • HARBOR_INSTANCE_URL:Harbor 实例的网址,例如 harbor-1.org-1.zone1.google.gdc.test.。如需检索 Harbor 实例的网址,请参阅查看 Harbor 注册表实例
    • HARBOR_PROJECT_NAME:Harbor 项目的名称,例如 my-project
    • IMAGE:映像的名称,例如 nginx
    • TAG:要拉取的映像版本的标记,例如 1.0
    • MOUNT_PATH:用于装载卷的 pod 内部路径。
    • PVC_NAME:您创建的 PVC。

配置异步存储复制

GDC 多可用区宇宙支持以异步模式使用复制的存储资源(例如卷和存储分区),以应对灾难恢复场景。这些存储资源选项可在同一区域中的任意两个可用区之间提供异步数据复制。异步复制在后台进行,可在发生灾难时提供较低但非零的恢复点目标 (RPO)。所有复制的数据都处于在线状态,可立即访问,但可能需要执行手动故障切换程序才能在次要可用区中写入数据。

您可以为容器应用选择以下异步存储复制类型之一:

创建用于对象存储的双区域存储桶

对象存储数据会写入单个存储桶,该存储桶的数据存储在两个可用区中。由于数据是跨可用区异步复制的,因此在任何时间点,可用区可能不会包含相同的对象版本,但如果未进行其他更改,最终会变得相同。与卷复制不同,复制的存储分区在可用区发生分区时可写入。每次写入对象都会生成不同的版本,并且在恢复连接后,任一可用区中的最新版本都将成为最终状态。

  1. 验证您的基础设施运算符 (IO) 是否已创建 BucketLocationConfig 自定义资源,这是在对象存储的可用区之间进行异步复制所必需的。此资源必须部署到根全局 API 服务器。

  2. 创建双区域 Bucket 自定义资源:

    kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF
    apiVersion: object.global.gdc.goog/v1
    kind: Bucket
    metadata:
      name: BUCKET_NAME
      namespace: PROJECT
    spec:
      location: LOCATION_NAME
      description: Sample DZ Bucket
      storageClass: Standard
    EOF
    

    替换以下内容:

    • GLOBAL_API_SERVER:全局 API 服务器的 kubeconfig 文件。
    • BUCKET_NAME:存储桶的名称。
    • PROJECT:存储桶所在的项目的名称。
    • LOCATION_NAME:存储桶中的对象数据所在的物理位置。此值必须映射到现有 BucketLocation 资源的名称。如需查询组织的全球 API 服务器以获取可用 BucketLocation 资源的列表,请运行 kubectl --kubeconfig GLOBAL_API_SERVER bucketlocations。 如果没有 BucketLocation 资源,请与您的 IO 联系,验证他们是否已启用异步复制。

配置跨可用区的异步块存储复制

复制的块存储提供异步复制的卷 (PV),可在主卷和辅助卷之间保持块等效性。由于异步特性,辅助卷反映的是主可用区在过去某个时间点(非零 RPO)的状态。在辅助卷仍为复制目标时,无法装载该卷,需要手动干预才能终止关系并启用写入操作。

您必须配置跨可用区的存储复制关系,才能创建可用于故障切换的复制数据(如果源可用区数据不可用)。如果您要为容器应用使用块存储,则此信息非常重要。

在开始之前,请验证您的基础设施运维人员 (IO) 是否已创建并配置 StorageClusterPeeringStorageVirtualMachinePeering 自定义资源,以允许跨可用区进行块存储复制。此资源必须部署到根全局 API 服务器。

  1. 创建 VolumeReplicationRelationship 自定义资源 YAML 文件并将其部署到全局 API 服务器:

    kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF
    apiVersion: storage.global.gdc.goog/v1
    kind: VolumeReplicationRelationship
    metadata:
      name: PVC_REPL_NAME
      namespace: PROJECT
    spec:
      source:
        pvc:
          clusterRef: SOURCE_PVC_CLUSTER
          pvcRef: SOURCE_PVC
        zoneRef: SOURCE_ZONE
    destination:
        pvc:
          clusterRef: DEST_PVC_CLUSTER
        zoneRef: DEST_ZONE
    EOF
    

    替换以下内容:

    • GLOBAL_API_SERVER:全局 API 服务器的 kubeconfig 文件。
    • PVC_REPL_NAME:卷复制关系的名称。
    • PROJECT:存储基础设施所在的项目。
    • SOURCE_PVC_CLUSTER:托管 PVC 的 Kubernetes 集群。
    • SOURCE_PVC:要复制的来源可用区中的 PVC。
    • SOURCE_ZONE:PVC 所在的源可用区。
    • DEST_PVC_CLUSTER:要将 PVC 复制到的目标 Kubernetes 集群。
    • DEST_ZONE:要将 PVC 复制到的目标可用区。
  2. 在目标可用区中创建一个 VolumeFailover 自定义资源,如果源可用区因任何原因而不可用,该资源会停止向目标可用区复制:

    kubectl --kubeconfig MANAGEMENT_API_SERVER apply -f - <<EOF
    apiVersion: storage.gdc.goog/v1
    kind: VolumeFailover
    metadata:
      name: PVC_FAILOVER_NAME
      namespace: PROJECT
    spec:
      volumeReplicationRelationshipRef: PVC_REPL_NAME
    EOF
    

    替换以下内容:

    • MANAGEMENT_API_SERVER:区域管理 API 服务器的 kubeconfig 文件。
    • PVC_FAILOVER_NAME:PVC 故障切换的名称。
    • PROJECT:存储基础设施所在的项目。
    • PVC_REPL_NAME:卷复制关系的名称。

后续步骤