Implantar um aplicativo de VM altamente disponível

Esta página apresenta a estratégia de implantação recomendada para criar um aplicativo de máquina virtual (VM) robusto e de alta disponibilidade (HA) no Google Distributed Cloud (GDC) isolado por air-gap. É necessário implantar o aplicativo de VM em várias zonas do GDC e configurar a replicação de armazenamento assíncrona para que o aplicativo e os dados possam ser recuperados em caso de inatividade inesperada ou desastre local.

Esta página é destinada a desenvolvedores do grupo de operadores de aplicativos, que são responsáveis por criar cargas de trabalho de aplicativos para a organização. Para mais informações, consulte Públicos-alvo para documentação isolada do GDC.

Objetivos

  • Crie uma instância de VM com discos de inicialização anexados em duas ou mais zonas no seu universo do GDC.
  • Configure o balanceamento de carga global.
  • Configure a replicação assíncrona de armazenamento usando armazenamento de blocos ou de objetos.

Antes de começar

  • Verifique se você está trabalhando em um universo do GDC com várias zonas disponíveis. Execute gdcloud zones list para listar as zonas disponíveis no seu universo. Para mais informações, consulte Listar zonas em um universo.

  • Peça ao administrador do IAM da organização para conceder a você os seguintes papéis:

    • Os papéis de VM para criar e gerenciar cargas de trabalho de VM.
    • Os papéis "Administrador do balanceador de carga" (load-balancer-admin) e "Administrador do balanceador de carga global" (global-load-balancer-admin). Você precisa ter essas funções para criar e gerenciar balanceadores de carga.
    • A função de administrador global da replicação de volume (app-volume-replication-admin-global). É necessário ter essa função para administrar a replicação de volume.
    • O papel de administrador global do PNP (global-project-networkpolicy-admin). Você precisa ter essa função para criar e gerenciar políticas de rede do projeto em todas as zonas.
    • A função de administrador global da replicação de volume (app-volume-replication-admin-global) para administrar a relação de replicação de volume para recursos de armazenamento em blocos.
    • Os papéis Administrador de objetos do bucket do projeto (project-bucket-object-admin) e Administrador do bucket do projeto (project-bucket-admin) para criar e gerenciar buckets de armazenamento.

    Consulte as descrições de papéis para mais informações.

  • Instale e configure a CLI gdcloud e configure os contextos zonal e global. Consulte Gerenciar recursos em várias zonas para mais informações.

  • Instale e configure a CLI kubectl com os arquivos kubeconfig adequados definidos para o servidor da API global e o servidor da API Management. Consulte Gerar manualmente o arquivo kubeconfig para mais informações.

Criar uma instância de VM em várias zonas

Uma instância de VM é um recurso zonal. Portanto, é necessário criar uma VM separadamente em cada zona. Neste exemplo, você vai criar uma instância de VM usando uma imagem do SO fornecida pelo GDC e anexar um disco de inicialização à VM. Para mais informações sobre como criar instâncias de VM e usar imagens personalizadas, consulte Criar e iniciar uma VM.

Por padrão, todos os projetos do GDC podem criar VMs com imagens do SO fornecidas pelo GDC.

Console

  1. No menu de navegação, selecione Máquinas virtuais > Instâncias.
  2. Clique em Criar instância.
  3. No campo Nome, especifique um nome para a VM.
  4. Selecione a zona em que a VM será criada.
  5. Clique em Adicionar rótulos para atribuir rótulos à VM e ajudar a organizar as instâncias de VM.
  6. Selecione a configuração de máquina a ser usada para a VM. Verifique se o tipo de máquina está alinhado à sua carga de trabalho, dependendo dos seus requisitos.
  7. Clique em Próxima.
  8. Ative o acesso externo para sua instância de VM.
  9. Clique em Próxima.
  10. Selecione Adicionar novo disco.
  11. Atribua um nome ao disco da VM.
  12. Configure o tamanho do disco e as configurações de anexação.
  13. Clique em Salvar.
  14. Clique em Criar para gerar a instância de VM.
  15. Repita as etapas anteriores para cada zona no seu universo do GDC. Verifique se uma instância de VM reside em cada zona que você quer para sua estratégia de alta disponibilidade.

