Implemente uma aplicação de contentor altamente disponível

Esta página fornece a estratégia de implementação recomendada para criar uma aplicação de contentor Kubernetes robusta e de alta disponibilidade (HA) no Google Distributed Cloud (GDC) isolado. Tem de implementar a aplicação de contentor em várias zonas do GDC e configurar a replicação de armazenamento assíncrona para que a aplicação e os respetivos dados sejam recuperáveis em caso de tempo de inatividade inesperado ou desastre local.

Esta página destina-se a programadores no grupo de operadores de aplicações, que são responsáveis por criar cargas de trabalho de aplicações para a respetiva organização. Para mais informações, consulte a documentação sobre públicos-alvo para GDC com isolamento de ar.

Objetivos

  • Crie um cluster do Kubernetes em duas ou mais zonas no seu universo do GDC.
  • Configure o balanceamento de carga global.
  • Implemente cargas de trabalho de contentores em cada cluster do Kubernetes zonal.
  • Aprovisione armazenamento e anexe-o aos seus pods.
  • Configurar a replicação de armazenamento assíncrona, usando o armazenamento em blocos ou o armazenamento de objetos.

Antes de começar

  • Confirme que está a trabalhar num 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 o artigo Liste as zonas num universo.

  • Peça ao administrador de IAM da organização para lhe conceder as seguintes funções:

    • A função de administrador do espaço de nomes (namespace-admin) para criar e gerir cargas de trabalho de contentores.

    • As funções de administrador do cluster de utilizadores (user-cluster-admin) e programador do cluster de utilizadores (user-cluster-developer) para criar e gerir clusters do Kubernetes e os respetivos node pools.

    • As funções de administrador do equilibrador de carga (load-balancer-admin) e administrador do equilibrador de carga global (global-load-balancer-admin). Tem de ter esta função para criar e gerir balanceadores de carga.

    • A função de administrador global da replicação de volumes (app-volume-replication-admin-global). Tem de ter esta função para administrar a replicação de volumes.

    • A função de administrador de PNP global (global-project-networkpolicy-admin) para criar e gerir políticas de rede de projetos em várias zonas.

    • As funções Harbor Instance Admin (harbor-instance-admin), Harbor Instance Viewer(harbor-instance-viewer) e Harbor Project Creator (harbor-project-creator). Estas funções são necessárias para criar e gerir imagens de contentores no registo de artefactos.

    • A função de administrador global da replicação de volumes (app-volume-replication-admin-global) para administrar a relação de replicação de volumes para recursos de armazenamento de blocos.

    • As funções de administrador de objetos do contentor do projeto (project-bucket-object-admin) e administrador do contentor do projeto (project-bucket-admin) para criar e gerir contentores de armazenamento.

    Consulte as descrições das funções para mais informações.

  • Instale e configure a CLI gcloud e configure os contextos zonais e globais. Consulte o artigo Faça a gestão de recursos em várias zonas para mais informações.

  • Instale e configure a CLI kubectl com os ficheiros kubeconfig adequados definidos para o servidor de API global, o servidor de API de gestão e o cluster Kubernetes. Consulte o artigo Gere manualmente o ficheiro kubeconfig para mais informações.

Crie um cluster do Kubernetes em várias zonas

Um cluster do Kubernetes é um recurso zonal, pelo que tem de criar um cluster separadamente em cada zona.

Consola

  1. No menu de navegação, selecione Kubernetes Engine > Clusters.

  2. Clique em Criar cluster.

  3. No campo Nome, especifique um nome para o cluster.

  4. Selecione a versão do Kubernetes para o cluster.

  5. Selecione a zona na qual criar o cluster.

  6. Clique em Anexar projeto e selecione um projeto existente para anexar ao seu cluster. Em seguida, clique em Guardar. Pode anexar ou desanexar projetos depois de criar o cluster na página Detalhes do projeto. Tem de ter um projeto associado ao cluster antes de implementar cargas de trabalho de contentores no mesmo.

  7. Clicar em Seguinte.

  8. Configure as definições de rede do cluster. Não pode alterar estas definições de rede depois de criar o cluster. O protocolo de Internet predefinido e único suportado para clusters do Kubernetes é a versão 4 do protocolo de Internet (IPv4).

    1. Especifique o tamanho do conjunto de endereços IP do balanceador de carga, como 20.

    2. Selecione o CIDR (Classless Inter-Domain Routing) do serviço a usar. Os seus serviços implementados, como equilibradores de carga, têm endereços IP atribuídos a partir deste intervalo.

    3. Selecione o CIDR do pod a usar. O cluster atribui endereços IP deste intervalo aos seus pods e VMs.

    4. Clicar em Seguinte.

  9. Reveja os detalhes do conjunto de nós predefinido gerado automaticamente para o cluster. Clique em Editar para modificar o conjunto de nós predefinido.

  10. Para criar node pools adicionais, selecione Adicionar node pool. Quando edita o node pool predefinido ou adiciona um novo node pool, personaliza-o com as seguintes opções:

    1. Atribua um nome ao conjunto de nós. Não pode modificar o nome depois de criar o conjunto de nós.
    2. Especifique o número de nós de trabalho a criar no node pool.
    3. Selecione a classe de máquinas mais adequada aos requisitos da sua carga de trabalho. Veja a lista das seguintes definições:

      • Tipo de máquina
      • CPU
      • Memória
    4. Clique em Guardar.

    5. Clique em Criar para criar o cluster.

  11. Repita estes passos para cada zona no seu universo do GDC. Certifique-se de que existe um cluster do Kubernetes em cada zona que quer para a sua estratégia de HA.

