Criar um balanceador de carga interno em redes VPC

Nesta página, explicamos como criar um balanceador de carga de rede de passagem interna no Google Kubernetes Engine (GKE) entre redes VPC.

Antes de ler este documento, confira se você conhece os seguintes conceitos:

Antes de começar

Antes de começar, verifique se você realizou as tarefas a seguir:

  • Ativar a API Google Kubernetes Engine.
  • Ativar a API Google Kubernetes Engine
  • Se você quiser usar a CLI do Google Cloud para essa tarefa, instale e inicialize a gcloud CLI. Se você instalou a CLI gcloud anteriormente, instale a versão mais recente executando o comando gcloud components update. Talvez as versões anteriores da CLI gcloud não sejam compatíveis com a execução dos comandos neste documento.

Criar um balanceador de carga interno com o Private Service Connect

Como produtor de serviço, é possível usar anexos de serviço para disponibilizar seus serviços aos consumidores de serviço em outras redes VPC usando o Private Service Connect. É possível criar, gerenciar e excluir anexos de serviço usando um recurso personalizado ServiceAttachment.

Requisitos e limitações

  • Limitações se aplicam ao Private Service Connect.
  • É possível criar um anexo de serviço nas versões 1.21.4-gke.300 e posteriores do GKE.
  • O cluster precisa ter o complemento HttpLoadBalancing ativado. Os novos clusters do GKE têm o complemento HttpLoadBalancing ativado por padrão.
  • Não é possível usar a mesma sub-rede em várias configurações de anexos do serviço.
  • Você precisa criar um serviço do GKE que usa um balanceador de carga de rede de passagem interna.
  • Não é possível especificar uma sub-rede em um projeto diferente (VPC compartilhada) para versões do GKE anteriores a 1.22.4-gke.100. Para a VPC compartilhada, verifique se todos os requisitos da VPC compartilhada foram atendidos.
  • Depois de criar um anexo de serviço, não é possível atualizar o balanceador de carga interno. Para mudar as configurações do balanceador de carga, exclua e recrie a vinculação de serviço.

Criar um ServiceAttachment

  1. Crie uma sub-rede.

    É necessário criar uma nova sub-rede para cada ServiceAttachment.

    gcloud beta compute networks subnets create SUBNET_NAME \
        --project PROJECT_ID \
        --network NETWORK_NAME \
        --region REGION \
        --range SUBNET_RANGE \
        --purpose PRIVATE_SERVICE_CONNECT
    

    Substitua:

    • SUBNET_NAME: o nome da nova sub-rede; Nas versões 1.22.4-gke.100 e posteriores do GKE, é possível especificar uma sub-rede em um projeto diferente usando o URL de recurso totalmente qualificado para esse campo. Você pode conseguir o URL do recurso totalmente qualificado usando o comando gcloud compute networks subnets describe.
    • PROJECT_ID: o ID do seu projeto Google Cloud.
    • NETWORK_NAME: o nome da rede VPC da sub-rede;
    • REGION: a região da nova sub-rede. Use a mesma região do serviço criado;
    • SUBNET_RANGE: o intervalo de endereços IP a ser usado para a sub-rede.
  2. Implante uma carga de trabalho.

    No manifesto a seguir, veja uma implantação que executa uma imagem de amostra do contêiner de aplicativo da Web. Salve o manifesto como my-deployment.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: psc-ilb
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: psc-ilb
      template:
        metadata:
          labels:
            app: psc-ilb
        spec:
          containers:
          - name: whereami
            image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1
            ports:
              - name: http
                containerPort: 8080
            readinessProbe:
              httpGet:
                path: /healthz
                port: 8080
                scheme: HTTP
              initialDelaySeconds: 5
              timeoutSeconds: 1
    
  3. Aplique o manifesto ao cluster:

    kubectl apply -f my-deployment.yaml
    
  4. Crie um serviço O manifesto a seguir descreve um serviço que cria um balanceador de carga de rede de passagem interna na porta TCP 8080. Salve o manifesto como my-service.yaml:

     apiVersion: v1
     kind: Service
     metadata:
       name: SERVICE_NAME
       annotations:
         networking.gke.io/load-balancer-type: "Internal"
     spec:
       type: LoadBalancer
       selector:
         app: psc-ilb
       ports:
       - port: 80
         targetPort: 8080
         protocol: TCP
    

    Substitua:

    • SERVICE_NAME: o nome do novo serviço;
  5. Aplique o manifesto ao cluster:

    kubectl apply -f my-service.yaml
    
  6. Criar ServiceAttachment.

    O manifesto a seguir descreve um ServiceAttachment que expõe o serviço criado para os consumidores de serviço. Salve o manifesto como my-psc.yaml:

    apiVersion: networking.gke.io/v1
    kind: ServiceAttachment
    metadata:
     name: SERVICE_ATTACHMENT_NAME
     namespace: default
    spec:
     connectionPreference: ACCEPT_AUTOMATIC
     natSubnets:
     - SUBNET_NAME
     proxyProtocol: false
     resourceRef:
       kind: Service
       name: SERVICE_NAME
    

    Substitua:

    • SERVICE_ATTACHMENT_NAME: o nome do novo anexo de serviço.
    • SUBNET_NAME: o nome da nova sub-rede. Nas versões 1.22.4-gke.100 e posteriores do GKE, é possível especificar uma sub-rede em um projeto diferente usando o URL de recurso totalmente qualificado para esse campo. Você pode conseguir o URL do recurso totalmente qualificado usando o comando gcloud compute networks subnets describe. Para uma configuração de VPC compartilhada, use o seguinte formato: projects/HOST_PROJECT_ID/regions/COMPUTE_REGION/subnetworks/SUBNET_NAME.

    Para saber mais sobre os campos de manifesto, consulte os campos de anexo de serviço.

  7. Aplique o manifesto ao cluster:

    kubectl apply -f my-psc.yaml
    
  8. Verifique se o controlador do Private Service Connect criou o anexo de serviço:

    gcloud beta compute service-attachments list
    

    A saída mostra um anexo de serviço com um nome gerado automaticamente:

    NAME        REGION       PRODUCER_FORWARDING_RULE          CONNECTION_PREFERENCE
    k8s1-sa-... REGION_NAME  a3fea439c870148bdba5e59c9ea9451a  ACCEPT_AUTOMATIC
    

