Nesta página, explicamos como usar o balanceamento de carga nativo de contêiner no Google Kubernetes Engine (GKE). O balanceamento de carga nativo de contêiner permite que os balanceadores de carga segmentem os pods do Kubernetes diretamente e distribuam o tráfego aos pods por igual.
Para mais informações sobre benefícios, requisitos e limitações do balanceamento de carga nativo de contêiner, consulte esta página.
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 Google Cloud CLI para essa tarefa,
instale e, em seguida,
inicialize a
CLI gcloud. Se você instalou a CLI gcloud anteriormente, instale a versão
mais recente executando
gcloud components update
.
Usar balanceamento de carga nativo de contêiner
Nas seções a seguir, você será orientado por uma configuração de balanceamento de carga nativo de contêiner no GKE. Para clusters do GKE que
executam a versão 1.17 ou superior e sob determinadas condições,
o balanceamento de carga nativo de contêiner é padrão e não exige uma anotação
de serviço cloud.google.com/neg: '{"ingress": true}'
explícita.
Criar um cluster nativo de VPC
Para usar o balanceamento de carga nativo de contêiner, os IPs do alias do cluster do GKE precisam estar ativados.
Por exemplo, o comando a seguir cria um cluster do GKE,
neg-demo-cluster
, com uma sub-rede provisionada automaticamente:
No modo Autopilot, os endereços IP do alias são ativados por padrão:
gcloud container clusters create-auto neg-demo-cluster \ --location=COMPUTE_LOCATION
Substitua
COMPUTE_LOCATION
pelo local do Compute Engine do cluster.
No modo Standard, ative os endereços IP do alias ao criar o cluster:
gcloud container clusters create neg-demo-cluster \ --enable-ip-alias \ --create-subnetwork="" \ --network=default \ --zone=us-central1-a
Criar uma implantação
No exemplo de implantação a seguir, neg-demo-app
executa uma única instância de um servidor HTTP em contêiner. Recomendamos o uso de cargas de trabalho que utilizem o feedback de prontidão do pod.
Como usar o feedback de prontidão do pod
apiVersion: apps/v1 kind: Deployment metadata: labels: run: neg-demo-app # Label for the Deployment name: neg-demo-app # Name of Deployment spec: selector: matchLabels: run: neg-demo-app template: # Pod template metadata: labels: run: neg-demo-app # Labels Pods from this Deployment spec: # Pod specification; each Pod created by this Deployment has this specification containers: - image: registry.k8s.io/serve_hostname:v1.4 # Application to run in Deployment's Pods name: hostname # Container name ports: - containerPort: 9376 protocol: TCP
Como usar o atraso fixado no código
apiVersion: apps/v1 kind: Deployment metadata: labels: run: neg-demo-app # Label for the Deployment name: neg-demo-app # Name of Deployment spec: minReadySeconds: 60 # Number of seconds to wait after a Pod is created and its status is Ready selector: matchLabels: run: neg-demo-app template: # Pod template metadata: labels: run: neg-demo-app # Labels Pods from this Deployment spec: # Pod specification; each Pod created by this Deployment has this specification containers: - image: registry.k8s.io/serve_hostname:v1.4 # Application to run in Deployment's Pods name: hostname # Container name # Note: The following line is necessary only on clusters running GKE v1.11 and lower. # For details, see https://cloud.google.com/kubernetes-engine/docs/how-to/container-native-load-balancing#align_rollouts ports: - containerPort: 9376 protocol: TCP terminationGracePeriodSeconds: 60 # Number of seconds to wait for connections to terminate before shutting down Pods
Nesta implantação, cada contêiner executa um servidor HTTP. O servidor HTTP retorna o nome do host do servidor de aplicativos (nome do pod em que o servidor é executado) como uma resposta.
Salve este manifesto como neg-demo-app.yaml
e crie a implantação:
kubectl apply -f neg-demo-app.yaml
Criar um serviço para um balanceador de carga nativo de contêiner
Depois de criar uma implantação, você precisa agrupar os pods correspondentes em um serviço.
O exemplo de serviço a seguir, neg-demo-svc
, é direcionado para a implantação de exemplo criada na seção anterior:
apiVersion: v1
kind: Service
metadata:
name: neg-demo-svc # Name of Service
annotations:
cloud.google.com/neg: '{"ingress": true}' # Creates a NEG after an Ingress is created
spec: # Service's specification
type: ClusterIP
selector:
run: neg-demo-app # Selects Pods labelled run: neg-demo-app
ports:
- name: http
port: 80 # Service's port
protocol: TCP
targetPort: 9376
A anotação do serviço, cloud.google.com/neg: '{"ingress": true}'
, ativa o balanceamento de carga nativo de contêiner. No entanto, o balanceador de carga não é criado até você criar um Ingress para o serviço.
Salve este manifesto como neg-demo-svc.yaml
e crie o serviço:
kubectl apply -f neg-demo-svc.yaml
Criar uma entrada para o serviço
A entrada de serviço (em inglês) a seguir, neg-demo-ing
, é direcionada para o serviço criado:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: neg-demo-ing
spec:
defaultBackend:
service:
name: neg-demo-svc # Name of the Service targeted by the Ingress
port:
number: 80 # Should match the port used by the Service
Salve este manifesto como neg-demo-ing.yaml
e crie a antrada:
kubectl apply -f neg-demo-ing.yaml
Ao criar o Ingress, um balanceador de carga de aplicativo é criado no projeto e os grupos de endpoints de rede (NEGs, na sigla em inglês) são criados em cada zona em que o cluster é executado. Os endpoints no NEG e os do serviço são mantidos em sincronia.
Verificar a entrada
Depois de implantar uma carga de trabalho, agrupar os respectivos pods em um serviço e criar uma entrada para o serviço, é preciso verificar se a entrada provisionou com sucesso o balanceador de carga nativo de contêiner.
Recuperar o status da entrada:
kubectl describe ingress neg-demo-ing
A saída inclui os eventos ADD
e CREATE
:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ADD 16m loadbalancer-controller default/neg-demo-ing
Normal Service 4s loadbalancer-controller default backend set to neg-demo-svc:32524
Normal CREATE 2s loadbalancer-controller ip: 192.0.2.0
Testar o balanceador de carga
Nas seções a seguir, explicaremos como testar a funcionalidade de um balanceador de carga nativo do contêiner.
Visite o endereço IP do Ingress
Aguarde alguns minutos para que o balanceador de carga de aplicativo seja configurado.
É possível verificar se o balanceador de carga nativo do contêiner está funcionando acessando o endereço IP do Ingress.
Para conseguir o endereço IP da entrada, execute o seguinte comando:
kubectl get ingress neg-demo-ing
Na saída do comando, o endereço IP do Ingress é exibido na coluna ADDRESS
. Visite o endereço IP em um navegador da Web.
Verificar status de integridade do serviço de back-end
Também é possível receber o status de integridade do serviço de back-end do balanceador de carga.
Receba uma lista dos serviços de back-end em execução no projeto:
gcloud compute backend-services list
Registre o nome do serviço de back-end que inclui o nome do serviço, como
neg-demo-svc
.Receba o status de integridade do serviço de back-end:
gcloud compute backend-services get-health BACKEND_SERVICE_NAME --global
Substitua
BACKEND_SERVICE_NAME
pelo nome do serviço de back-end.
Testar a Entrada
Outra maneira de testar se o balanceador de carga funciona conforme o esperado é dimensionar o exemplo de implantação, enviando solicitações de teste para o Ingress e verificar se o número correto de réplicas responde.
Escalone a implantação
neg-demo-app
de uma instância para duas instâncias:kubectl scale deployment neg-demo-app --replicas 2
Esse comando pode levar alguns minutos para ser concluído.
Verificar se o lançamento foi concluído:
kubectl get deployment neg-demo-app
A saída precisa incluir duas réplicas disponíveis:
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE neg-demo-app 2 2 2 2 26m
Acessar o endereço IP de entrada:
kubectl describe ingress neg-demo-ing
Se esse comando retornar um erro 404, aguarde alguns minutos para que o balanceador de carga seja iniciado e tente novamente.
Contar o número de respostas distintas do balanceador de carga:
for i in `seq 1 100`; do \ curl --connect-timeout 1 -s IP_ADDRESS && echo; \ done | sort | uniq -c
Substitua
IP_ADDRESS
pelo endereço IP da entrada.O resultado será assim:
44 neg-demo-app-7f7dfd7bc6-dcn95 56 neg-demo-app-7f7dfd7bc6-jrmzf
Nessa saída, o número de respostas distintas é igual ao número de réplicas, o que indica que todos os pods de back-end estão disponibilizando tráfego.
Limpar
Depois de concluir as tarefas nesta página, siga estas etapas para remover os recursos e evitar cobranças indesejadas na conta:
Excluir o cluster
gcloud
gcloud container clusters delete neg-demo-cluster
Console
Acesse a página Google Kubernetes Engine no console do Google Cloud.
Selecione neg-demo-cluster e clique em delete Excluir.
Quando solicitado a confirmar, clique em Excluir.
Solução de problemas
Use as técnicas abaixo para verificar a configuração de rede. As seções a seguir explicam como resolver problemas comuns relacionados ao balanceamento de carga nativo de contêiner.
Veja a documentação de balanceamento de carga para saber como listar grupos de endpoints de rede.
É possível encontrar o nome e as zonas do NEG correspondente a um serviço na anotação
neg-status
do serviço. Veja a especificação do serviço com:kubectl get svc SVC_NAME -o yaml
A anotação
metadata:annotations:cloud.google.com/neg-status
lista as zonas e o nome do NEG correspondente ao serviço.É possível verificar a integridade do serviço de back-end correspondente a um NEG com o seguinte comando:
gcloud compute backend-services --project PROJECT_NAME \ get-health BACKEND_SERVICE_NAME --global
O serviço de back-end tem o mesmo nome que o NEG.
Para imprimir os logs de eventos de um serviço:
kubectl describe svc SERVICE_NAME
A string do nome do serviço inclui o nome e o namespace do serviço correspondente do GKE.
Não é possível criar um cluster com IPs de alias
- Sintomas
Quando você tenta criar um cluster com IPs de alias, pode encontrar o seguinte erro:
ResponseError: code=400, message=IP aliases cannot be used with a legacy network.
- Causas possíveis
Você encontrará esse erro se tentar criar um cluster com IPs de alias que também usa uma rede legada.
- Resolução
Verifique se você não criou um cluster com IPs de alias e uma rede legada ativada simultaneamente. Para mais informações sobre como usar IPs de alias, consulte Criar um cluster nativo de VPC.
O tráfego não alcança os endpoints
- Sintomas
- Erros 502/503 ou conexões rejeitadas.
- Causas possíveis
Novos endpoints geralmente se tornam acessíveis depois de anexados ao balanceador de carga, desde que respondam a verificações de integridade. Poderão ocorrer erros 502 ou conexões rejeitadas se o tráfego não conseguir alcançar os endpoints.
Erros 502 e conexões rejeitadas também podem ser causados por um contêiner que não lida com
SIGTERM
. Se um contêiner não lida comSIGTERM
de maneira explícita, ele encerra imediatamente e para de processar as solicitações. O balanceador de carga continua a enviar tráfego de entrada para este contêiner encerrado, causando erros.O balanceador de carga nativo do contêiner tem apenas um endpoint de back-end. Durante uma atualização gradual, o endpoint antigo é desprogramado antes que o novo endpoint seja programado.
Os pods de back-end são implantados em uma nova zona pela primeira vez depois que um balanceador de carga nativo de contêiner é provisionado. A infraestrutura do balanceador de carga é programada em uma zona quando há pelo menos um endpoint na zona. Quando um novo endpoint é adicionado a uma zona, a infraestrutura do balanceador de carga é programada e causa interrupções no serviço.
- Resolução
Configure os contêineres para lidar com
SIGTERM
e continuar a responder às solicitações durante o período de carência do encerramento (30 segundos por padrão). Configure os pods para começarem a falhar nas verificações de integridade ao receberemSIGTERM
. Isso envia um sinal para que o balanceador de carga pare de enviar tráfego para o pod enquanto a desprogramação do endpoint estiver em andamento.Se o aplicativo não for encerrado normalmente e parar de responder a solicitações ao receber um
SIGTERM
, o hook preStop poderá ser usado para processarSIGTERM
e continuar veiculando tráfego enquanto a desprogramação do endpoint estiver em andamento.lifecycle: preStop: exec: # if SIGTERM triggers a quick exit; keep serving traffic instead command: ["sleep","60"]
Consulte a documentação sobre encerramento de pods.
Se o back-end do balanceador de carga tiver apenas uma instância, configure a estratégia de implantação para evitar a desmontagem da única instância antes que a nova instância seja completamente programada. Para pods de aplicativos gerenciados pela carga de trabalho
Deployment
, isso pode ser feito configurando a estratégia de lançamento com o parâmetromaxUnavailable
igual a0
.strategy: rollingUpdate: maxSurge: 1 maxUnavailable: 0
Para solucionar problemas de tráfego que não alcança os endpoints, verifique se as regras de firewall permitem o tráfego TCP de entrada para os endpoints nos intervalos
130.211.0.0/22
e35.191.0.0/16
. Para saber mais, consulte Como adicionar verificações de integridade na documentação do Cloud Load Balancing.Veja os serviços de back-end no seu projeto. A string de nome do serviço de back-end relevante inclui o nome e o namespace do serviço do GKE correspondente:
gcloud compute backend-services list
Recupere o status de integridade do back-end do serviço correspondente:
gcloud compute backend-services get-health BACKEND_SERVICE_NAME
Se nenhum back-end estiver íntegro, significa que pode haver problemas na configuração de seu firewall, sua entrada ou seu serviço.
Se alguns back-ends não estiverem íntegros por um curto período de tempo, a causa poderá ser a latência de programação de rede.
Se alguns back-ends não aparecerem na lista de serviços de back-end, a causa poderá ser a latência de programação. É possível verificar isso executando o seguinte comando, em que
NEG_NAME
é o nome do serviço de back-end. NEGs e serviços de back-end compartilham o mesmo nome:gcloud compute network-endpoint-groups list-network-endpoints NEG_NAME
Verifique se todos os endpoints esperados estão no NEG.
Se você tiver um pequeno número de back-ends (por exemplo, um pod) selecionado por um balanceador de carga nativo de contêiner, considere aumentar o número de réplicas e distribuir os pods de back-end em todas as zonas do cluster do GKE períodos. Isso garante que a infraestrutura subjacente do balanceador de carga seja totalmente programada. Caso contrário, considere restringir os pods de back-end a uma única zona.
Se você configurar uma política de rede para o endpoint, verifique se a entrada da sub-rede somente proxy é permitida.
Lançamento interrompido
- Sintomas
- O lançamento de uma implantação atualizada é interrompido e o número de réplicas atualizadas não corresponde ao esperado.
- Causas possíveis
As verificações de integridade da implantação estão falhando. A imagem do contêiner pode estar corrompida ou a verificação de integridade pode estar mal configurada. A substituição gradual dos pods aguarda até que o pod recém-iniciado passe pelo bloqueio de prontidão do pod (em inglês). Isso só ocorrerá se o pod estiver respondendo às verificações de integridade do balanceador de carga. Se o pod não estiver respondendo ou se a verificação de integridade estiver configurada incorretamente, as condições do portão de prontidão não poderão ser cumpridas e o lançamento não poderá continuar.
Se você estiver usando
kubectl
1.13 ou superior, é possível verificar o status dos portões de prontidão de um pod com o seguinte comando:kubectl get pod POD_NAME -o wide
Verifique a coluna
READINESS GATES
.Essa coluna não existe em
kubectl
1,12 ou inferior. Um pod marcado comoREADY
pode ter um portão de prontidão falho. Para verificar isso, use o seguinte comando:kubectl get pod POD_NAME -o yaml
Os portões de prontidão e os status deles são listados na saída.
- Resolução
Verifique se a imagem do contêiner na especificação do pod de implantação está funcionando corretamente e se é capaz de responder a verificações de integridade. Verifique se as verificações de integridade estão configuradas corretamente.
Erros de modo degradado
- Sintomas
A partir da versão 1.29.2-gke.1643000 do GKE, você pode receber os seguintes avisos no serviço na Análise de registros quando os NEGs são atualizados:
Entering degraded mode for NEG <service-namespace>/<service-name>-<neg-name>... due to sync err: endpoint has missing nodeName field
- Causas possíveis
Esses avisos indicam que o GKE detectou configurações incorretas do endpoint durante uma atualização do NEG com base em objetos
EndpointSlice
, acionando um processo de cálculo mais detalhado chamado modo degradado. O GKE continua atualizando os NEGs com base no melhor esforço, corrigindo a configuração incorreta ou excluindo os endpoints inválidos das atualizações do NEG.Alguns erros comuns são:
endpoint has missing pod/nodeName field
endpoint corresponds to an non-existing pod/node
endpoint information for attach/detach operation is incorrect
- Resolução
Normalmente, os estados transitórios causam esses eventos e são corrigidos por conta própria. No entanto, os eventos causados por configurações incorretas em objetos
EndpointSlice
personalizados permanecem sem resolução. Para entender a configuração incorreta, examine os objetosEndpointSlice
correspondentes ao serviço:kubectl get endpointslice -l kubernetes.io/service-name=<service-name>
Valide cada endpoint com base no erro do evento.
Para resolver o problema, você precisa modificar manualmente os objetos
EndpointSlice
. A atualização aciona os NEGs a serem atualizados. Quando a configuração incorreta não existir mais, a saída será semelhante a esta:NEG <service-namespace>/<service-name>-<neg-name>... is no longer in degraded mode
Problemas conhecidos
O balanceamento de carga nativo de contêiner no GKE tem os seguintes problemas conhecidos:
Coleta de lixo incompleta
O GKE coleta lixo de balanceadores de carga nativos do recipiente a cada dois minutos. Se um cluster for excluído antes que os balanceadores de carga sejam totalmente removidos, você precisará excluir manualmente os NEGs do balanceador de carga.
Veja os NEGs do seu projeto executando o seguinte comando:
gcloud compute network-endpoint-groups list
Na saída do comando, procure os NEGs relevantes.
Para excluir um NEG, execute o seguinte comando, substituindo NEG_NAME
pelo nome do NEG:
gcloud compute network-endpoint-groups delete NEG_NAME
Alinhar lançamentos de cargas de trabalho com propagação de endpoint
Ao implantar uma carga de trabalho no cluster ou atualizar uma carga de trabalho atual, o balanceador de carga nativo de contêiner pode levar mais tempo para propagar novos endpoints do que leva para concluir o lançamento da carga de trabalho. A implantação de exemplo implantada neste guia usa dois campos para alinhar o lançamento com a propagação de endpoints: terminationGracePeriodSeconds
e minReadySeconds
.
terminationGracePeriodSeconds
(em inglês) permite que o pod encerre normalmente esperando que as conexões sejam encerradas após um pod ser programado para exclusão.
minReadySeconds
(em inglês) adiciona um período de latência depois que um pod é criado. Especifique um número mínimo de segundos para que um novo pod fique no status Ready
(em inglês), sem que nenhum contêiner apresente falhas, para que o pod seja considerado disponível.
Configure os valores minReadySeconds
e terminationGracePeriodSeconds
das cargas de trabalho como 60 segundos ou mais para garantir que o serviço não seja interrompido devido ao lançamento de cargas de trabalho.
terminationGracePeriodSeconds
está disponível em todas as especificações do pod e minReadySeconds
está disponível para implantações e DaemonSets.
Para saber mais sobre o ajuste fino de distribuições, consulte RollingUpdateStrategy.
initialDelaySeconds
no pod readinessProbe
não respeitados
A configuração initialDelaySeconds
no readinessProbe
do pod será respeitada
pelo balanceador de carga nativo do contêiner. No entanto, readinessProbe
é implementado pelo
kubelet, e a configuração initialDelaySeconds
controla a verificação de integridade
do kubelet, não o balanceador de carga nativo do contêiner. O balanceamento de carga
nativo de contêiner tem sua própria verificação de integridade de balanceamento de carga.