API

Para criar um novo cluster do Kubernetes diretamente através da API, aplique um recurso personalizado a cada zona do GDC.

  1. Crie um recurso personalizado Cluster e implemente-o no servidor da API Management para a sua zona:

    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
    

    Substitua o seguinte:

    • MANAGEMENT_API_SERVER: o caminho kubeconfig do servidor da API Management zonal. Para mais informações, consulte o artigo Mude para o contexto zonal.
    • CLUSTER_NAME: o nome do cluster. O nome do cluster não pode terminar com -system. O sufixo -system está reservado para clusters criados pelo GDC.
    • POD_CIDR: o tamanho dos intervalos de rede a partir dos quais os endereços IP virtuais (VIP) dos pods são atribuídos. Se não estiver definida, é usado o valor predefinido 21.
    • SERVICE_CIDR: o tamanho dos intervalos de rede a partir dos quais os VIPs de serviço são atribuídos. Se não estiver definida, é usado o valor predefinido 23.
    • KUBERNETES_VERSION: a versão do Kubernetes do cluster, como 1.26.5-gke.2100. Para listar as versões do Kubernetes disponíveis para configurar, consulte o artigo Liste as versões do Kubernetes disponíveis para um cluster.
    • LOAD_BALANCER_POOL_SIZE: o tamanho dos conjuntos de endereços IP não sobrepostos usados pelos serviços de balanceamento de carga. Se não for definida, é usado o valor predefinido 20.
    • MACHINE_TYPE: o tipo de máquina para os nós de trabalho do node pool. Veja os tipos de máquinas disponíveis para o que está disponível para configuração.
    • NODE_POOL_NAME: o nome do node pool.
    • NUMBER_OF_WORKER_NODES: o número de nós de trabalho a aprovisionar no node pool.
    • TAINTS: as manchas a aplicar aos nós deste node pool. Este é um campo opcional.
    • LABELS: as etiquetas a aplicar aos nós deste node pool. Contém uma lista de pares de chave-valor. Este é um campo opcional.
    • GPU_PARTITION_SCHEME: o esquema de partição da GPU, se estiver a executar cargas de trabalho da GPU, como o mixed-2. A GPU não é particionada se este campo não estiver definido. Para ver os perfis de GPU multi-instância (MIG) disponíveis, consulte os perfis de MIG suportados.
  2. Repita o passo anterior para cada zona que quer alojar a sua aplicação de contentor para a sua estratégia de HA.

Configure balanceadores de carga

Para distribuir o tráfego entre os seus pods em diferentes zonas, crie balanceadores de carga. Tem a opção de criar balanceadores de carga externos (ELB) e balanceadores de carga internos (ILB), que podem ser configurados ao nível da zona ou globalmente. Para este exemplo, configure um ILB global e um ELB global para a sua aplicação de contentor.

Crie um balanceador de carga interno global

Os balanceadores de carga internos (ILB) expõem serviços na organização a partir de um conjunto de endereços IP internos atribuídos à organização. Um serviço ILB nunca está acessível a partir de nenhum ponto final fora da organização.

Conclua os passos seguintes para criar um ILB global para as suas cargas de trabalho de contentores.

gdcloud

Crie um ILB que segmente cargas de trabalho de pods através da CLI gcloud.

Este ILB segmenta todas as cargas de trabalho no projeto que correspondem à etiqueta definida no objeto Backend. O recurso personalizado Backend tem de estar no âmbito de uma zona.

