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 vê-las sendo usadas juntas para resolver um problema real pode ajudar a consolidar seu conhecimento.

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

Este exemplo é útil para quem quiser conferir 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 as funções comuns e exemplos de tarefas que referenciamos no Google Cloud conteúdo, consulte Funções e tarefas comuns do usuário 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 automatizado 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 Google Cloud console

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

  1. No Google Cloud console do, acesse a página Cargas de trabalho e filtre pela sua carga de trabalho product-catalog.
  2. Observe a coluna de status Pods. Em vez do 3/3 íntegro, 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 incomumente alto.

Essa alta contagem 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á sendo reiniciado repetidamente, é necessário 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. Você descreve o pod instável para receber o histórico de eventos detalhado:

    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 oferece 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 anteriormente.

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 Google Cloud console do, acesse o Metrics Explorer.
  2. Selecione a métrica container/memory/used_bytes.
  3. Filtre a saída para o cluster, namespace e nome do pod específicos.

O gráfico mostra um padrão distinto: o uso da memória aumenta de forma constante e, em seguida, cai abruptamente para zero quando o contêiner é encerrado 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 o motivo. Para descobrir a causa raiz, use a Análise de registros.

  1. No Google Cloud console, acesse a Análise de registros.
  2. Escreva uma consulta para filtrar os registros do contêiner específico de pouco antes do último 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 pouco 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.

Os achados

Ao usar as ferramentas juntas, você tem uma imagem completa do problema:

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

Agora você está pronto para implementar uma solução. É possível otimizar o código do app para processar arquivos grandes com mais eficiência 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