部署高可用性虚拟机应用

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

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

目标

  • 在 GDC 范围内创建具有已挂接启动磁盘的虚拟机实例,该实例位于两个或更多可用区中。
  • 配置全球负载均衡。
  • 使用块存储或对象存储配置异步存储复制。

准备工作

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

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

    • 用于创建和管理虚拟机工作负载的虚拟机角色
    • Load Balancer Admin (load-balancer-admin) 和 Global Load Balancer Admin (global-load-balancer-admin) 角色。您必须拥有这些角色才能创建和管理负载平衡器。
    • Volume Replication Global Admin 角色 (app-volume-replication-admin-global)。您必须拥有此角色才能管理卷复制。
    • Global PNP Admin (global-project-networkpolicy-admin) 角色。您必须拥有此角色,才能跨可用区创建和管理项目网络政策。
    • 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 服务器设置适当的 kubeconfig 文件。如需了解详情,请参阅手动生成 kubeconfig 文件

在多个可用区中创建虚拟机实例

虚拟机实例是可用区级资源,因此您必须在每个可用区中单独创建虚拟机。在此示例中,您将使用 GDC 提供的操作系统映像创建虚拟机实例,并将启动磁盘挂接到该虚拟机。如需详细了解如何创建虚拟机实例以及使用自定义映像,请参阅创建并启动虚拟机

默认情况下,所有 GDC 项目都可以使用 GDC 提供的操作系统映像创建虚拟机。

控制台

  1. 在导航菜单中,选择虚拟机 > 实例
  2. 点击创建实例
  3. 名称字段中,指定虚拟机的名称。
  4. 选择要在其中创建虚拟机的可用区。
  5. 点击添加标签,为虚拟机分配任意标签,以帮助整理虚拟机实例。
  6. 选择要用于虚拟机的机器配置。根据您的要求,验证机器类型是否与您的工作负载相符。
  7. 点击下一步
  8. 为虚拟机实例启用外部访问权限。
  9. 点击下一步
  10. 选择添加新磁盘
  11. 为您的虚拟机磁盘分配名称。
  12. 配置磁盘大小和连接设置。
  13. 点击保存
  14. 点击创建以创建虚拟机实例。
  15. 针对 GDC 宇宙中的每个可用区重复执行上述步骤。确保虚拟机实例位于您希望在 HA 策略中使用的每个可用区中。

gdcloud

  1. 登录到您要托管虚拟机实例的可用区:

    gdcloud config set core/zone ZONE
    
  2. 使用 GDC 提供的映像在可用区中创建虚拟机实例:

    gdcloud compute instances create VM_NAME \
        --machine-type=MACHINE_TYPE \
        --image=BOOT_DISK_IMAGE_NAME
        --image-project=vm-system \
        --boot-disk-size=BOOT_DISK_SIZE \
        --no-boot-disk-auto-delete=NO_BOOT_DISK_AUTO_DELETE
    

    替换以下内容:

    • VM_NAME:新虚拟机的名称。名称只能包含字母数字字符和短划线,且长度不得超过 53 个字符。
    • MACHINE_TYPE:新虚拟机的预定义机器类型。如需选择可用的机器类型,请运行 gdcloud compute machine-types list
    • BOOT_DISK_IMAGE_NAME:要用于新虚拟机启动磁盘的映像的名称。
    • BOOT_DISK_SIZE:启动磁盘的大小,例如 20GB。此值必须始终大于或等于启动磁盘映像的 minimumDiskSize
    • NO_BOOT_DISK_AUTO_DELETE:在删除虚拟机实例时是否自动删除启动磁盘。
  3. 针对 GDC 宇宙中的每个可用区重复执行上述步骤。确保每个您希望纳入高可用性策略的可用区中都有一个虚拟机实例。