Para criar um ILB através da CLI gdcloud, siga estes passos:

  1. Crie um recurso Backendzonal em cada zona onde os seus pods estão a ser executados para definir o ponto final do ILB:

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

    Substitua o seguinte:

    • BACKEND_NAME: o nome escolhido para o recurso de back-end, como my-backend.
    • LABELS: o seletor que define que pontos finais entre pods usar para este recurso de back-end, como app=web.
    • PROJECT: o nome do seu projeto.
    • CLUSTER_NAME: o cluster do Kubernetes ao qual o âmbito dos seletores definidos está limitado. Se este campo não for especificado, são selecionados todos os pontos finais com a etiqueta fornecida. Este campo é opcional.
    • ZONE: a zona a usar para esta invocação. Para predefinir a flag de zona para todos os comandos que a requerem, execute gdcloud config set core/zone ZONE. O indicador de zona está disponível apenas em ambientes com várias zonas. Este campo é opcional.

    Repita este passo para cada zona no seu universo do GDC.

  2. Crie um recurso BackendService global:

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

    Substitua o seguinte:

    • BACKEND_SERVICE_NAME: o nome do serviço de back-end.
    • PROJECT: o nome do seu projeto.
    • TARGET_PORTS: uma lista separada por vírgulas das portas de destino que este 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. Pode especificar várias portas de destino. Este campo tem de estar no formato protocol:port:targetport, como TCP:80:8080. Este campo é opcional.
  3. 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 o seguinte:

    • 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 seu projeto.

    Conclua este passo para cada back-end zonal que criou anteriormente.

  4. Crie um recurso ForwardingRule interno que defina o endereço IP virtual (VIP) no qual 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 o seguinte:

    • FORWARDING_RULE_INTERNAL_NAME: o nome da regra de encaminhamento.
    • CIDR: o CIDR a usar para a regra de encaminhamento. Este campo é opcional. Se não for especificado, é reservado automaticamente um IPv4/32 CIDR do conjunto de endereços IP global. Especifique o nome de um recurso Subnet no mesmo espaço de nomes que esta regra de encaminhamento. Um recurso Subnet representa as informações de pedido e atribuição de uma sub-rede global. Para mais informações sobre os Subnet recursos, consulte o artigo Faça a gestão das sub-redes.
    • PROTOCOL_PORT: o protocolo e a porta a expor na regra de encaminhamento. Este campo tem de estar no formato ip-protocol=TCP:80. A porta exposta tem de ser a mesma que a aplicação real está a expor no contentor.
  5. Para validar o ILB configurado, confirme a condição Ready em cada um dos objetos criados. Valide o tráfego com um pedido curl para o VIP:

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

      gdcloud compute forwarding-rules describe FORWARDING_RULE_INTERNAL_NAME --global
      
    2. Valide o tráfego com um pedido curl para o VIP na porta especificada no campo na regra de encaminhamento:

      curl http://FORWARDING_RULE_VIP:PORT
      

    Substitua o seguinte:

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

API

