Como fazer tudo funcionar em conjunto: exemplo de cenário de solução de problemas


Entender as ferramentas individuais de solução de problemas do Google Kubernetes Engine (GKE) é útil, mas ver como elas são usadas juntas para resolver um problema real pode ajudar a consolidar seu conhecimento.

Siga um exemplo guiado que combina o uso do console Google Cloud , da ferramenta de linha de comando kubectl, do Cloud Logging e do Cloud Monitoring para identificar a causa raiz de um erro OutOfMemory (OOMKilled).

Este exemplo é útil para quem quer ver uma aplicação prática das técnicas de solução de problemas descritas nesta série, principalmente administradores e operadores de plataforma e desenvolvedores de aplicativos. Para mais informações sobre os papéis comuns e as tarefas de exemplo referenciados no conteúdo doGoogle Cloud , consulte Funções e tarefas de usuário comuns do GKE.

O cenário

Você é o engenheiro de plantão de um app da Web chamado product-catalog que é executado no GKE.

Sua investigação começa quando você recebe um alerta automático do Cloud Monitoring:

Alert: High memory utilization for container 'product-catalog' in 'prod' cluster.

Esse alerta informa que há um problema e indica que ele tem algo a ver com a carga de trabalho product-catalog.

Confirmar o problema no console do Google Cloud

Comece com uma visão geral das suas cargas de trabalho para confirmar o problema.

  1. No console Google Cloud , acesse a página Cargas de trabalho e filtre pela carga de trabalho product-catalog.
  2. Confira a coluna de status Pods. Em vez do 3/3 normal, você vê o valor mostrando um status não íntegro: 2/3. Esse valor informa que um dos pods do app não tem o status Ready.
  3. Para investigar mais a fundo, clique no nome da carga de trabalho product-catalog para acessar a página de detalhes.
  4. Na página de detalhes, confira a seção Pods gerenciados. Você identifica imediatamente um problema: a coluna Restarts do pod mostra 14, um número muito alto.

Esse alto número de reinicializações confirma que o problema está causando instabilidade no app e sugere que um contêiner está falhando nas verificações de integridade ou falhando.

Encontrar o motivo com comandos kubectl

Agora que você sabe que o app está reiniciando repetidamente, é preciso descobrir o motivo. O comando kubectl describe é uma boa ferramenta para isso.

  1. Você recebe o nome exato do pod instável:

    kubectl get pods -n prod
    

    A saída é esta:

    NAME                             READY  STATUS            RESTARTS  AGE
    product-catalog-d84857dcf-g7v2x  0/1    CrashLoopBackOff  14        25m
    product-catalog-d84857dcf-lq8m4  1/1    Running           0         2h30m
    product-catalog-d84857dcf-wz9p1  1/1    Running           0         2h30m
    
  2. Descreva o pod instável para conferir o histórico detalhado de eventos:

    kubectl describe pod product-catalog-d84857dcf-g7v2x -n prod
    
  3. Você analisa a saída e encontra pistas nas seções Last State e Events:

    Containers:
      product-catalog-api:
        ...
        State:          Waiting
          Reason:       CrashLoopBackOff
        Last State:     Terminated
          Reason:       OOMKilled
          Exit Code:    137
          Started:      Mon, 23 Jun 2025 10:50:15 -0700
          Finished:     Mon, 23 Jun 2025 10:54:58 -0700
        Ready:          False
        Restart Count:  14
    ...
    Events:
      Type     Reason     Age                           From                Message
      ----     ------     ----                          ----                -------
      Normal   Scheduled  25m                           default-scheduler   Successfully assigned prod/product-catalog-d84857dcf-g7v2x to gke-cs-cluster-default-pool-8b8a777f-224a
      Normal   Pulled     8m (x14 over 25m)             kubelet             Container image "us-central1-docker.pkg.dev/my-project/product-catalog/api:v1.2" already present on machine
      Normal   Created    8m (x14 over 25m)             kubelet             Created container product-catalog-api
      Normal   Started    8m (x14 over 25m)             kubelet             Started container product-catalog-api
      Warning  BackOff    3m (x68 over 22m)             kubelet             Back-off restarting failed container
    

    A saída fornece duas pistas importantes:

    • Primeiro, a seção Last State mostra que o contêiner foi encerrado com Reason: OOMKilled, o que indica que ele ficou sem memória. Esse motivo é confirmado pelo Exit Code: 137, que é o código de saída padrão do Linux para um processo que foi encerrado devido ao consumo excessivo de memória.
    • Em segundo lugar, a seção Events mostra um evento Warning: BackOff com a mensagem Back-off restarting failed container. Essa mensagem confirma que o contêiner está em um loop de falha, que é a causa direta do status CrashLoopBackOff que você viu antes.

Visualizar o comportamento com métricas

O comando kubectl describe informou o que aconteceu, mas o Cloud Monitoring pode mostrar o comportamento do seu ambiente ao longo do tempo.

  1. No console Google Cloud , acesse o Metrics Explorer.
  2. Você seleciona a métrica container/memory/used_bytes.
  3. Filtre a saída para seu cluster, namespace e nome de pod específicos.

O gráfico mostra um padrão distinto: o uso de memória aumenta constantemente e depois cai abruptamente para zero quando o contêiner é encerrado por falta de memória e reiniciado. Essa evidência visual confirma um vazamento de memória ou um limite de memória insuficiente.

Encontrar a causa raiz nos registros

Agora você sabe que o contêiner está ficando sem memória, mas ainda não sabe exatamente por quê. Para descobrir a causa raiz, use o Explorador de registros.

  1. No console do Google Cloud , acesse o Explorador de registros.
  2. Escreva uma consulta para filtrar os registros do contêiner específico de pouco antes do horário da última falha (que você viu na saída do comando kubectl describe):

    resource.type="k8s_container"
    resource.labels.cluster_name="example-cluster"
    resource.labels.namespace_name="prod"
    resource.labels.pod_name="product-catalog-d84857dcf-g7v2x"
    timestamp >= "2025-06-23T17:50:00Z"
    timestamp < "2025-06-23T17:55:00Z"
    
  3. Nos registros, você encontra um padrão repetido de mensagens logo antes de cada falha:

    {
      "message": "Processing large image file product-image-large.jpg",
      "severity": "INFO"
    },
    {
      "message": "WARN: Memory cache size now at 248MB, nearing limit.",
      "severity": "WARNING"
    }
    

Essas entradas de registro informam que o app está tentando processar arquivos de imagem grandes carregando-os totalmente na memória, o que acaba esgotando o limite de memória do contêiner.

As descobertas

Ao usar as ferramentas juntas, você tem uma visão completa do problema:

  • O alerta de monitoramento notificou você sobre um problema.
  • O console Google Cloud mostrou que o problema estava afetando usuários (reinicializações).
  • Os comandos kubectl apontaram o motivo exato das reinicializações (OOMKilled).
  • O Metrics Explorer visualizou o padrão de vazamento de memória ao longo do tempo.
  • O Explorador de registros revelou o comportamento específico que estava causando o problema de memória.

Agora você já pode implementar uma solução. Você pode otimizar o código do app para processar arquivos grandes de maneira mais eficiente ou, como uma correção de curto prazo, aumentar o limite de memória do contêiner (especificamente, o valor spec.containers.resources.limits.memory) no manifesto YAML da carga de trabalho.

A seguir