Engenharia

A importância dos metadados nas suas iniciativas de observabilidade do Kubernetes

Este post foi publicado originalmente no site tfir.io.

Kubernetes é um popular sistema de orquestração de container que é o elemento central dos projetos da Cloud Native Computing Foundation. Ele automatiza a implantação, o ciclo de vida e as operações de containers, aplicações em containers e “pods”, que são grupos de um ou mais containers. A própria plataforma, junto com cada uma dessas cargas de trabalho, pode gerar dados de eventos. Existem diferentes tipos de dados associados a esses processos. Os logs podem variar de simples mensagens de depuração do tipo “sim, cheguei aqui” a logs detalhados de acesso do servidor web que fornecem informações de transação. Métricas, ou dados de série temporal, são valores numéricos mensurados em um intervalo regular — por exemplo, o número de operações instantâneas por segundo, taxas de acerto de cache, contagem de clientes acessando o seu website ou coisas básicas, como quanto de CPU ou memória um container usou nos últimos cinco segundos.

A observabilidade pega esses logs e métricas e os torna buscáveis, geralmente em um armazenamento de dados correlacionado e geralmente sendo combinados com dados de trace da aplicação. Esses dados de trace, ou informações detalhadas de monitoramento de performance de aplicação (APM), capturam onde as aplicações ou os serviços estão gastando seu tempo, como e com o que estão interagindo, e quaisquer erros encontrados. Os logs e as métricas são uma espécie de caixa preta de uma aplicação, enquanto os dados de APM mostram o que está acontecendo dentro das aplicações.  

Combinados, logs, métricas e dados de trace da aplicação podem ajudar a reduzir o tempo médio de detecção e resolução ou os erros e incidentes, mas conforme os modelos de implantação das aplicações evoluem (assim como as implantações do Kubernetes), torna-se muito importante entender onde as coisas estão realmente acontecendo em um ambiente dinâmico. É aí que entram os metadados.

O que são os metadados exatamente?

Conforme a definição do Webster, metadados são “dados que fornecem informações sobre outros dados”. Parece muito simples, certo? Existem muitos lugares comuns onde você encontrará metadados — a página que hospeda este post do blog contém metadados. Ela contém tags de SEO, dicas para ajudar diferentes navegadores a formatar a página corretamente e palavras-chave para ajudar a descrever a página. Da mesma forma, uma imagem no seu dispositivo móvel tem muitos metadados — veja um snippet:

ExifTool Version Number         : 11.11 
File Name                       : 60398459048__A20828DD-FAA4-4133-BA1F-059DEC9E7332.jpeg 
Directory                       : . 
File Size                       : 2.8 MB 
File Modification Date/Time     : 2020:02:21 08:30:01-05:00 
File Access Date/Time           : 2020:02:21 08:30:23-05:00 
File Inode Change Date/Time     : 2020:02:21 08:30:22-05:00 
MIME Type                       : image/jpeg 
JFIF Version                    : 1.01 
Acceleration Vector             : -0.03239090369 -0.9104139204 -0.3862404525 
Exif Byte Order                 : Big-endian (Motorola, MM) 
Make                            : Apple 
Camera Model Name               : iPhone XS 
Orientation                     : Rotate 90 CW 
X Resolution                    : 72 
Y Resolution                    : 72 
Exif Image Width                : 4032 
Exif Image Height               : 3024

“Como saber o tipo MIME de uma imagem do iPhone me ajuda nas minhas iniciativas de observabilidade?”, talvez você esteja se perguntando. Não ajuda, porque não é para isso que servem os metadados da imagem, mas o exemplo deve dar uma ideia do que os metadados oferecem. Os metadados do iPhone permitem que você filtre por tamanho, orientação ou o quanto você tremeu quando tirou a foto (aparentemente, tenho de melhorar nisso). Vamos examinar algumas coisas que vão ajudar você a navegar nos seus dados de observabilidade, ou seja, os logs, métricas e dados de trace da aplicação do seu ambiente, e correlacioná-los.  

Tendências de implantação de software e hardware

Os dias de glória das aplicações monolíticas em servidores bare-metal de finalidade única em um único datacenter já fazem parte do passado. Claro, ainda é comum vê-los executando cargas de trabalho dedicadas e não há nada de errado nisso; muitos produtos e aplicações de larga escala exigem o máximo de computação possível. Entretanto, no geral, as tendências do setor quanto aos modelos de implantação de software e hardware estão se movendo em direção aos microsserviços e containers.