Veja uma ServiceAttachment

Para visualizar os detalhes de uma ServiceAttachment, use o seguinte comando:

kubectl describe serviceattachment SERVICE_ATTACHMENT_NAME

O resultado será assim:

Name:        <sa-name>
Namespace:    default
Labels:       <none>
Annotations:  <none>
API Version:  networking.gke.io/v1beta1
Kind:         ServiceAttachment
Metadata:
  ...
Status:
  Forwarding Rule URL:      https://www.googleapis.com/compute/beta/projects/<project>/regions/<region>/forwardingRules/<fr-name>
  Last Modified Timestamp:  2021-07-08T01:32:39Z
  Service Attachment URL:   https://www.googleapis.com/compute/beta/projects/<projects>/regions/<region>/serviceAttachments/<gce-service-attachment-name>
Events:                     <none>

Consumir um ServiceAttachment

Para consumir o serviço de outro projeto, siga estas etapas:

  1. Consiga o URL do ServiceAttachment:

    kubectl get serviceattachment SERVICE_ATTACHMENT_NAME -o=jsonpath="{.status.serviceAttachmentURL}"
    

    O resultado será assim:

      serviceAttachmentURL: https://www.googleapis.com/compute/alpha/projects/<project>/region/<region>/serviceAttachments/k8s1-...my-sa
    
  2. Crie um endpoint do Private Service Connect usando o URL do ServiceAttachment.

  3. Verifique se é possível se conectar ao serviço implantado no projeto do produtor usando um comando curl de uma VM no projeto do consumidor:

    curl PSC_IP_ADDRESS
    

    Substitua PSC_IP_ADDRESS pelo endereço IP da regra de encaminhamento no projeto do consumidor.

    O resultado será assim:

    {
      "cluster_name":"cluster",
      "host_header":"10.128.15.200",
      "node_name":"gke-psc-default-pool-be9b6e0e-dvxg.c.gke_project.internal",
      "pod_name":"foo-7bf648dcfd-l5jf8",
      "pod_name_emoji":"👚",
      "project_id":"gke_project",
      "timestamp":"2021-06-29T21:32:03",
      "zone":"ZONE_NAME"
    }
    

Atualizar um ServiceAttachment

É possível atualizar um ServiceAttachment usando as seguintes etapas:

  1. Edite o manifesto ServiceAttachment em my-psc.yaml:

    apiVersion: networking.gke.io/v1
    kind: ServiceAttachment
    metadata:
      name: my-sa
      namespace: default
    spec:
      connectionPreference: ACCEPT_AUTOMATIC
      natSubnets:
      - my-nat-subnet
      proxyProtocol: false
      resourceRef:
        kind: Service
        name: ilb-service
    
  2. Aplique o manifesto ao cluster:

    kubectl apply -f my-psc.yaml
    

Excluir um ServiceAttachment