gdcloud

  1. Faça login na zona em que você quer hospedar a instância de VM:

    gdcloud config set core/zone ZONE
    
  2. Crie a instância de VM na zona usando uma imagem fornecida pelo 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
    

    Substitua:

    • VM_NAME: o nome da nova VM. O nome precisa conter apenas caracteres alfanuméricos e traços e não pode ter mais de 53 caracteres.
    • MACHINE_TYPE: o tipo de máquina predefinido para a nova VM. Para selecionar um tipo de máquina disponível, execute gdcloud compute machine-types list.
    • BOOT_DISK_IMAGE_NAME: o nome da imagem a ser usada para o disco de inicialização da nova VM.
    • BOOT_DISK_SIZE: o tamanho do disco de inicialização, como 20GB. Esse valor precisa ser sempre maior ou igual ao minimumDiskSize da imagem do disco de inicialização.
    • NO_BOOT_DISK_AUTO_DELETE: se o disco de inicialização será excluído automaticamente quando a instância de VM for excluída.
  3. Repita as etapas anteriores para cada zona no seu universo do GDC. Verifique se uma instância de VM está em cada zona que você quer para sua estratégia de alta disponibilidade.

API

  1. Crie a instância de VM na zona usando uma imagem fornecida pelo 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
    

    Substitua:

    • MANAGEMENT_API_SERVER: o arquivo kubeconfig do servidor da API Management para a zona em que a instância de VM será criada. Se você ainda não gerou um arquivo kubeconfig para o servidor da API Management, consulte Gerar manualmente o arquivo kubeconfig para mais detalhes.
    • VM_BOOT_DISK_NAME: o nome do novo disco de inicialização da VM.
    • PROJECT: o projeto do GDC em que a VM será criada.
    • BOOT_DISK_IMAGE_NAME: o nome da imagem a ser usada para o disco de inicialização da nova VM.
    • BOOT_DISK_SIZE: o tamanho do disco de inicialização, como 20Gi. Esse valor precisa ser sempre maior ou igual ao minimumDiskSize da imagem do disco de inicialização.
    • VM_NAME: o nome da nova VM. O nome precisa conter apenas caracteres alfanuméricos e traços e não pode ter mais de 53 caracteres.
    • MACHINE_TYPE: o tipo de máquina predefinido para a nova VM. Para selecionar um tipo de máquina disponível, execute gdcloud compute machine-types list.
    • BOOT_DISK_AUTO_DELETE: se o disco de inicialização será excluído automaticamente quando a instância de VM for excluída.
  2. Verifique se a VM está disponível e aguarde até que ela mostre o estado Running. O estado Running não indica que o SO está totalmente pronto e acessível.

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

    Substitua VM_NAME e PROJECT pelo nome e projeto da VM.

  3. Repita as etapas anteriores para cada zona no seu universo do GDC. Verifique se uma instância de VM está em cada zona que você quer para sua estratégia de alta disponibilidade.

Configurar balanceadores de carga

Para distribuir o tráfego entre as VMs em diferentes zonas, crie balanceadores de carga. Você pode criar balanceadores de carga externos (ELB) e balanceadores de carga internos (ILB), que podem ser configurados por zona ou globalmente. Para este exemplo, configure um ILB global e um ELB global para seu aplicativo de VM.

Criar um balanceador de carga interno global

Os balanceadores de carga internos (ILB, na sigla em inglês) expõem serviços dentro da organização de um pool de endereços IP internos atribuído a ela. Um serviço ILB nunca é acessível de qualquer endpoint fora da organização.

Conclua as etapas a seguir para criar um ILB global para suas cargas de trabalho de VM.

gdcloud

Crie um ILB que tenha como destino cargas de trabalho de VM usando a CLI gdcloud.

Esse ILB tem como destino todas as cargas de trabalho no projeto que correspondem ao rótulo definido no objeto Backend. O recurso personalizado Backend precisa ser definido como uma zona.