API

  1. 使用 GDC 提供的映像在可用区中创建虚拟机实例:

    kubectl --kubeconfig MANAGEMENT_API_SERVER apply -f - <<EOF
    apiVersion: virtualmachine.gdc.goog/v1
    kind: VirtualMachineDisk
    metadata:
      name: VM_BOOT_DISK_NAME
      namespace: PROJECT
    spec:
      source:
        image:
          name: BOOT_DISK_IMAGE_NAME
          namespace: vm-system
      size: BOOT_DISK_SIZE
    ---
    apiVersion: virtualmachine.gdc.goog/v1
    kind: VirtualMachine
    metadata:
      name: VM_NAME
      namespace: PROJECT
    spec:
      compute:
        virtualMachineType: MACHINE_TYPE
      disks:
        - virtualMachineDiskRef:
            name: VM_BOOT_DISK_NAME
          boot: true
          autoDelete: BOOT_DISK_AUTO_DELETE
    ---
    apiVersion: virtualmachine.gdc.goog/v1
    kind: VirtualMachineExternalAccess
    metadata:
      name: VM_NAME
      namespace: PROJECT
    spec:
      enabled: true
      ports:
      - name: port-80
        port: 80
        protocol: TCP
    EOF
    

    替换以下内容:

    • MANAGEMENT_API_SERVER:要在其中创建虚拟机实例的区域的管理 API 服务器 kubeconfig 文件。如果您尚未为 Management API 服务器生成 kubeconfig 文件,请参阅手动生成 kubeconfig 文件了解详情。
    • VM_BOOT_DISK_NAME:新虚拟机启动磁盘的名称。
    • PROJECT:用于创建虚拟机的 GDC 项目。
    • BOOT_DISK_IMAGE_NAME:要用于新虚拟机启动磁盘的映像的名称。
    • BOOT_DISK_SIZE:启动磁盘的大小,例如 20Gi。此值必须始终大于或等于启动磁盘映像的 minimumDiskSize
    • VM_NAME:新虚拟机的名称。名称只能包含字母数字字符和短划线,且长度不得超过 53 个字符。
    • MACHINE_TYPE:新虚拟机的预定义机器类型。如需选择可用的机器类型,请运行 gdcloud compute machine-types list
    • BOOT_DISK_AUTO_DELETE:在删除虚拟机实例时是否自动删除启动磁盘。
  2. 验证虚拟机是否可用,并等待虚拟机显示 Running 状态。Running 状态并不表示操作系统已完全准备就绪并可供访问。

    kubectl --kubeconfig MANAGEMENT_API_SERVER \
        get virtualmachine.virtualmachine.gdc.goog VM_NAME -n PROJECT
    

    VM_NAMEPROJECT 替换为虚拟机的名称和项目。

  3. 针对 GDC 宇宙中的每个可用区重复执行上述步骤。确保每个您希望纳入高可用性策略的可用区中都有一个虚拟机实例。

配置负载平衡器

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

创建全球内部负载均衡器

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

完成以下步骤,为您的虚拟机工作负载创建全球 ILB。

