Host e containers: recursos não contam toda a história

Parte 4 de 8 — série Observabilidade na prática.

A API de catálogo demora a responder e seu container continua em execução. Nesse cenário hipotético, seria tentador procurar imediatamente CPU ou memória no limite. Mas a requisição também poderia estar esperando um lock, uma conexão do pool ou uma resposta externa. Os recursos ajudam a avaliar essas hipóteses; não escolhem a causa por nós.

A investigação precisa combinar recursos do host, limites do container e comportamento da aplicação. Um processo ativo descreve seu ciclo de vida. A entrega da função esperada exige outros sinais.

CPU e memória pedem contexto

Uma série de CPU pode representar tempo usado, capacidade ocupada ou espera por I/O, dependendo do exporter e da consulta. Os nomes e a semântica variam; confirme como cada métrica é definida. Uma CPU aparentemente ociosa pode coexistir com requisições lentas se o serviço estiver esperando rede, disco ou conexões. No Linux, iowait descreve uma condição de contabilização do tempo de CPU; sozinho, não mede a latência de uma consulta nem a saturação de um disco.

Memória merece interpretação semelhante. Sistemas operacionais e cgroups contabilizam memória de maneiras diferentes, e cache pode ser recuperável. Uma linha que cresce nem sempre representa vazamento. Compare o valor com o limite relevante, acompanhe pressão e tendência e entenda o indicador antes de definir um alerta.

O gráfico deve mostrar o denominador da comparação quando isso for necessário. Um host com mais CPUs pode usar mais tempo absoluto e ainda ter baixa ocupação relativa. Um container pode parecer pequeno até que seu limite de memória esteja próximo.

Discos e filesystems

Espaço livre, inodes e atividade de I/O respondem perguntas distintas. Um volume pode ter blocos livres e não ter inodes disponíveis para novos arquivos. Uma taxa alta de I/O pode ser normal durante uma compactação. Espaço ocupado descreve capacidade; duração e fila de operações ajudam a investigar desempenho. São perguntas diferentes. Latência média pode esconder uma fila longa ou uma cauda de operações demoradas.

Camadas de bloco também podem representar o mesmo trabalho mais de uma vez: dispositivo físico, partição, volume lógico e filesystem. Somar todas as camadas sem conhecer a topologia duplica atividade. Relacione cada medida ao dispositivo ou ponto de montagem que importa e registre como o exporter define bytes, operações, tempo e fila.

Em máquinas com discos de velocidades diferentes, armazenamento não é intercambiável. Mover uma base de métricas, logs ou traces para um disco maior pode alterar significativamente as buscas. Meça leituras representativas e observe a carga antes de decidir onde manter cada tipo de dado.

Container ativo, serviço saudável?

O runtime sabe se um processo está executando. Alguns containers também definem um healthcheck, mas outros não. Portanto, “sem healthcheck” deve ser diferente de “healthcheck falhou”. Reinícios, estado e uso de recursos ajudam a reconhecer sintomas, mas a aplicação pode ainda responder com erro ou demorar excessivamente.

Combine sinais conforme o objetivo:

  • O runtime informa ciclo de vida e recursos do container.
  • O processo ou exporter informa métricas internas específicas.
  • Uma sondagem da aplicação verifica uma resposta externa definida.
  • Um trace instrumentado detalha o caminho de uma operação.

Esses sinais se complementam; nenhum substitui todos os outros.

O acesso ao exporter também tem alcance

Alguns exporters de containers consultam a API do runtime para obter metadados e estatísticas; outros coletam informações diretamente do sistema, como dados de cgroups. Quando a coleta usa a API, ela pode envolver um socket local com capacidades administrativas dentro do escopo daquele usuário. Dar acesso ao socket a um exporter amplia o impacto potencial de uma falha ou comprometimento. Trate esse acesso como uma fronteira de segurança e mantenha o endpoint de métricas acessível apenas ao coletor autorizado.

Execute o exporter com o menor privilégio compatível, leia os requisitos de acesso do projeto e limite o que ele pode alcançar. Montar o socket do runtime como somente leitura não torna sua API uma API de leitura: a capacidade de emitir comandos depende do serviço do outro lado do socket. Um endpoint de métricas não deveria ficar aberto para a rede inteira só porque o coletor precisa consultá-lo. No modelo de scrape, o Prometheus inicia a conexão; restrinja o acesso por controles de rede e autenticação, conforme o suporte do exporter, e configure em qual endereço ele escuta.

Confirme a topologia real de rede. Container, socket Unix, bind local e porta publicada no host são caminhos diferentes. Uma configuração de exemplo pode ser segura num namespace isolado e exposta em outro ambiente.

Painéis para perguntas de operação

Um dashboard de host pode reunir CPU, memória, rede e armazenamento, destacando pressão ao longo do tempo. Um dashboard de containers pode mostrar identidade estável, ciclo de vida, reinícios, health quando disponível e uso relativo aos limites.

Evite preencher a tela com toda métrica exportada. Um indicador deve existir porque sua mudança pede investigação ou ação. Anote o significado de “unknown”, ausência e zero; as pessoas precisam saber o que uma linha vazia comunica. Configure alertas sobre sintomas que importam, depois de observar a variação normal do ambiente.

Antes de adotar uma regra, acompanhe-a durante condições usuais, manutenção e reinícios. Alertar em todo pico gera cansaço e reduz a confiança nos sinais. Deixe claro se a regra detecta falta de coleta, pressão de recurso ou indisponibilidade de uma função. Para o catálogo, encontrar CPU baixa deve manter abertas as hipóteses de espera. O próximo sinal precisa mostrar onde o trabalho parou, em vez de apenas aumentar a lista de recursos monitorados.

Na série: anterior — OpenTelemetry Collector: organizando o fluxo da telemetria; próxima — PostgreSQL: observar além das conexões.

Referências

← Voltar para todos os posts