Para criar um ILB usando a CLI gdcloud, siga estas etapas:

  1. Crie um recurso Backend zonal em cada zona em que as VMs estão em execução para definir o endpoint do ILB:

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

    Substitua:

    • BACKEND_NAME: o nome escolhido para o recurso de back-end, como my-backend.
    • LABELS: o seletor que define quais endpoints entre VMs usar para esse recurso de back-end, como app=web.
    • PROJECT: o nome do projeto.
    • ZONE: a zona a ser usada para essa invocação. Para predefinir a flag de zona para todos os comandos que a exigem, execute gdcloud config set core/zone ZONE. A flag de zona só está disponível em ambientes multizonais. Este campo é opcional.

    Repita essa etapa para cada zona no seu universo do GDC.

  2. Defina uma verificação de integridade global para o 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
    

    Substitua:

    • HEALTH_CHECK_NAME: o nome do recurso de verificação de integridade, como my-health-check.
    • CHECK_INTERVAL: o tempo em segundos entre o início de uma sondagem e o início da próxima. O valor padrão é 5. Este campo é opcional.
    • HEALTHY_THRESHOLD: o tempo de espera antes de declarar falha. O valor padrão é 5. Este campo é opcional.
    • TIMEOUT: o tempo em segundos para aguardar antes de declarar falha. O valor padrão é 5. Este campo é opcional.
    • UNHEALTHY_THRESHOLD: o número de sondagens sequenciais que precisam falhar para que o endpoint seja considerado não íntegro. O valor padrão é 2. Este campo é opcional.
    • PORT: a porta em que a verificação de integridade é realizada. O valor padrão é 80. Este campo é opcional.
  3. Crie um recurso BackendService global:

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

    Substitua:

    • BACKEND_SERVICE_NAME: o nome do serviço de back-end.
    • PROJECT: o nome do projeto.
    • TARGET_PORTS: uma lista separada por vírgulas de portas de destino que esse serviço de back-end traduz, em que cada porta de destino especifica o protocolo, a porta na regra de encaminhamento e a porta na instância de back-end. É possível especificar várias portas de destino. Esse campo precisa estar no formato protocol:port:targetport, como TCP:80:8080. Este campo é opcional.
    • HEALTH_CHECK_NAME: o nome do recurso de verificação de integridade. Este campo é opcional.
  4. Adicione o recurso BackendService ao recurso Backend criado anteriormente em cada zona:

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

    Substitua:

    • BACKEND_SERVICE_NAME: o nome do serviço de back-end global.
    • ZONE: a zona do back-end.
    • BACKEND_NAME: o nome do back-end zonal.
    • PROJECT: o nome do projeto.

    Conclua esta etapa para cada back-end zonal criado anteriormente.

  5. Crie um recurso ForwardingRule interno que defina o endereço IP virtual (VIP) em que o serviço está disponível:

    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
    

    Substitua:

    • FORWARDING_RULE_INTERNAL_NAME: o nome da regra de encaminhamento.
    • CIDR: o CIDR a ser usado na regra de encaminhamento. Este campo é opcional. Se não for especificado, um CIDR IPv4/32 será reservado automaticamente do pool global de endereços IP. Especifique o nome de um recurso Subnet no mesmo namespace que esta regra de encaminhamento. Um recurso Subnet representa as informações de solicitação e alocação de uma sub-rede global. Para mais informações sobre recursos Subnet, consulte Gerenciar sub-redes.
    • PROTOCOL_PORT: o protocolo e a porta a serem expostos na regra de encaminhamento. Esse campo precisa estar no formato ip-protocol=TCP:80. A porta exposta precisa ser a mesma que o aplicativo real está expondo dentro da VM.
  6. Para validar o ILB configurado, confirme a condição Ready em cada um dos objetos criados. Verifique o tráfego com uma solicitação curl para o VIP:

    1. Para receber o VIP atribuído, descreva a regra de encaminhamento:

      gdcloud compute forwarding-rules describe FORWARDING_RULE_INTERNAL_NAME --global
      
    2. Verifique o tráfego com uma solicitação curl para o VIP na porta especificada no campo da regra de encaminhamento:

      curl http://FORWARDING_RULE_VIP:PORT
      

    Substitua:

    • FORWARDING_RULE_VIP: o VIP da regra de encaminhamento.
    • PORT: o número da porta da regra de encaminhamento.

API