gdcloud

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

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

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

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

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

    替换以下内容:

    • BACKEND_NAME:为后端资源选择的名称,例如 my-backend
    • LABELS:用于定义虚拟机之间要用于此后端资源的端点的选择器,例如 app=web
    • PROJECT:您的项目的名称。
    • ZONE:要用于此调用的可用区。如需为需要设置时区的全部命令预设时区标志,请运行 gdcloud config set core/zone ZONE。可用区标志仅在多可用区环境中可用。此字段是可选字段。

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

  2. 为 ILB 定义全局健康检查:

    gdcloud compute health-checks create tcp HEALTH_CHECK_NAME \
        --check-interval=CHECK_INTERVAL \
        --healthy-threshold=HEALTHY_THRESHOLD \
        --timeout=TIMEOUT \
        --unhealthy-threshold=UNHEALTHY_THRESHOLD \
        --port=PORT \
        --global
    

    替换以下内容:

    • HEALTH_CHECK_NAME:健康检查资源的名称,例如 my-health-check
    • CHECK_INTERVAL:从一次探测开始到下一次探测开始之间的时间量(以秒为单位)。默认值为 5。此字段是可选字段。
    • HEALTHY_THRESHOLD:在声明失败之前等待的时间。默认值为 5。此字段是可选字段。
    • TIMEOUT:在声明失败之前等待的时间量(以秒为单位)。默认值为 5。此字段是可选字段。
    • UNHEALTHY_THRESHOLD:要将端点视为运行状况不佳所必须失败的连续探测次数。默认值为 2。此字段是可选字段。
    • PORT:执行健康检查的端口。默认值为 80。此字段是可选字段。
  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-zone=ZONE \
        --backend=BACKEND_NAME \
        --project=PROJECT \
        --global
    

    替换以下内容:

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

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

  5. 创建内部 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 格式。公开的端口必须与虚拟机内实际应用公开的端口相同。
  6. 如需验证配置的 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:
      endpointsLabels:
        matchLabels:
          app: APP_NAME
    EOF
    

    替换以下内容:

    • MANAGEMENT_API_SERVER:区域管理 API 服务器的 kubeconfig 路径。如需了解详情,请参阅切换到地区性上下文
    • PROJECT:您的项目的名称。
    • BACKEND_NAMEBackend 资源的名称。
    • APP_NAME:虚拟机应用的名称。

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

  2. 为 ILB 定义全局健康检查:

    kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF
    apiVersion: networking.global.gdc.goog/v1
    kind: HealthCheck
    metadata:
      namespace: PROJECT
      name: HEALTH_CHECK_NAME
    spec:
      tcpHealthCheck:
        port: PORT
      timeoutSec: TIMEOUT
      checkIntervalSec: CHECK_INTERVAL
      healthyThreshold: HEALTHY_THRESHOLD
      unhealthyThreshold: UNHEALTHY_THRESHOLD
    EOF
    

    替换以下内容:

    • GLOBAL_API_SERVER:全局 API 服务器的 kubeconfig 路径的 kubeconfig 路径。如需了解详情,请参阅切换到全局上下文
    • PROJECT:您的项目的名称。
    • HEALTH_CHECK_NAME:健康检查资源的名称,例如 my-health-check
    • PORT:执行健康检查的端口。默认值为 80
    • TIMEOUT:在声明失败之前等待的时间量(以秒为单位)。默认值为 5
    • CHECK_INTERVAL:从一次探测开始到下一次探测开始之间的时间量(以秒为单位)。默认值为 5
    • HEALTHY_THRESHOLD:要将端点视为运行状况良好必须通过的连续探测次数。默认值为 2
    • UNHEALTHY_THRESHOLD:要将端点视为运行状况不佳所必须失败的连续探测次数。默认值为 2
  3. 使用之前创建的 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
      
  4. 创建内部 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
      
  5. 如需验证配置的 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:负载平衡器后面的虚拟机上的后端端口。此值位于 Service 资源的清单的 .spec.ports[].targetPortfield 字段中。此字段是可选字段。

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

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

    gdcloud compute backends create BACKEND_NAME \
      --labels=LABELS \
      --project=PROJECT
    

    替换以下内容:

    • BACKEND_NAME:后端资源的名称,例如 my-backend
    • LABELS:一个选择器,用于定义要为此后端资源使用哪些虚拟机之间的端点,例如 app=web
    • PROJECT:您的项目的名称。

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

  3. 为 ELB 定义全局健康检查:

    gdcloud compute health-checks create tcp HEALTH_CHECK_NAME \
      --check-interval=CHECK_INTERVAL \
      --healthy-threshold=HEALTHY_THRESHOLD \
      --timeout=TIMEOUT \
      --unhealthy-threshold=UNHEALTHY_THRESHOLD \
      --port=PORT \
      --global
    

    替换以下内容:

    • HEALTH_CHECK_NAME:健康检查资源的名称,例如 my-health-check
    • CHECK_INTERVAL:从一次探测开始到下一次探测开始之间的时间量(以秒为单位)。默认值为 5。此字段是可选字段。
    • HEALTHY_THRESHOLD:在声明失败之前等待的时间。默认值为 5。此字段是可选字段。
    • TIMEOUT:在声明失败之前等待的时间(以秒为单位)。默认值为 5。此字段是可选字段。
    • UNHEALTHY_THRESHOLD:要将端点视为运行状况不佳所必须失败的连续探测次数。默认值为 2。此字段是可选字段。
    • PORT:执行健康检查的端口。 默认值为 80。此字段是可选字段。
  4. 创建全局 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:健康检查资源的名称。此字段是可选字段。
  5. 将全局 BackendService 资源添加到之前创建的区域级 Backend 资源:

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

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

  6. 创建外部 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:您的项目的名称。
  7. 如需验证配置的 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 创建以虚拟机工作负载为目标的 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:负载平衡器后面的虚拟机上的后端端口。此值位于 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:
      endpointsLabels:
        matchLabels:
          app: server
    EOF
    

    替换以下内容:

    • MANAGEMENT_API_SERVER:区域管理 API 服务器的 kubeconfig 路径。如果您尚未为目标可用区中的 API 服务器生成 kubeconfig 文件,请参阅手动生成 kubeconfig 文件了解详情。
    • PROJECT:您的项目的名称。
    • BACKEND_NAMEBackend 资源的名称。

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

  3. 为 ELB 定义全局健康检查:

    kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF
    apiVersion: networking.global.gdc.goog/v1
    kind: HealthCheck
    metadata:
      namespace: PROJECT
      name: HEALTH_CHECK_NAME
    spec:
      tcpHealthCheck:
        port: PORT
      timeoutSec: TIMEOUT
      checkIntervalSec: CHECK_INTERVAL
      healthyThreshold: HEALTHY_THRESHOLD
      unhealthyThreshold: UNHEALTHY_THRESHOLD
    EOF
    

    替换以下内容:

    • HEALTH_CHECK_NAME:健康检查资源的名称,例如 my-health-check
    • PORT:执行健康检查的端口。 默认值为 80
    • TIMEOUT:在声明失败之前等待的时间(以秒为单位)。默认值为 5
    • CHECK_INTERVAL:从一次探测开始到下一次探测开始之间的时间量(以秒为单位)。默认值为 5
    • HEALTHY_THRESHOLD:要将端点视为运行状况良好必须通过的连续探测次数。默认值为 2
    • UNHEALTHY_THRESHOLD:要将端点视为运行状况不佳所必须失败的连续探测次数。默认值为 2

    由于这是全局 ELB,因此请在全局 API 中创建健康检查。

  4. 使用之前创建的 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
    
  5. 创建外部 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
    
  6. 如需验证配置的 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