Não é possível excluir um balanceador de carga de rede de passagem interna conectado a um anexo de serviço. É necessário excluir o anexo de serviço e o serviço do GKE separadamente.

  1. Exclua o anexo de serviço:

    kubectl delete serviceattachment SERVICE_ATTACHMENT_NAME --wait=false
    

    Esse comando marca o anexo de serviço para exclusão, mas o recurso continua a existir. Também é possível aguardar a conclusão da exclusão omitindo a sinalização --wait.

  2. Exclua o serviço:

    kubectl delete svc SERVICE_NAME
    
  3. Exclua a sub-rede:

    gcloud compute networks subnets delete SUBNET_NAME
    

ServiceAttachment campos

O ServiceAttachment tem os seguintes campos:

  • connectionPreference: a preferência de conexão que determina como os clientes se conectam ao serviço. É possível usar a aprovação automática do projeto usando ACCEPT_AUTOMATIC ou a aprovação explícita do projeto usando ACCEPT_MANUAL. Para mais informações, consulte Como publicar serviços usando o Private Service Connect.
  • natSubnets: uma lista de nomes de recurso de sub-rede a serem usados para o anexo de serviço.
  • proxyProtocol: quando definido como verdadeiro, o IP de origem do consumidor e o ID da conexão do Private Service Connect estão disponíveis nas solicitações. Esse campo é opcional e o padrão será falso se não for fornecido.
  • consumerAllowList: a lista de projetos de consumidor que têm permissão para se conectar ao ServiceAttachment. Este campo só pode ser usado quando connectionPreference é ACCEPT_MANUAL. Para mais informações sobre esse campo, consulte Como publicar serviços usando o Private Service Connect.
    • project: o ID ou o número do projeto do consumidor.
    • connectionLimit: o limite de conexão do projeto do consumidor. Este campo é opcional.
    • forceSendFields: os nomes de campo a serem enviados para incluir nas solicitações de API. Este campo é opcional.
    • nullFields: os nomes de campo a serem incluídos nas solicitações de API com um valor nulo. Este campo é opcional.
  • consumerRejectList: a lista de IDs de projeto ou números de consumidores que não têm permissão para se conectar a ServiceAttachment. Este campo só pode ser usado quando connectionPreference é ACCEPT_MANUAL. Para mais informações sobre esse campo, consulte Como publicar serviços usando o Private Service Connect.
  • resourceRef: uma referência ao recurso do Kubernetes.

    • kind: o tipo do recurso do Kubernetes. Você precisa usar Service.
    • name: o nome do recurso do Kubernetes que precisa estar no mesmo namespace que o balanceador de carga de rede de passagem interna.

Solução de problemas

É possível ver as mensagens de erro usando o seguinte comando:

kubectl get events -n NAMESPACE

Substitua NAMESPACE pelo namespace do balanceador de carga de rede de passagem interna.

Erro ao excluir o balanceador de carga de rede de passagem interna

Se você tentar excluir um balanceador de carga de rede de passagem interna que está sendo usado por um anexo de serviço, ocorrerá uma mensagem de erro semelhante à mensagem a seguir. É preciso excluir o ServiceAttachment antes de excluir o balanceador de carga de rede de passagem interna.

Error syncing load balancer: failed to ensure load balancer: googleapi:
Error 400: The forwarding_rule resource '<fwd-rule-URL>' is already being used
by '<svc-attachment-URL>', resourceInUseByAnotherResource.

Erro ao ativar o acesso global

Você pode encontrar um erro ao ativar o acesso global para um balanceador de carga de rede de passagem interna que usa um anexo de serviço do Private Service Connect.

Sintoma:

Quando você ativa o acesso global atualizando o manifesto do serviço do GKE e definindo a anotação networking.gke.io/internal-load-balancer-allow-global-access: "true", a atualização falha ao aplicar o manifesto. Você vai ver a seguinte mensagem de erro ao executar o comando kubectl get events:

Error syncing load balancer: failed to ensure load balancer: googleapi: Error 400: The forwarding_rule resource '...' is already being used by '...', resourceInUseByAnotherResource

Motivo:

Esse erro ocorre porque o plano de controle do GKE tenta recriar a regra de encaminhamento do balanceador de carga para ativar o acesso global. No entanto, como a regra de encaminhamento está sendo usada por um ServiceAttachment, ela não pode ser excluída e recriada, o que resulta no erro.

Alternativa:

Para ativar o acesso global no balanceador de carga e minimizar o tempo de inatividade, você precisa atualizar a configuração do serviço do GKE e atualizar manualmente a regra de encaminhamento:

  1. Atualize o manifesto de serviço do GKE: atualize o manifesto de serviço do GKE para incluir a anotação networking.gke.io/internal-load-balancer-allow-global-access: "true".

  2. Ative manualmente o acesso global na regra de encaminhamento: siga as etapas em Ativar o acesso global para atualizar a regra de encaminhamento do balanceador de carga usando o consoleGoogle Cloud , a Google Cloud CLI ou a API Compute Engine.

A seguir