Crie um ILB que tenha como destino cargas de trabalho de VM usando a API KRM. Esse ILB tem como destino todas as cargas de trabalho no projeto que correspondem ao rótulo definido no objeto Backend. Para criar um ILB global usando a API KRM, siga estas etapas:

  1. Crie um recurso Backend para definir os endpoints do ILB. Crie recursos Backend para cada zona em que as cargas de trabalho da VM estão localizadas:

    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
    

    Substitua:

    • MANAGEMENT_API_SERVER: o caminho kubeconfig do servidor da API Management zonal. Para mais informações, consulte Mudar para um contexto zonal.
    • PROJECT: o nome do projeto.
    • BACKEND_NAME: o nome do recurso Backend.
    • APP_NAME: o nome do aplicativo da VM.

    Você pode usar o mesmo recurso Backend para cada zona ou criar recursos Backend com conjuntos de rótulos diferentes para cada uma.

  2. Defina uma verificação de integridade global para o 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
    

    Substitua:

    • GLOBAL_API_SERVER: o caminho kubeconfig do servidor de API global. Para mais informações, consulte Mudar para um contexto global.
    • PROJECT: o nome do projeto.
    • HEALTH_CHECK_NAME: o nome do recurso de verificação de integridade, como my-health-check.
    • PORT: a porta em que a verificação de integridade será realizada. O valor padrão é 80.
    • TIMEOUT: o tempo em segundos para aguardar antes de declarar falha. O valor padrão é 5.
    • CHECK_INTERVAL: o tempo em segundos entre o início de uma sondagem e o início da próxima. O valor padrão é 5.
    • HEALTHY_THRESHOLD: o número de sondagens sequenciais que precisam ser bem-sucedidas para que o endpoint seja considerado íntegro. O valor padrão é 2.
    • UNHEALTHY_THRESHOLD: o número de sondagens sequenciais que precisam falhar para que o endpoint seja considerado não íntegro. O valor padrão é 2.
  3. Crie um objeto BackendService usando o recurso Backend criado anteriormente. Inclua o recurso 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
    

    Substitua:

    • GLOBAL_API_SERVER: o caminho kubeconfig do servidor da API global.
    • PROJECT: o nome do projeto.
    • BACKEND_SERVICE_NAME: o nome escolhido para o recurso BackendService.
    • HEALTH_CHECK_NAME: o nome do recurso HealthCheck criado anteriormente.
    • BACKEND_NAME: o nome do recurso zonal Backend.
    • ZONE: a zona em que o recurso Backend está localizado. É possível especificar vários back-ends no campo backendRefs. Exemplo:

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

      O campo targetPorts é opcional. Esse recurso lista as portas que o recurso BackendService traduz. Se você estiver usando esse objeto, forneça valores para o seguinte:

    • PORT: a porta exposta pelo serviço.

    • PROTOCOL: o protocolo da camada 4 que o tráfego precisa corresponder. Somente TCP e UDP são aceitos.

    • TARGET_PORT: a porta para a qual o valor é traduzido, como 8080. O valor não pode ser repetido em um determinado objeto.

      Um exemplo de targetPorts pode ser assim:

      targetPorts:
        - port: 80
          protocol: TCP
          targetPort: 8080
      
  4. Crie um recurso ForwardingRule interno que defina o endereço IP virtual (VIP) em que o serviço está disponível.

    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
    

    Substitua:

    • GLOBAL_API_SERVER: o caminho kubeconfig do servidor da API global.
    • PROJECT: o nome do projeto.
    • FORWARDING_RULE_INTERNAL_NAME: o nome escolhido para o recurso ForwardingRuleInternal.
    • CIDR: o CIDR a ser usado na regra de encaminhamento. Este campo é opcional. Se não for especificado, um CIDR IPv4/32 será reservado automaticamente do pool global de endereços IP. Especifique o nome de um recurso Subnet no mesmo namespace que esta regra de encaminhamento. Um recurso Subnet representa as informações de solicitação e alocação de uma sub-rede global. Para mais informações sobre recursos Subnet, consulte Gerenciar sub-redes.
    • PORT: a porta a ser exposta na regra de encaminhamento. Use o campo ports para especificar uma matriz de portas L4 para as quais os pacotes são encaminhados aos back-ends configurados com essa regra de encaminhamento. É necessário especificar pelo menos uma porta. Use o campo port para especificar um número de porta. A porta exposta precisa ser a mesma que o aplicativo real está expondo dentro do contêiner.
    • PROTOCOL: o protocolo a ser usado para a regra de encaminhamento, como TCP. Uma entrada na matriz ports precisa ser semelhante a esta:

      ports:
      - port: 80
        protocol: TCP
      
  5. Para validar o ILB configurado, confirme a condição Ready em cada um dos objetos criados. Verifique o tráfego com uma solicitação curl para o VIP:

    1. Recupere o VIP:

      kubectl get forwardingruleinternal -n PROJECT
      

      A saída será assim:

      NAME           BACKENDSERVICE                  CIDR              READY
      ilb-name       BACKEND_SERVICE_NAME            192.0.2.0/32      True
      
    2. Teste o tráfego com uma solicitação curl ao VIP na porta especificada no campo da regra de encaminhamento:

      curl http://FORWARDING_RULE_VIP:PORT
      

      Substitua:

      • FORWARDING_RULE_VIP: o VIP da regra de encaminhamento.
      • PORT: o número da porta do campo na regra de encaminhamento.