Crie um ILB que segmenta cargas de trabalho de contentores através da API KRM. Este ILB segmenta todos os cargas de trabalho no projeto que correspondem à etiqueta definida no objeto Backend. Para criar um ILB global através da API KRM, siga estes passos:

  1. Crie um recurso Backend para definir os pontos finais do ILB. Crie recursos Backend para cada zona em que as cargas de trabalho do contentor 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:
      clusterName: CLUSTER_NAME
      endpointsLabels:
        matchLabels:
          app: APP_NAME
    EOF
    

    Substitua o seguinte:

    • MANAGEMENT_API_SERVER: o caminho kubeconfig do caminho kubeconfig do servidor da API Management zonal. Para mais informações, consulte o artigo Mude para um contexto zonal.
    • PROJECT: o nome do seu projeto.
    • BACKEND_NAME: o nome do recurso Backend
    • CLUSTER_NAME: o cluster do Kubernetes ao qual o âmbito dos seletores definidos está limitado. Se este campo não for especificado, são selecionados todos os pontos finais com a etiqueta fornecida. Este campo é opcional.
    • APP_NAME: o nome da sua aplicação de contentores.

    Pode usar o mesmo recurso Backend para cada zona ou criar recursos Backend com diferentes conjuntos de etiquetas para cada zona.

  2. Crie um objeto BackendService com o recurso Backend criado anteriormente. Certifique-se de que inclui 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 o seguinte:

    • GLOBAL_API_SERVER: o caminho kubeconfig do caminho kubeconfig do servidor da API global.
    • PROJECT: o nome do seu projeto.
    • BACKEND_SERVICE_NAME: o nome escolhido para o seu recurso BackendService.
    • HEALTH_CHECK_NAME: o nome do recurso HealthCheck criado anteriormente.
    • BACKEND_NAME: o nome do recurso Backend zonal.
    • ZONE: a zona em que o recurso Backend reside. Pode especificar vários backends no campo backendRefs. Por exemplo:

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

      O campo targetPorts é opcional. Este recurso apresenta as portas que este recurso BackendServicetraduz. Se estiver a usar este objeto, faculte valores para o seguinte:

    • PORT: a porta exposta pelo serviço.

    • PROTOCOL: o protocolo de camada 4 com o qual o tráfego tem de corresponder. Apenas são suportados os protocolos TCP e UDP.

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

      Um exemplo para targetPorts pode ter o seguinte aspeto:

      targetPorts:
        - port: 80
          protocol: TCP
          targetPort: 8080
      
  3. Crie um recurso ForwardingRule interno que defina o endereço IP virtual (VIP) no qual 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 o seguinte:

    • GLOBAL_API_SERVER: o caminho kubeconfig do caminho kubeconfig do servidor da API global.
    • PROJECT: o nome do seu projeto.
    • FORWARDING_RULE_INTERNAL_NAME: o nome escolhido para o seu recurso ForwardingRuleInternal.
    • CIDR: o CIDR a usar para a regra de encaminhamento. Este campo é opcional. Se não for especificado, é reservado automaticamente um IPv4/32 CIDR do conjunto de endereços IP global. Especifique o nome de um recurso Subnet no mesmo espaço de nomes que esta regra de encaminhamento. Um recurso Subnet representa as informações de pedido e atribuição de uma sub-rede global. Para mais informações sobre os Subnet recursos, consulte o artigo Faça a gestão das sub-redes.
    • PORT: a porta a expor na regra de encaminhamento. Use o campo ports para especificar uma matriz de portas L4 para as quais os pacotes são encaminhados para os back-ends configurados com esta regra de encaminhamento. Tem de especificar, pelo menos, uma porta. Use o campo port para especificar um número de porta. A porta exposta tem de ser a mesma que a aplicação real está a expor no contentor.
    • PROTOCOL: o protocolo a usar para a regra de encaminhamento, como TCP. Uma entrada na matriz ports tem de ser semelhante ao seguinte:

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

    1. Recupere o VIP:

      kubectl get forwardingruleinternal -n PROJECT
      

      O resultado tem o seguinte aspeto:

      NAME           BACKENDSERVICE                  CIDR              READY
      ilb-name       BACKEND_SERVICE_NAME            192.0.2.0/32      True
      
    2. Teste o tráfego com um pedido curl para o VIP na porta especificada no campo na regra de encaminhamento:

      curl http://FORWARDING_RULE_VIP:PORT
      

      Substitua o seguinte:

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

Crie um balanceador de carga externo global

Os equilibradores de carga externos (ELB) expõem serviços para acesso a partir do exterior da organização a partir dos endereços IP de um conjunto atribuídos à organização a partir do conjunto de endereços IP externos de instâncias maior.

Conclua os passos seguintes para criar um ELB global para as suas cargas de trabalho de contentores.

gdcloud

