Implantar serviços LoadBalancer de várias redes

Este documento mostra como expor pods de várias redes a clientes internos ou externos criando Google Cloud recursos de balanceador de carga de rede de passagem externa e balanceador de carga de rede de passagem interna no GKE. Ele descreve a configuração, os recursos e as limitações necessários dos serviços LoadBalancer de várias redes.

Se você conectar cargas de trabalho a várias redes VPC, use um serviço do Kubernetes do tipo LoadBalancer para encaminhar o tráfego para pods em uma rede secundária específica. Ao criar o serviço, o GKE cria um balanceador de carga de rede de passagem para gerenciar esse tráfego.

Para mais informações sobre várias redes no GKE, consulte Sobre o suporte a várias redes para pods.

Como os serviços LoadBalancer de várias redes funcionam

Para expor uma carga de trabalho de várias redes, crie um Service de type: LoadBalancer. O serviço precisa incluir um seletor especial que segmenta pods com base na rede da interface secundária. Adicione uma anotação para especificar se você quer criar um balanceador de carga interno ou externo.

O rótulo networking.gke.io/network no seletor filtra endpoints por rede. Esse rótulo garante que o balanceador de carga envie tráfego apenas para as interfaces de pod conectadas à rede especificada.

Limitações

Os balanceadores de carga de várias redes têm as seguintes limitações:

  • Serviços que usam externalTrafficPolicy: Cluster não são aceitos.
  • Serviços que segmentam pods hostNetwork não são aceitos.
  • As redes IPv6 e de pilha dupla não são aceitas.
  • Não é possível mudar a rede de um serviço atual.
  • Somente redes da camada 3 são aceitas.
  • Balanceadores de carga baseados em pools de destino ou back-ends de grupos de instâncias não são aceitos.
  • Os serviços ClusterIP e NodePort não são aceitos em redes secundárias (não padrão).

Antes de começar

Antes de começar, faça o seguinte:

  1. Siga as etapas em Configurar o suporte a várias redes para pods para preparar suas redes VPC e criar um cluster do GKE com uma rede extra.
  2. Verifique se o cluster tem a criação de subconjuntos para balanceadores de carga internos da camada 4 ativada. Para ativar esse recurso, use a flag --enable-l4-ilb-subsetting ao criar ou atualizar o cluster.
  3. Verifique se o cluster está executando a versão 1.37 ou mais recente do GKE.

Implantar pods de várias redes

Para anexar pods a uma rede extra, crie uma implantação com a anotação networking.gke.io/interfaces. Essa anotação especifica as redes e interfaces dos pods.

  1. Salve o seguinte manifesto como web-app-deployment.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: web-app
      labels:
        app: web-app
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: web-app
      template:
        metadata:
          labels:
            app: web-app
          annotations:
            networking.gke.io/default-interface: 'eth1'
            networking.gke.io/interfaces: '[
              {"interfaceName":"eth0","network":"default"},
              {"interfaceName": "eth1","network": "dmz"}
            ]'
    spec:
      containers:
      - name: whereami
        image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1
        ports:
        - containerPort: 8080
    

    Esse manifesto cria uma implantação chamada web-app com três pods. Os pods têm duas interfaces: eth0 conectada à rede default e eth1 conectada à rede dmz. A anotação networking.gke.io/default-interface define eth1 como a interface padrão dos pods.

  2. Aplique o manifesto ao cluster:

    kubectl apply -f web-app-deployment.yaml
    

Se você usar uma interface não padrão para o serviço, será necessário configurar o roteamento no pod. Para configurar o roteamento, adicione um initContainer à especificação do pod que tenha a capacidade NET_ADMIN.

O exemplo a seguir mostra um initContainer que adiciona uma rota padrão para a interface eth1:

initContainers:
      - name: init-routes-busybox
        image: busybox
        command: ['sh', '-c', 'ip route add default dev eth1 table 200 && ip rule add from 172.16.1.0/24 table 200']
        securityContext:
          capabilities:
            add: ["NET_ADMIN"]

No comando initContainer, substitua 172.16.1.0/24 pelo intervalo de endereços IP secundário da rede de pods.

Implantar um serviço LoadBalancer interno

Para expor a implantação web-app na rede dmz, crie um serviço LoadBalancer interno.

  1. Salve o seguinte manifesto como internal-lb-service.yaml:

    apiVersion: v1
    kind: Service
    metadata:
      name: web-app-internal-lb
      namespace: default
      annotations:
        networking.gke.io/load-balancer-type: "Internal"
    spec:
      externalTrafficPolicy: Local
      ports:
      -   port: 80
        protocol: TCP
        targetPort: 8080
      selector:
        networking.gke.io/network: dmz
        app: web-app
      type: LoadBalancer
    

    Esse manifesto cria um serviço com as seguintes propriedades:

    • networking.gke.io/load-balancer-type: "Internal": especifica um balanceador de carga de rede de passagem interna.
    • selector: seleciona pods com o rótulo app: web-app que estão conectados à rede dmz.
  2. Aplique o manifesto ao cluster:

    kubectl apply -f internal-lb-service.yaml
    

Implantar um serviço LoadBalancer externo