Criar um balanceador de carga externo global

Os balanceadores de carga externos (ELB, na sigla em inglês) expõem serviços para acesso de fora da organização de um pool de endereços IP atribuídos à organização do pool maior de endereços IP externo da instância.

Conclua as etapas a seguir para criar um ELB global para suas cargas de trabalho de VM.

gdcloud

Use a CLI gdcloud para criar um ELB global que tenha como destino todas as cargas de trabalho no projeto que correspondem ao rótulo definido no objeto Backend. O recurso personalizado Backend precisa ter escopo em uma zona.

  1. Para que os serviços do ELB funcionem, configure e aplique sua própria transferência de dados ProjectNetworkPolicy personalizada na política para permitir o tráfego para as cargas de trabalho desse serviço do ELB. As políticas de rede controlam o acesso às cargas de trabalho, não ao balanceador de carga em si. Os ELBs expõem cargas de trabalho à rede do cliente, exigindo políticas de rede explícitas para permitir o tráfego externo à porta da carga de trabalho, como 8080.

    Especifique o endereço CIDR externo para permitir o tráfego para as cargas de trabalho deste 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
    

    Substitua:

    • GLOBAL_API_SERVER: o caminho kubeconfig do servidor de API global. Se você ainda não gerou um arquivo kubeconfig para o servidor da API global, consulte Gerar manualmente o arquivo kubeconfig para mais detalhes.
    • PROJECT: o nome do projeto.
    • CIDR: o CIDR externo de onde o ELB precisa ser acessado. Essa política é necessária porque o balanceador de carga externo usa o retorno direto do servidor (DSR), que preserva o endereço IP externo de origem e ignora o balanceador de carga no caminho de retorno. Para mais informações, consulte Criar uma regra de firewall de entrada global para tráfego entre organizações.
    • PORT: a porta de back-end nas VMs atrás do balanceador de carga. Esse valor é encontrado no campo .spec.ports[].targetPortfield do manifesto do recurso Service. Este campo é opcional.

    Essa configuração fornece a todos os recursos dentro dos projetos acesso ao intervalo de CIDR especificado.

  2. Crie um recurso Backend em cada zona para definir o endpoint do ELB:

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

    Substitua:

    • BACKEND_NAME: o nome do recurso de back-end, como my-backend.
    • LABELS: um seletor que define quais endpoints entre VMs usar para esse recurso de back-end, como app=web.
    • PROJECT: o nome do projeto.

    Você pode usar o mesmo recurso Backend para cada zona ou criar recursos Backend com conjuntos de rótulos diferentes para cada uma.

  3. Defina uma verificação de integridade global para o 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
    

    Substitua:

    • HEALTH_CHECK_NAME: o nome do recurso de verificação de integridade, como my-health-check.
    • CHECK_INTERVAL: o tempo em segundos entre o início de uma sondagem e o início da próxima. O valor padrão é 5. Este campo é opcional.
    • HEALTHY_THRESHOLD: o tempo a ser aguardado antes de declarar falha. O valor padrão é 5. Este campo é opcional.
    • TIMEOUT: o tempo em segundos para aguardar antes de declarar falha. O valor padrão é 5. Este campo é opcional.
    • UNHEALTHY_THRESHOLD: o número de sondagens sequenciais que precisam falhar para que o endpoint seja considerado não íntegro. O valor padrão é 2. Este campo é opcional.
    • PORT: a porta em que a verificação de integridade será realizada. O valor padrão é 80. Este campo é opcional.
  4. Crie um recurso BackendService global:

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

    Substitua:

    • BACKEND_SERVICE_NAME: o nome escolhido para esse serviço de back-end.
    • PROJECT: o nome do projeto.
    • TARGET_PORTS: uma lista separada por vírgulas de portas de destino que esse serviço de back-end traduz. Cada porta de destino especifica o protocolo, a porta na regra de encaminhamento e a porta na instância de back-end. É possível especificar várias portas de destino. Esse campo precisa estar no formato protocol:port:targetport, como TCP:80:8080. Este campo é opcional.
    • HEALTH_CHECK_NAME: o nome do recurso de verificação de integridade. Este campo é opcional.
  5. Adicione o recurso global BackendService ao recurso zonal Backend criado anteriormente:

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

    Conclua esta etapa para cada back-end zonal criado anteriormente.

  6. Crie um recurso ForwardingRule externo que defina o VIP em que o serviço está disponível:

    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
    

    Substitua:

    • FORWARDING_RULE_EXTERNAL_NAME: o nome da regra de encaminhamento.
    • CIDR: o CIDR a ser usado na regra de encaminhamento. Este campo é opcional. Se não for especificado, um CIDR IPv4/32 será reservado automaticamente do pool global de endereços IP. Especifique o nome de um recurso Subnet no mesmo namespace que esta regra de encaminhamento. Um recurso Subnet representa as informações de solicitação e alocação de uma sub-rede global. Para mais informações sobre recursos Subnet, consulte Gerenciar sub-redes.
    • PROTOCOL_PORT: o protocolo e a porta a serem expostos na regra de encaminhamento. Esse campo precisa estar no formato ip-protocol=TCP:80. A porta exposta precisa ser a mesma que o aplicativo real está expondo dentro da VM.
    • PROJECT: o nome do projeto.
  7. Para validar o ELB configurado, confirme a condição Ready em cada um dos objetos criados. Verifique o tráfego com uma solicitação curl para o VIP:

    1. Para receber o VIP atribuído, descreva a regra de encaminhamento:

      gdcloud compute forwarding-rules describe FORWARDING_RULE_EXTERNAL_NAME
      
    2. Verifique o tráfego com uma solicitação curl para o VIP na porta especificada no campo PROTOCOL_PORT da regra de encaminhamento:

      curl http://FORWARDING_RULE_VIP:PORT
      

      Substitua:

      • FORWARDING_RULE_VIP: o VIP da regra de encaminhamento.
      • PORT: o número da porta do campo PROTOCOL_PORT na regra de encaminhamento.