trends-increasingly-complex-systems.png

Essa tendência não é um big bang — muitas lojas terão vários modelos de implantação de software trabalhando em paralelo, junto com vários padrões de hardware. Máquinas virtuais ou instâncias de nuvem executam aplicações cliente/servidor ou SOA, enquanto os containers executam imagens para seus microsserviços, orquestrados pelo Kubernetes ou Docker. Em muitos casos, as aplicações e serviços de um modelo de implantação estão aproveitando os serviços de outro — aquele novo microsserviço sofisticado ainda pode estar usando um banco de dados hospedado em bare metal.

A natureza desses sistemas heterogêneos torna os metadados ainda mais importantes. Conforme mudamos para containers, pods e microsserviços programados dinamicamente, fica ainda mais difícil entrar no datacenter, apontar para uma máquina e dizer “minha aplicação está ali”. Talvez até esteja, mas pode também estar nos outros quatro servidores atrás de você. 

É aí que entram os metadados de localização. Não estou falando sobre latitude e longitude (embora isso possa ser útil), mas sim um esquema de endereço, algo que lhe permitiria pelo menos ver logicamente de onde um dado (seja um log, métrica ou dados de trace da aplicação) vem.  

Características da infraestrutura

Localização, localização, localização

Suas necessidades vão variar de acordo com a sua configuração, mas você deve planejar o futuro. O quanto você pode capturar depende do que um determinado trabalho está executando — se for uma aplicação monolítica em bare metal, você não vai capturar detalhes do pod do Kubernetes, o que é normal. Basicamente, queremos fornecer uma trilha para que possamos ver onde as coisas estão sendo executadas. Veremos por que daqui a pouco.

Com a localização, estamos buscando uma hierarquia de metadados, até o nível da aplicação, onde o trabalho está sendo executado fisicamente.  

Datacenter

Os metadados do datacenter devem incluir um identificador exclusivo para cada datacenter — o nome da cidade, por exemplo. Essas informações podem ficar um pouco confusas quando falamos sobre provedores de serviços em nuvem, mas existem algumas analogias paralelas. Nesse cenário, podemos utilizar o provedor de serviços em nuvem e a região na qual estamos executando, por exemplo, GCP, europe-west1 e zona de disponibilidade b.

Se você tem níveis dedicados em seus datacenters (como hosts específicos reservados para produção ou teste, ou divididos entre projetos), adicione isso aos seus metadados também.  É como se fosse uma parte isolada do seu datacenter ou um datacenter dentro de um datacenter.

Informações do host

Independentemente de estarmos executando em bare metal, ambiente virtualizado ou em uma instância de nuvem, temos algumas informações do host regularmente disponíveis. Cada host terá atributos para nome de host, endereço(s) IP, modelo de hardware ou tipo de instância, RAM e armazenamento configurados, e até mesmo informações do sistema operacional. Você pode ir mais longe e incluir informações ainda mais detalhadas, como onde o host está instalado — o andar no datacenter, em qual rack, qual fileira, até em qual prateleira. Não seria a primeira vez que um rack inteiro seria afetado por uma infraestrutura de energia ou fiação mal feita!

Detalhes da aplicação

Neste ponto, temos informações suficientes para identificar onde cada coisa está sendo executada — mas apenas até o nível do host, e cada host pode estar executando muitos serviços ou aplicações diferentes. Quando começamos a falar sobre as aplicações e serviços, precisamos adicionar o nível correspondente de metadados. É aqui que as coisas podem ficar um pouco correlacionadas, por isso, vamos manter tudo em um nível geral e trabalhar no cenário mais complexo, com microsserviços orquestrados pelo Kubernetes. Aplicar isso a aplicações bare-metal e ambientes virtualizados deve ser bastante simples.

Os containers no Kubernetes e no Docker têm automaticamente algum nível de metadados disponível, que deve ser incluído. No mínimo, precisamos incluir o nome do container e/ou do pod, a imagem e a versão usadas como base do container e o horário de início. Idealmente, também incluiremos o nome da rede e as informações de IP, junto com a rede, memória ou cotas de armazenamento. Consegue traçar um paralelo com as informações do host? Containers e máquinas virtuais são basicamente hosts executados em outro host, portanto, faz sentido que queiramos extrair as mesmas informações.

Dito isso, ao trabalhar com um ambiente virtualizado, podemos fazer as mesmas analogias. Um host virtual terá os mesmos detalhes gerais que os hosts: um nome, endereço IP e limites de memória e armazenamento.