Use a CLI gdcloud para criar um ELB global que segmenta todas as cargas de trabalho no projeto que correspondem à etiqueta definida no objeto Backend. O recurso personalizado Backend tem de ter o âmbito de uma zona.

  1. Para que os serviços ELB funcionem, tem de configurar e aplicar a sua própria transferência de dados ProjectNetworkPolicy personalizada na política para permitir o tráfego para as cargas de trabalho deste serviço ELB. As políticas de rede controlam o acesso aos seus workloads e não ao equilibrador de carga propriamente dito. Os ELBs expõem cargas de trabalho à sua rede de clientes, o que requer políticas de rede explícitas para permitir tráfego externo para a porta de carga de trabalho, como 8080.

    Especifique o endereço CIDR externo para permitir 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 o seguinte:

    • GLOBAL_API_SERVER: o caminho kubeconfig do caminho kubeconfig do servidor de API global. Se ainda não tiver gerado um ficheiro kubeconfig para o servidor de API global, consulte o artigo Gerar manualmente o ficheiro kubeconfig para ver detalhes.
    • PROJECT: o nome do seu projeto.
    • CIDR: o CIDR externo a partir do qual o ELB tem de ser acedido. Esta 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 o artigo Crie uma regra de firewall de entrada global para tráfego entre organizações.
    • PORT: a porta de back-end nos pods atrás do balanceador de carga. Este valor encontra-se no campo .spec.ports[].targetPortfield do manifesto para o recurso Service. Este campo é opcional.

    Esta configuração dá acesso a todos os recursos nos projetos ao intervalo CIDR especificado.

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

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

    Substitua o seguinte:

    • BACKEND_NAME: o nome do recurso de back-end, como my-backend.
    • LABELS: um seletor que define que pontos finais entre os pods usar para este recurso de back-end, como app=web.
    • PROJECT: o nome do seu projeto.
    • CLUSTER_NAME: o cluster do Kubernetes ao qual o âmbito dos seletores definidos está limitado. Se este campo não for especificado, são selecionados todos os pontos finais com a etiqueta fornecida. Este campo é opcional.
    • ZONE: a zona a usar para esta invocação. Para predefinir a flag de zona para todos os comandos que a requerem, execute gdcloud config set core/zone ZONE. O indicador de zona está disponível apenas em ambientes com várias zonas. Este campo é opcional.

    Pode usar o mesmo recurso Backend para cada zona ou criar recursos Backend com diferentes conjuntos de etiquetas para cada zona.

  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 o seguinte:

    • BACKEND_SERVICE_NAME: o nome escolhido para este serviço de back-end.
    • PROJECT: o nome do seu projeto.
    • TARGET_PORTS: uma lista separada por vírgulas de portas de destino que este 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. Pode especificar várias portas de destino. Este campo tem de estar no formato protocol:port:targetport, como TCP:80:8080. Este campo é opcional.
    • HEALTH_CHECK_NAME: o nome do recurso de verificação de estado. Este campo é opcional.
  4. Adicione o recurso BackendService global ao recurso zonal criado anteriormente:Backend

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

    Conclua este passo para cada back-end zonal que criou anteriormente.

  5. Crie um recurso ForwardingRule externo que defina o VIP no qual 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 o seguinte:

    • FORWARDING_RULE_EXTERNAL_NAME: o nome da regra de encaminhamento.
    • CIDR: o CIDR a usar para a regra de encaminhamento. Este campo é opcional. Se não for especificado, é reservado automaticamente um IPv4/32 CIDR do conjunto de endereços IP global. Especifique o nome de um recurso Subnet no mesmo espaço de nomes que esta regra de encaminhamento. Um recurso Subnet representa as informações de pedido e atribuição de uma sub-rede global. Para mais informações sobre os Subnet recursos, consulte o artigo Faça a gestão das sub-redes.
    • PROTOCOL_PORT: o protocolo e a porta a expor na regra de encaminhamento. Este campo tem de estar no formato ip-protocol=TCP:80. A porta exposta tem de ser a mesma que a aplicação real está a expor no contentor.
    • PROJECT: o nome do seu projeto.
  6. Para validar o ELB configurado, confirme a condição Ready em cada um dos objetos criados. Valide o tráfego com um pedido curl para o VIP:

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

      gdcloud compute forwarding-rules describe FORWARDING_RULE_EXTERNAL_NAME
      
    2. Valide o tráfego com um pedido curl para o VIP na porta especificada no campo PROTOCOL_PORT na regra de encaminhamento:

      curl http://FORWARDING_RULE_VIP:PORT
      

      Substitua o seguinte:

      • 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 segmenta cargas de trabalho de pods através da API KRM. Este ELB segmenta todas as cargas de trabalho no projeto que correspondem à etiqueta definida no objeto Backend. Para criar um ELB zonal através da API KRM, siga estes passos:

  1. Para que os serviços ELB funcionem, tem de configurar e aplicar a sua própria transferência de dados ProjectNetworkPolicy personalizada na política para permitir o tráfego para as cargas de trabalho deste serviço ELB. As políticas de rede controlam o acesso aos seus workloads e não ao equilibrador de carga propriamente dito. Os ELBs expõem cargas de trabalho à sua rede de clientes, o que requer políticas de rede explícitas para permitir tráfego externo para a porta de carga de trabalho, como 8080.

    Especifique o endereço CIDR externo para permitir 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 o seguinte:

    • GLOBAL_API_SERVER: o caminho kubeconfig do caminho kubeconfig do servidor de API global. Se ainda não tiver gerado um ficheiro kubeconfig para o servidor de API global, consulte o artigo Gerar manualmente o ficheiro kubeconfig para ver detalhes.
    • PROJECT: o nome do seu projeto.
    • CIDR: o CIDR externo a partir do qual o ELB tem de ser acedido. Esta 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 o artigo Crie uma regra de firewall de entrada global para tráfego entre organizações.
    • PORT: a porta de back-end nos pods atrás do balanceador de carga. Este valor encontra-se no campo .spec.ports[].targetPortfield do manifesto para o recurso Service. Este campo é opcional.
  2. Crie um recurso Backend para definir os pontos finais 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:
      clusterName: CLUSTER_NAME
      endpointsLabels:
        matchLabels:
          app: APP_NAME
    EOF
    

    Substitua o seguinte:

    • MANAGEMENT_API_SERVER: o caminho kubeconfig do caminho kubeconfig do servidor da API Management zonal. Se ainda não gerou um ficheiro kubeconfig para o servidor da API na sua zona segmentada, consulte o artigo Gere manualmente o ficheiro kubeconfig para ver detalhes.
    • PROJECT: o nome do seu projeto.
    • BACKEND_NAME: o nome do recurso Backend.
    • CLUSTER_NAME: o cluster do Kubernetes ao qual o âmbito dos seletores definidos está limitado. Se este campo não for especificado, são selecionados todos os pontos finais com a etiqueta fornecida. Este campo é opcional.
    • APP_NAME: o nome da sua aplicação de contentores.

    Pode usar o mesmo recurso Backend para cada zona ou criar recursos Backend com diferentes conjuntos de etiquetas para cada zona.

  3. Crie um objeto BackendService com 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 o seguinte:

    • BACKEND_SERVICE_NAME: o nome escolhido para o seu recurso BackendService.
    • HEALTH_CHECK_NAME: o nome do recurso HealthCheck criado anteriormente. Não inclua este campo se estiver a configurar um ELB para cargas de trabalho de pods.
    • ZONE: a zona em que o recurso Backend reside. Pode especificar vários backends no campo backendRefs. Por exemplo:
    - name: my-backend-1
      zone: us-east1-a
    - name: my-backend-2
      zone: us-east1-b
    

  4. Crie um recurso ForwardingRule externo que defina o VIP no qual 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 o seguinte:

    • FORWARDING_RULE_EXTERNAL_NAME: o nome escolhido para o recurso ForwardingRuleExternal.
    • CIDR: o CIDR a usar para a regra de encaminhamento. Este campo é opcional. Se não for especificado, é reservado automaticamente um IPv4/32 CIDR do conjunto de endereços IP global. Especifique o nome de um recurso Subnet no mesmo espaço de nomes que esta regra de encaminhamento. Um recurso Subnet representa as informações de pedido e atribuição de uma sub-rede global. Para mais informações sobre os Subnet recursos, consulte o artigo Faça a gestão das sub-redes.
    • PORT: a porta a expor na regra de encaminhamento. Use o campo ports para especificar uma matriz de portas L4 para as quais os pacotes são encaminhados para os back-ends configurados com esta regra de encaminhamento. Tem de especificar, pelo menos, uma porta. Use o campo port para especificar um número de porta. A porta exposta tem de ser a mesma que a aplicação real está a expor no contentor.
    • PROTOCOL: o protocolo a usar para a regra de encaminhamento, como TCP. Uma entrada na matriz ports tem de ter o seguinte aspeto:
    ports:
    - port: 80
      protocol: TCP
    
  5. Para validar o ELB configurado, confirme a condição Ready em cada um dos objetos criados. Experimente e teste o tráfego com um pedido curl ao VIP.

    1. Recupere o VIP do projeto:

      kubectl get forwardingruleexternal -n PROJECT
      

      O resultado tem o seguinte aspeto:

      NAME           BACKENDSERVICE                  CIDR              READY
      elb-name       BACKEND_SERVICE_NAME            192.0.2.0/32      True
      
    2. Valide o tráfego com um pedido curl para o VIP na porta especificada no campo PORT na 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.