API

Crie um ELB que tenha como destino cargas de trabalho de VM usando a API KRM. Esse ELB direciona todas as cargas de trabalho no projeto que correspondem ao rótulo definido no objeto Backend. Para criar um ELB zonal usando a API KRM, siga estas etapas:

  1. Para que os serviços do ELB funcionem, configure e aplique sua própria transferência de dados ProjectNetworkPolicy personalizada na política para permitir o tráfego para as cargas de trabalho desse serviço do ELB. As políticas de rede controlam o acesso às cargas de trabalho, não ao balanceador de carga em si. Os ELBs expõem cargas de trabalho à rede do cliente, exigindo políticas de rede explícitas para permitir o tráfego externo à porta da carga de trabalho, como 8080.

    Especifique o endereço CIDR externo para permitir o tráfego para as cargas de trabalho deste 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
    

    Substitua:

    • GLOBAL_API_SERVER: o caminho kubeconfig do servidor de API global. Se você ainda não gerou um arquivo kubeconfig para o servidor da API global, consulte Gerar manualmente o arquivo kubeconfig para mais detalhes.
    • PROJECT: o nome do projeto.
    • CIDR: o CIDR externo de onde o ELB precisa ser acessado. Essa política é necessária porque o balanceador de carga externo usa o retorno direto do servidor (DSR), que preserva o endereço IP externo de origem e ignora o balanceador de carga no caminho de retorno. Para mais informações, consulte Criar uma regra de firewall de entrada global para tráfego entre organizações.
    • PORT: a porta de back-end nas VMs atrás do balanceador de carga. Esse valor é encontrado no campo .spec.ports[].targetPortfield do manifesto do recurso Service. Este campo é opcional.
  2. Crie um recurso Backend para definir os endpoints do ELB. Crie recursos Backend para cada zona em que as cargas de trabalho estão localizadas:

    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
    

    Substitua:

    • MANAGEMENT_API_SERVER: o caminho kubeconfig do servidor da API Management zonal. Se você ainda não gerou um arquivo kubeconfig para o servidor da API na zona de destino, consulte Gerar manualmente o arquivo kubeconfig para mais detalhes.
    • PROJECT: o nome do projeto.
    • BACKEND_NAME: o nome do recurso ;Backend

    Você pode usar o mesmo recurso Backend para cada zona ou criar recursos Backend com conjuntos de rótulos diferentes para cada uma.

  3. Defina uma verificação de integridade global para o 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
    

    Substitua:

    • HEALTH_CHECK_NAME: o nome do recurso de verificação de integridade, como my-health-check.
    • PORT: a porta em que a verificação de integridade será realizada. O valor padrão é 80.
    • TIMEOUT: o tempo em segundos para aguardar antes de declarar falha. O valor padrão é 5.
    • CHECK_INTERVAL: o tempo em segundos entre o início de uma sondagem e o início da próxima. O valor padrão é 5.
    • HEALTHY_THRESHOLD: o número de sondagens sequenciais que precisam ser aprovadas para que o endpoint seja considerado íntegro. O valor padrão é 2.
    • UNHEALTHY_THRESHOLD: o número de sondagens sequenciais que precisam falhar para que o endpoint seja considerado não íntegro. O valor padrão é 2.

    Como este é um ELB global, crie a verificação de integridade na API global.

  4. Crie um objeto BackendService usando o recurso Backend criado anteriormente:

    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
    

    Substitua:

    • BACKEND_SERVICE_NAME: o nome escolhido para o recurso BackendService.
    • HEALTH_CHECK_NAME: o nome do recurso HealthCheck criado anteriormente. Não inclua esse campo se você estiver configurando um ELB para cargas de trabalho de pod.
    • ZONE: a zona em que o recurso Backend está localizado. É possível especificar vários back-ends no campo backendRefs. Exemplo:
    - name: my-backend-1
      zone: us-east1-a
    - name: my-backend-2
      zone: us-east1-b
    
  5. Crie um recurso ForwardingRule externo que defina o VIP em que o serviço está disponível.

    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
    

    Substitua:

    • FORWARDING_RULE_EXTERNAL_NAME: o nome escolhido para o recurso ForwardingRuleExternal.
    • CIDR: o CIDR a ser usado na regra de encaminhamento. Este campo é opcional. Se não for especificado, um CIDR IPv4/32 será reservado automaticamente do pool global de endereços IP. Especifique o nome de um recurso Subnet no mesmo namespace que esta regra de encaminhamento. Um recurso Subnet representa as informações de solicitação e alocação de uma sub-rede global. Para mais informações sobre recursos Subnet, consulte Gerenciar sub-redes.
    • PORT: a porta a ser exposta na regra de encaminhamento. Use o campo ports para especificar uma matriz de portas L4 em que os pacotes são encaminhados para os back-ends configurados com essa regra de encaminhamento. É necessário especificar pelo menos uma porta. Use o campo port para especificar um número de porta. A porta exposta precisa ser a mesma que o aplicativo real está expondo dentro do contêiner.
    • PROTOCOL: o protocolo a ser usado para a regra de encaminhamento, como TCP. Uma entrada na matriz ports precisa ser assim:
    ports:
    - port: 80
      protocol: TCP
    
  6. Para validar o ELB configurado, confirme a condição Ready em cada um dos objetos criados. Teste o tráfego com uma solicitação curl para o VIP.

    1. Recupere o VIP do projeto:

      kubectl get forwardingruleexternal -n PROJECT
      

      A saída será assim:

      NAME           BACKENDSERVICE                  CIDR              READY
      elb-name       BACKEND_SERVICE_NAME            192.0.2.0/32      True
      
    2. Verifique o tráfego com uma solicitação curl para o VIP na porta especificada no campo PORT da regra de encaminhamento:

      curl http://FORWARDING_RULE_VIP:PORT
      

      Substitua FORWARDING_RULE_VIP:PORT pelo VIP e pela porta da regra de encaminhamento, como 192.0.2.0:80.