Temos um pequeno dilema neste ponto: temos alguns nomes de campo duplicados. É importante lembrar que queremos manter uma hierarquia. Os metadados do host se posicionam mais alto nessa hierarquia do que um container ou uma máquina virtual:

├── NYC DC 1 
│   ├── Host 1 
│   │   ├── vm 1 
│   │   ├── vm 2 
│   │   └── vm 3 
│   └── Host 2 
│       ├── vm 1 
│       └── vm 2 
└── NYC DC 2 
    └── Host 1 
        ├── vm 1 
        ├── vm 2 
        ├── vm 3 
        └── vm 4

Com isso, é bastante óbvio que precisamos colocar valores em espaços de nome diferentes e previsíveis para garantir que esses nomes não entrem em conflito. Uma ótima maneira de fazer isso é transmiti-los como pares de chave/valor; por exemplo, os metadados de vm 2 no Host 1 no nosso NYC DC 1 podem incluir:

dc.name: "NYC DC 1" 
dc.floor: 2 
 
host.name:  "Host 1" 
host.IP: … 
host.available_memory_mb: 16384 
vm.name: "vm 1" 
vm.IP: …

Os containers são um pouco diferentes quanto à hierarquia, já que um único cluster do Kubernetes pode abranger vários hosts. Nesse caso, é importante obter não só as informações de localização de um determinado pod ou container, mas também os metadados de orquestração correspondentes, conforme mencionado acima. A seguir, veremos como os metadados nos ajudam a obter uma melhor observabilidade para as nossas aplicações.

Observabilidade da aplicação

Agora que sabemos como lidar plenamente com as coisas em execução em nossos sistemas, podemos começar a conversar sobre a coleta de dados reais (lembre-se de que os metadados descrevem outros dados). Os “três pilares da observabilidade” são os logs, as métricas e os dados de trace da aplicação (também conhecidos como dados de APM), ocasionalmente com dados de tempo de funcionamento mostrados como um quarto “pilar”. Queremos coletar logs e métricas em cada camada do nosso ecossistema, conforme indicado no diagrama abaixo, que inclui informações sobre quais tipos de dados de observabilidade devem ser coletados para cada abstração:

what-to-monitor.png

Por exemplo, queremos coletar dados de logs, métricas e disponibilidade de cada host ou elemento de rede em nossos datacenters, mas adicionar APM para aplicações e serviços.

Enriquecemos todos os itens acima com os metadados correspondentes para cada nível a fim de aumentar a visibilidade das nossas aplicações, da infraestrutura e de todo o ecossistema. Há muitas maneiras de fazer isso: podemos enviá-los com cada evento ou trace, o que agiliza a busca e a filtragem, ou armazenar os metadados das porções estáticas do nosso ecossistema e fazer a referência cruzada. Embora o último método economize um pouco de espaço, ele corre o risco de ficar obsoleto ou desatualizado, especialmente em ecossistemas dinâmicos.

Juntando as peças

Com nossos dados de observabilidade enriquecidos com metadados, poderemos dividi-los com base nas facetas que escolhermos, sem nos limitarmos a olhar para dados ou logs de APM específicos. Por exemplo, podemos dividir a utilização atual da CPU por host ou por serviço:

infra-viewer.png

Ou observar o mesmo parâmetro ao longo do tempo:

metrics-explorer.png

Isso nos permite escolher os detalhes que desejamos analisar, respondendo a perguntas que não seria possível responder de outra forma, como:

  • Meu datacenter nos EUA está superutilizado em comparação com meu datacenter na região EMEA?
  • Estão ocorrendo mais erros em algum rack no meu ecossistema do que em outros?
  • Posso reutilizar alguma infraestrutura de desenvolvimento para produção?
  • Os containers e pods do meu app de comércio eletrônico estão sendo executados em quais hosts físicos?
  • E, finalmente, por que minhas fotos do iPhone saem sempre tremidas?

Resumo

Os metadados adicionam novas dimensões à sua análise, fornecendo novas maneiras de agregar e dividir seus dados para ajudar a responder a perguntas nos seus negócios e operações. Certifique-se de que a solução que você usa para suas iniciativas de observabilidade esteja preparada para crescer com você e leve em consideração metadados buscáveis e navegáveis, como o Elastic Common Schema, para que você possa garantir que seus metadados estejam onde você espera.