Implemente cargas de trabalho de contentores em cada cluster zonal

As cargas de trabalho de contentores não são um recurso global, o que significa que tem de implementar cada uma das suas aplicações de contentores separadamente nos clusters Kubernetes zonais.

  1. Inicie sessão na zona que aloja o seu cluster do Kubernetes:

    gdcloud config set core/zone ZONE
    
  2. Verifique se a imagem do contentor está disponível no registo do Harbor gerido. Para mais informações, consulte o tutorial Implemente uma app de contentor.

  3. Crie um ficheiro de manifesto para a carga de trabalho do contentor e implemente-o no cluster do Kubernetes zonal:

    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
    

    Substitua o seguinte:

    • KUBERNETES_CLUSTER: o ficheiro kubeconfig para o cluster Kubernetes zonal no qual está a implementar cargas de trabalho de contentores. Se ainda não gerou um ficheiro kubeconfig para o seu cluster Kubernetes zonal, consulte o artigo Gere manualmente o ficheiro kubeconfig para obter detalhes.
    • PROJECT: o espaço de nomes do projeto no qual implementar as cargas de trabalho do contentor.
    • DEPLOYMENT_NAME: o nome da implementação do contentor.
    • NUMBER_OF_REPLICAS: o número de objetos Pod replicados que a implementação gere.
    • APP_NAME: o nome da aplicação a executar na implementação.
    • CONTAINER_NAME: o nome do contentor.
    • HARBOR_INSTANCE_URL: o URL da instância do Harbor, como harbor-1.org-1.zone1.google.gdc.test. Para aceder ao URL da instância do Harbor, consulte Ver instâncias do registo do Harbor.
    • HARBOR_PROJECT_NAME: o nome do projeto do Harbor, como my-project.
    • IMAGE: o nome da imagem, como nginx.
    • TAG: a etiqueta da versão da imagem que quer obter, como 1.0.
  4. Repita os passos anteriores para cada zona no seu universo do GDC. Certifique-se de que a aplicação de contentor reside em todas as zonas que quer para a sua estratégia de HA.