Configurar a replicação assíncrona de armazenamento

Os universos multizonais do GDC oferecem o uso de recursos de armazenamento replicados, como volumes e buckets, no modo assíncrono para cenários de recuperação de desastres. Essas opções de recursos de armazenamento oferecem replicação assíncrona de dados entre duas zonas na mesma região. A replicação assíncrona ocorre em segundo plano, fornecendo um objetivo de ponto de recuperação (RPO) baixo, mas não zero, em caso de desastre. Todos os dados replicados estão on-line e imediatamente acessíveis, mas podem exigir um procedimento manual de failover para permitir a gravação na zona secundária.

Você pode escolher um dos seguintes tipos de replicação de armazenamento assíncrona para o aplicativo da VM:

Criar um bucket de duas zonas para armazenamento de objetos

Os dados de armazenamento de objetos são gravados em um único bucket, que armazena os dados nas duas zonas. Como os dados são copiados de forma assíncrona entre as zonas, elas podem não conter as mesmas versões de objetos a qualquer momento, mas vão se tornar equivalentes se nenhuma outra mudança for feita. Ao contrário da replicação de volume, os buckets replicados podem ser gravados durante as partições de zona. Cada gravação em um objeto produz uma versão diferente, e a versão mais recente em qualquer zona será o estado final após o restabelecimento da conectividade.

  1. Verifique se o operador de infraestrutura (IO) criou o recurso personalizado BucketLocationConfig, que é necessário para a replicação assíncrona entre zonas para armazenamento de objetos. Esse recurso precisa ser implantado no servidor da API global raiz.

  2. Crie o recurso personalizado Bucket de duas zonas:

    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
    

    Substitua:

    • GLOBAL_API_SERVER: o arquivo kubeconfig do servidor da API global.
    • BUCKET_NAME: o nome do bucket de armazenamento.
    • PROJECT: o nome do projeto em que o bucket está.
    • LOCATION_NAME: o local físico em que os dados do objeto no bucket estão. Isso precisa ser mapeado para o nome de um recurso BucketLocation existente. Para consultar o servidor de API global da sua organização e ver uma lista de recursos BucketLocation disponíveis, execute kubectl --kubeconfig GLOBAL_API_SERVER bucketlocations. Se não houver recursos BucketLocation, entre em contato com seu IO para verificar se ele ativou a replicação assíncrona.