配置异步存储复制

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)的状态。在辅助卷仍为复制目标时,无法装载该卷,需要手动干预才能终止关系并启用写入操作。

您必须向全局 API 服务器部署VolumeReplicationRelationship自定义资源,以创建可用于故障切换的复制数据(如果源地区数据变得不可用)。

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

gdcloud

  1. 设置主要可用区和次要可用区之间的异步复制卷关系:

    gdcloud compute disks start-async-replication PRIMARY_DISK_NAME \
        --project PROJECT \
        --zone PRIMARY_ZONE \
        --secondary-disk SECONDARY_DISK_NAME \
        --secondary-zone SECONDARY_ZONE
    

    替换以下内容:

    • PRIMARY_DISK_NAME:正在复制的源磁盘的名称。
    • PROJECT:主磁盘的 GDC 项目。
    • PRIMARY_ZONE:主磁盘所在的可用区。
    • SECONDARY_DISK_NAME:要复制到的目标磁盘的名称。
    • SECONDARY_ZONE:辅助磁盘必须驻留的可用区。
  2. 在目标可用区中创建 VolumeFailover 自定义资源,如果源可用区因任何原因而不可用,该资源会停止复制到目标可用区:

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

    替换以下内容:

    • MANAGEMENT_API_SERVER:管理 API 服务器的 kubeconfig 文件。
    • FAILOVER_NAME:故障切换的名称。
    • PROJECT:存储基础架构所在的项目。
    • REPL_NAME:卷复制关系的名称。

    如需详细了解如何管理虚拟机工作负载的异步复制,请参阅异步复制卷

API

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

    kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF
    apiVersion: storage.global.gdc.goog/v1
    kind: VolumeReplicationRelationship
    metadata:
      name: VRR_NAME
      namespace: PROJECT
    spec:
      source:
        virtualMachineDisk:
          virtualMachineDiskRef: PRIMARY_DISK_NAME
        zoneRef: PRIMARY_ZONE
      destination:
        volumeOverrideName: SECONDARY_DISK_NAME
        zoneRef: SECONDARY_ZONE
    EOF
    

    替换以下内容:

    • GLOBAL_API_SERVER:全局管理 API 服务器的 kubeconfig 文件。
    • VRR_NAME:卷复制关系的名称。停止异步复制时必须使用相同的名称。
    • PROJECT:主磁盘的 GDC 项目。
    • PRIMARY_DISK_NAME:正在复制的源磁盘的名称。
    • PRIMARY_ZONE:主磁盘所在的可用区。
    • SECONDARY_DISK_NAME:要复制到的目标磁盘的名称。
    • SECONDARY_ZONE:辅助磁盘必须所在的可用区。
  2. 在目标可用区中创建 VolumeFailover 自定义资源,如果源可用区因任何原因而不可用,该资源会停止复制到目标可用区:

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

    替换以下内容:

    • MANAGEMENT_API_SERVER:管理 API 服务器的 kubeconfig 文件。
    • FAILOVER_NAME:故障切换的名称。
    • PROJECT:存储基础架构所在的项目。
    • REPL_NAME:卷复制关系的名称。

如需详细了解如何管理虚拟机工作负载的异步复制,请参阅异步复制卷

后续步骤