Exponha a sua aplicação de contentor através do Kubernetes

Tem de expor a sua aplicação de contentor para permitir o acesso à mesma a partir de outros recursos no seu universo da GDC.

  1. Crie um recurso Service de type: LoadBalancer. Este recurso expõe os pods da sua aplicação através de uma rede.

    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
    

    Substitua o seguinte:

    • KUBERNETES_CLUSTER: o ficheiro kubeconfig para o cluster Kubernetes zonal no qual está a implementar cargas de trabalho de contentores.
    • PROJECT: o espaço de nomes do projeto no qual as cargas de trabalho do contentor residem.
    • SERVICE_NAME: o nome do serviço de balanceador de carga.
    • APP_NAME: a etiqueta que aplicou para a sua aplicação de contentor.
  2. Crie um recurso personalizado NetworkPolicy para permitir todo o tráfego de rede para o espaço de nomes predefinido:

    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
    

Aprovisione armazenamento persistente para os seus pods

Tem de criar um recurso PersistentVolumeClaim (PVC) para fornecer pods de aplicações com armazenamento persistente.

As instruções seguintes mostram como criar um volume através da GDC standard-rwo StorageClass.

  1. Crie um recurso PersistentVolumeClaim. Por exemplo, configure-o com um ReadWriteOnce modo de acesso e uma standard-rwo classe de armazenamento:

    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
    

    Substitua o seguinte:

    • KUBERNETES_CLUSTER: o ficheiro kubeconfig para o cluster do Kubernetes.
    • PROJECT: o espaço de nomes do projeto no qual criar o PVC.
    • PVC_NAME: o nome do objeto PersistentVolumeClaim.
  2. Os objetos PersistentVolume (PV) são aprovisionados dinamicamente. Verifique o estado dos novos volumes persistentes no seu cluster do Kubernetes:

    kubectl get pv --kubeconfig KUBERNETES_CLUSTER
    

    O resultado é semelhante ao seguinte:

    NAME       CAPACITY   ACCESS MODES   STATUS      CLAIM     STORAGECLASS   AGE
    pvc-uuidd  10Gi       RWO            Bound       pvc-name  standard-rwo   60s
    
  3. Configure as cargas de trabalho do contentor para usar o PVC. Segue-se um exemplo de um manifesto de pod que usa um PVC:standard-rwo

    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
    

    Substitua o seguinte:

    • KUBERNETES_CLUSTER: o ficheiro kubeconfig para o cluster do Kubernetes no qual está a implementar cargas de trabalho de contentores.
    • PROJECT: o espaço de nomes do projeto no qual o PVC reside.
    • APP_LABEL: a etiqueta que aplicou para a sua aplicação de contentor.
    • CONTAINER_NAME: o nome do contentor.
    • HARBOR_INSTANCE_URL: o URL da instância do Harbor, como harbor-1.org-1.zone1.google.gdc.test. Para aceder ao URL da instância do Harbor, consulte Ver instâncias do registo do Harbor.
    • HARBOR_PROJECT_NAME: o nome do projeto do Harbor, como my-project.
    • IMAGE: o nome da imagem, como nginx.
    • TAG: a etiqueta da versão da imagem que quer obter, como 1.0.
    • MOUNT_PATH: o caminho no interior do pod para montar o volume.
    • PVC_NAME: o PVC que criou.

Configure a replicação de armazenamento assíncrona