Configurar a replicação assíncrona do armazenamento em blocos entre zonas

O armazenamento em blocos replicado fornece volumes (PVs) replicados de forma assíncrona, que mantêm a equivalência de blocos entre os volumes primário e secundário. Devido à natureza assíncrona, o volume secundário reflete o estado da zona principal em algum momento do passado (RPO diferente de zero). O volume secundário não pode ser montado enquanto permanece como destino da replicação, exigindo intervenção manual para encerrar a relação e permitir que as gravações ocorram.

É necessário implantar um recurso personalizado VolumeReplicationRelationship no servidor de API global para criar dados replicados que estejam disponíveis para failover se os dados da zona de origem ficarem indisponíveis.

Antes de começar, verifique se o operador de infraestrutura (IO) criou e configurou os recursos personalizados StorageClusterPeering e StorageVirtualMachinePeering para permitir a replicação de armazenamento em blocos entre zonas. Esse recurso precisa ser implantado no servidor de API global raiz.

gdcloud

  1. Defina a relação de volume de replicação assíncrona entre a zona primária e as zonas secundárias:

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

    Substitua:

    • PRIMARY_DISK_NAME: o nome do disco de origem que está sendo replicado.
    • PROJECT: o projeto do GDC do disco principal.
    • PRIMARY_ZONE: a zona em que o disco principal reside.
    • SECONDARY_DISK_NAME: o nome do disco de destino para replicar.
    • SECONDARY_ZONE: a zona em que o disco secundário precisa estar.
  2. Crie um recurso personalizado VolumeFailover na zona de destino, que interrompe a replicação para a zona de destino se a zona de origem estiver indisponível por qualquer motivo:

    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
    

    Substitua:

    • MANAGEMENT_API_SERVER: o arquivo kubeconfig para o servidor da API Management.
    • FAILOVER_NAME: o nome do failover.
    • PROJECT: o projeto em que a infraestrutura de armazenamento está localizada.
    • REPL_NAME: o nome da relação de replicação de volume.

    Para mais informações sobre como gerenciar a replicação assíncrona para cargas de trabalho de VM, consulte Replicar volumes de forma assíncrona.

API

  1. Crie um arquivo YAML de recurso personalizado VolumeReplicationRelationship e implante-o no servidor de API global:

    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
    

    Substitua:

    • GLOBAL_API_SERVER: o arquivo kubeconfig do servidor da API de gerenciamento global.
    • VRR_NAME: o nome da relação de replicação de volume. O mesmo nome precisa ser usado ao interromper a replicação assíncrona.
    • PROJECT: o projeto do GDC do disco principal.
    • PRIMARY_DISK_NAME: o nome do disco de origem que está sendo replicado.
    • PRIMARY_ZONE: a zona em que o disco principal reside.
    • SECONDARY_DISK_NAME: o nome do disco de destino para replicar.
    • SECONDARY_ZONE: a zona em que o disco secundário precisa estar.
  2. Crie um recurso personalizado VolumeFailover na zona de destino, que interrompe a replicação para a zona de destino se a zona de origem estiver indisponível por qualquer motivo:

    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
    

    Substitua:

    • MANAGEMENT_API_SERVER: o arquivo kubeconfig do servidor da API Management.
    • FAILOVER_NAME: o nome do failover.
    • PROJECT: o projeto em que a infraestrutura de armazenamento reside.
    • REPL_NAME: o nome da relação de replicação de volume.

Para mais informações sobre como gerenciar a replicação assíncrona para cargas de trabalho de VM, consulte Replicar volumes de forma assíncrona.

A seguir