Para expor a implantação web-app a clientes externos, crie um serviço LoadBalancer externo.

  1. Salve o seguinte manifesto como external-lb-service.yaml:

    apiVersion: v1
    kind: Service
    metadata:
      name: web-app-external-lb
      namespace: default
      annotations:
        cloud.google.com/l4-rbs: "enabled"
    spec:
      externalTrafficPolicy: Local
      ports:
      -   port: 80
        protocol: TCP
        targetPort: 8080
      selector:
        networking.gke.io/network: dmz
        app: web-app
      type: LoadBalancer
    

    Esse manifesto cria um serviço com as seguintes propriedades:

    • cloud.google.com/l4-rbs: "enabled": especifica um balanceador de carga de rede de passagem externa baseado em serviço de back-end.
    • selector: seleciona pods com o rótulo app: web-app que estão conectados à rede dmz.
  2. Aplique o manifesto ao cluster:

    kubectl apply -f external-lb-service.yaml
    

Verificar os serviços

Depois de implantar os serviços, verifique se os balanceadores de carga foram criados e configurados corretamente.

  1. Verifique o status dos serviços:

    kubectl get services
    

    O resultado será assim:

    NAME                  TYPE           CLUSTER-IP    EXTERNAL-IP     PORT(S)        AGE
    web-app-external-lb   LoadBalancer   10.8.47.77    35.239.57.231   80:31550/TCP   5m
    web-app-internal-lb   LoadBalancer   10.8.43.251   172.16.0.43     80:32628/TCP   6m
    kubernetes            ClusterIP      10.8.32.1     <none>          443/TCP        43h
    

    O endereço EXTERNAL-IP do balanceador de carga interno pertence à rede dmz.

  2. Liste as regras de encaminhamento no seu projeto:

    gcloud compute forwarding-rules list
    

    O resultado será assim:

    NAME                                                   REGION        IP_ADDRESS     IP_PROTOCOL  TARGET
    af901673cc0f24907a6aa8c3ce4afc21                       us-central1   35.239.57.231  TCP          us-central1/backendServices/k8s2-xhvzqabw-default-web-app-external-lb-u4xbs4ot
    k8s2-tcp-xhvzqabw-default-web-app-internal-lb-vp1x1d6a us-central1   172.16.0.43    TCP          us-central1/backendServices/k8s2-xhvzqabw-default-web-app-internal-lb-vp1x1d6a
    
  3. Descreva a regra de encaminhamento do balanceador de carga interno para verificar se ela está anexada à rede correta:

    gcloud compute forwarding-rules describe k8s2-tcp-xhvzqabw-default-web-app-internal-lb-vp1x1d6a --region=$REGION
    

    Substitua REGION pela região do cluster.

    A resposta será semelhante a esta: Verifique se os campos network e subnetwork correspondem aos detalhes da rede dmz.

    IPAddress: 172.16.0.43
    IPProtocol: TCP
    ...
    loadBalancingScheme: INTERNAL
    name: k8s2-tcp-xhvzqabw-default-web-app-internal-lb-vp1x1d6a
    network: https://www.googleapis.com/compute/v1/projects/projectId/global/networks/dmz-vpc
    ...
    subnetwork: https://www.googleapis.com/compute/v1/projects/projectId/regions/us-central1/subnetworks/dmz-subnet
    

Testar os balanceadores de carga

  1. Para testar o balanceador de carga externo, envie uma solicitação para o endereço IP externo dele:

    curl EXTERNAL_LB_IP:80
    

    Substitua EXTERNAL_LB_IP pelo endereço IP externo do serviço web-app-external-lb.

  2. Para testar o balanceador de carga interno, envie uma solicitação de um host na mesma VPC que o balanceador de carga:

    curl INTERNAL_LB_IP:80
    

    Substitua INTERNAL_LB_IP pelo endereço IP do serviço web-app-internal-lb.

Solução de problemas

Esta seção descreve como solucionar problemas com balanceadores de carga de várias redes.

Falha na criação do balanceador de carga

Se a criação do balanceador de carga falhar, verifique os eventos de serviço em busca de mensagens de erro:

kubectl describe service SERVICE_NAME

Substitua SERVICE_NAME pelo nome do serviço.

Uma mensagem de erro como network some-other-network does not exist indica que a rede especificada no seletor de serviço não está definida no cluster. Verifique se a rede existe:

kubectl get networks

Se a rede existir, verifique se o objeto Network faz referência corretamente a um recurso GKENetworkParamSet válido. Para verificar se há erros de configuração, inspecione o status do recurso Network:

kubectl get networks NETWORK_NAME -o yaml

Substitua NETWORK_NAME pelo nome da sua rede.

Em uma configuração válida, as condições ParamsReady e Ready são True. Se ParamsReady não for True, verifique se o parametersRef na especificação Network corresponde corretamente ao nome, tipo e grupo de um recurso GKENetworkParamSet atual.

Se o recurso Network estiver correto, mas ainda não estiver pronto, verifique o status de GKENetworkParamSet referenciado em busca de erros, como uma sub-rede ausente:

kubectl get gkenetworkparamsets GNP_NAME -o yaml

Substitua GNP_NAME pelo nome do GKENetworkParamSet.

O balanceador de carga não tem back-ends

Se o balanceador de carga for provisionado, mas não tiver back-ends íntegros, faça o seguinte:

  1. Verifique se existe um pool de nós com interfaces de rede na rede usada pelo serviço.
  2. Verifique se os pods selecionados pelo serviço estão em execução.
  3. Verifique os endpoints do serviço:

    kubectl describe endpointslice -l kubernetes.io/service-name=SERVICE_NAME
    

    O controlador multinet-endpointslice-controller.gke.io cria os endpoints de várias redes. Os endereços IP de pod listados no EndpointSlice pertencem à rede usada pelo serviço. Se o EndpointSlice não tiver endpoints, verifique se os rótulos do seletor de serviço correspondem aos pods em execução e se o seletor de rede corresponde à rede dos pods.

A seguir