Os universos multizona da GDC oferecem a utilização de recursos de armazenamento replicados, como volumes e contentores, no modo assíncrono para cenários de recuperação de desastres. Estas opções de recursos de armazenamento oferecem replicação de dados assíncrona entre quaisquer duas zonas na mesma região. A replicação assíncrona ocorre em segundo plano, oferecendo um objetivo de ponto de recuperação (RPO) baixo, mas não nulo, em caso de desastre. Todos os dados replicados estão online e imediatamente acessíveis, mas podem exigir um procedimento de comutação por falha manual para permitir a escrita na zona secundária.

Pode escolher um dos seguintes tipos de replicação de armazenamento assíncrona para a sua aplicação de contentor:

Crie um contentor de zona dupla para armazenamento de objetos

Os dados de armazenamento de objetos são escritos num único contentor cujos dados são armazenados em ambas as zonas. Uma vez que os dados são copiados de forma assíncrona entre zonas, as zonas podem não conter as mesmas versões de objetos em qualquer momento, mas acabam por ficar equivalentes se não forem feitas alterações adicionais. Ao contrário da replicação de volumes, os contentores replicados são graváveis durante as partições de zonas. Cada gravação num objeto produz uma versão diferente, e a versão mais recente em qualquer zona é o estado final após o restauro da conetividade.

  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 o armazenamento de objetos. Este recurso tem de ser implementado no servidor de API global raiz.

  2. Crie o recurso personalizado Bucket de zona dupla:

    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 o seguinte:

    • GLOBAL_API_SERVER: o ficheiro kubeconfig para o servidor de API global.
    • BUCKET_NAME: o nome do contentor de armazenamento.
    • PROJECT: o nome do projeto onde o contentor reside.
    • LOCATION_NAME: o local físico onde os dados de objetos no contentor residem. Tem de ser mapeado para o nome de um recurso BucketLocation existente. Para consultar o servidor da API global da sua organização para obter uma lista de recursos BucketLocation disponíveis, execute kubectl --kubeconfig GLOBAL_API_SERVER bucketlocations. Se não existirem recursos BucketLocation, contacte o seu IO para verificar se ativou a replicação assíncrona.

Configure a replicação de armazenamento em blocos assíncrona em várias zonas

O armazenamento de blocos replicado oferece volumes replicados de forma assíncrona (PVs), que mantêm a equivalência de blocos entre os volumes principal e secundário. Devido à natureza assíncrona, o volume secundário reflete o estado da zona principal num determinado momento no passado (RPO diferente de zero). O volume secundário não é montável enquanto permanecer o destino da replicação, o que requer intervenção manual para terminar a relação e permitir que as gravações ocorram.

Tem de configurar uma relação de replicação de armazenamento entre zonas para criar dados replicados que estejam disponíveis para a comutação por falha se os dados da zona de origem ficarem indisponíveis. Isto é relevante se estiver a usar o armazenamento de blocos para a sua aplicação de contentores.

Antes de começar, verifique se o seu operador de infraestrutura (IO) criou e configurou os recursos personalizados StorageClusterPeering e StorageVirtualMachinePeering para permitir a replicação do armazenamento de blocos em várias zonas. Este recurso tem de ser implementado no servidor de API global raiz.

  1. Crie um ficheiro YAML de recursos personalizados VolumeReplicationRelationshipe implemente-o no servidor de API global:

    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
    

    Substitua o seguinte:

    • GLOBAL_API_SERVER: o ficheiro kubeconfig para o servidor de API global.
    • PVC_REPL_NAME: o nome da relação de replicação de volume.
    • PROJECT: o projeto onde reside a infraestrutura de armazenamento.
    • SOURCE_PVC_CLUSTER: o cluster do Kubernetes onde o PVC está alojado.
    • SOURCE_PVC: o PVC na zona de origem a replicar.
    • SOURCE_ZONE: a zona de origem onde o PVC está alojado.
    • DEST_PVC_CLUSTER: o cluster Kubernetes de destino para replicar o PVC.
    • DEST_ZONE: a zona de destino para replicar o PVC.
  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: PVC_FAILOVER_NAME
      namespace: PROJECT
    spec:
      volumeReplicationRelationshipRef: PVC_REPL_NAME
    EOF
    

    Substitua o seguinte:

    • MANAGEMENT_API_SERVER: o ficheiro kubeconfig do servidor da API Management zonal.
    • PVC_FAILOVER_NAME: o nome da comutação por falha do PVC.
    • PROJECT: o projeto onde reside a infraestrutura de armazenamento.
    • PVC_REPL_NAME: o nome da relação de replicação de volume.

O que se segue?