Observabilidade do Elasticsearch: adoção dos padrões do Prometheus e do OpenMetrics para métricas

Neste blog, trataremos destes assuntos:

  • Por que os padrões abertos são importantes
  • O formato de exposição do Prometheus
  • Como a Elastic enxerga a observabilidade
  • Três maneiras pelas quais o Elasticsearch pode consumir as métricas do Prometheus
  • Exemplo de como coletar e visualizar as métricas expostas pelo exportador Prometheus Redis

Padrões abertos

Em opensource.com, há um recurso informativo com o título: "What are Open Standards?" (O que são os padrões abertos?). Há muitos assuntos excelentes nesse documento, mas na minha opinião pessoal de quem atua há muitos anos nas operações, estes são os mais importantes:

  1. Disponibilidade: Os padrões abertos ficam disponíveis para que todos leiam e implementem.
  2. Maximizam a escolha do usuário final
  3. Não há discriminação (neutralidade de fornecedor): Os padrões abertos e as organizações que os administram não favorecem um implementador em detrimento de outro.
  4. Não há segredos intencionais: o padrão não deve reter nenhum detalhe necessário para implementação interoperável.

Esses são os motivos atraentes pelos quais os padrões abertos são interessantes; agora vamos falar sobre por que o formato de exposição do Prometheus é a base para o OpenMetrics. Em suas palestras nos eventos PromCon 2018 e KubeCon + CloudNativeCon North America 2018, Richard Hartmann resumiu os motivos para criar um padrão aberto influenciado pelo formato de exposição do Prometheus:

  • A maioria dos formatos de dados é proprietária, difícil de implementar ou as duas coisas
  • O Prometheus se tornou o verdadeiro padrão no monitoramento de métricas nativo na nuvem
  • A facilidade dos dados de exposição resultou em uma explosão nos endpoints de métricas compatíveis
  • O formato de exposição do Prometheus se baseia em muita experiência operacional, mas foi projetado entre poucas pessoas
  • Alguns outros projetos e fornecedores ficam receosos em termos de adotar uma tecnologia de um produto "concorrente"

Formato de exposição do Prometheus

Você pode ler sobre o formato de exposição no repositório do Prometheus Github. Por enquanto, vamos apenas analisar um exemplo. Eu tenho um exportador, o exportador Redis da Oliver006, publicando métricas na porta 9121 no endpoint /metrics. Estou mostrando somente informações sobre a métrica "operações instantâneas por segundo" do Redis aqui. Há três linhas para a leitura:

  1. Texto de Ajuda
  2. Tipo de métrica (gauge neste caso)
  3. O servidor Redis sendo mensurado (porta host local 6379) e sua leitura atual (9 operações por segundo)

roscigno-prometheus-exposition-format.png

Observabilidade na Elastic

Eu incentivo você a ler sobre como a Elastic enxerga a observabilidade, mas esta é minha linha favorita da postagem:

O objetivo de projetar e desenvolver um sistema 'observável' é garantir que, quando ele for executado em produção, os operadores responsáveis por ele possam detectar comportamentos indesejáveis (p. ex.: inatividade de serviço, erros, respostas lentas) e ter informações práticas para identificar a causa principal de maneira eficaz (p. ex.: logs de evento detalhados, informações de utilização de recursos granulares e rastreamentos de aplicativos).

Essa instrução, que eu apoio incondicionalmente, informa que precisamos de todos os logs, métricas e informações de rastreamento para executar, reparar e gerenciar os serviços que fornecemos. O Prometheus é uma parte importante da observabilidade devido à sua adoção disseminada e comunidade ativa. O padrão OpenMetrics só aumentará o valor removendo barreiras, sejam elas reais ou percebidas, à adoção de um formato de métricas surgido nas operações e de bom senso.

A maioria das pessoas com quem converso é bastante familiarizada com o Elastic Stack, ou ELK, para logs. Se você não sabia que o Elastic Stack também é ótimo para métricas e APM, veja nossas métricas e APM/rastreamento distribuído.

Os principais motivos para os quais vemos interesse na profunda integração entre os métodos do Elastic Stack e do Prometheus de exportar métricas são:

  • Combinar métricas com logs e APM no Elasticsearch e correlacioná-los no Kibana. Confira uma história de usuário da NS1 sobre combinação de logs e métricas no Elastic Stack.
  • Usar o Elasticsearch como armazenamento de longo prazo para métricas coletadas pelo Prometheus Server, que no momento não oferece suporte a cluster nativamente.
  • Atingir uma visão global das métricas entre instâncias do Prometheus geograficamente dispersas.

O restante do blog descreve em detalhes como abordamos essas integrações.

Um exportador de amostra

Meu ambiente de demonstração está em execução no Google Kubernetes Engine (GKE), por isso estou executando meu aplicativo, o Metricbeat, e o exportador do Prometheus, tudo no Kubernetes. Este é um trecho do manifesto do Oliver006 para implantar um exportador do Redis como um sidecar ao longo da imagem do Redis. Como você pode ver, o exportador está publicando na porta 9121, que é o número de porta atribuído padrão para o exportador do Prometheus Redis.

...
  - name: redis-exporter
    image: oliver006/redis_exporter:latest
    resources:
      requests:
        cpu: 100m
        memory: 100Mi
    ports:
    - containerPort: 9121
...

Fonte completa em GitHub

Uso de scraping nas métricas com o módulo Metricbeat Prometheus

O Metricbeat é o shipper leve da Elastic para métricas. O módulo Prometheus que é fornecido com o Metricbeat pode reunir métricas de três maneiras:

  1. Conectar-se ao servidor do Prometheus na porta 9090 e obter métricas já coletadas usando a API de federação do Prometheus (para obter as métricas que o Prometheus está coletando)
  2. Conectar-se ao servidor do Prometheus na porta 9090 usando o endpoint /metrics (automonitoramento do Prometheus)
  3. Conectar-se aos exportadores do Prometheus individualmente e analisar o formato de exposição

Por que você escolheria uma abordagem em detrimento da outra? Isso depende do seu nível de conforto com o servidor do Prometheus.

  • Se você já tem o servidor do Prometheus configurado para fazer scraping de métricas e quiser consultar diretamente essas métricas para fins de integração, você poderá começar com as opções (1) e (2).
  • Se, por outro lado, você ainda não tiver o servidor do Prometheus ou não se importar em fazer scraping dos exportadores em paralelo por várias ferramentas, você poderá escolher a opção (3).

Nota: Parte da funcionalidade do Metricbeat acima é beta no Metricbeat versão 7.0. Nós incentivaríamos você a fazer download da versão 7.0 beta ou copiar os links de container de https://www.docker.elastic.co/ e executar a versão beta em um ambiente de não produção.

API de federação do Prometheus

Em geral, a federação é usada para habilitar o escalonamento, reunir os conjuntos de dados ou fazer uma cópia dos dados disponíveis em um local diferente (para recuperação de desastres). O servidor do Prometheus fornece um endpoint /federation, e a Elastic se conecta a esse endpoint para copiar as métricas coletadas pelo Prometheus para todos os motivos anteriores.

...
  - module: prometheus
    period: 10s
    hosts: ["prometheus-service.monitoring.svc.cluster.local:9090"]
    metrics_path: '/federate'
    query:
      'match[]': '{__name__!=""}'
...

Fonte completa em GitHub

No exemplo anterior, a consulta é definida como "qualquer coisa que tenha um nome que não seja em branco". Talvez você não queira obter tudo, e os documentos do Prometheus têm informações sobre como gravar uma condição de correspondência mais restritiva. O exemplo também está se conectando ao servidor do Prometheus a cada dez segundos, meu servidor de demonstração só está coletando a partir de alguns pods e métricas com estado de kube, mas talvez você queira alterar o intervalo.

Automonitoramento do Prometheus

O Prometheus fornece um endpoint /metrics, assim como os exportadores. Tanto é assim que você pode coletar as métricas sobre o servidor do Prometheus. Isso é configurado desta maneira:

...
  - module: prometheus
    period: 10s
    hosts: ["prometheus-service.monitoring.svc.cluster.local:9090"]
    metrics_path: /metrics
...

Fonte completa em GitHub

Scraping do exportador do Prometheus

Esse trecho do YAML proveniente de um manifesto para implantar um Metricbeat DaemonSet informa que o Metricbeat faça uma autodescoberta das tarefas com kubernetes.labels.app == redis e leia as métricas recebidas na porta 9121 desse pod. Lembre-se de que o conjunto de containerPort para o container do exportador do Redis é 9121.

...
- condition.equals:
    kubernetes.annotations.prometheus.io/scrape: "true"
  config:
    - module: prometheus
      period: 10s
      # Redis pods
      hosts: ["${data.host}:9121"]
      metrics_path: /metrics
...

Depois que o Metricbeat for implantado, quaisquer pods que satisfaçam a condição kubernetes.labels.app == redis terão o módulo Prometheus aplicado a eles, e as métricas serão coletadas a partir do sidecar do exportador na porta 9121.

Mas, os metadados fazem o mundo dos k8s avançar, não é? Vamos fazer mais com metadados e o recurso de autodescoberta do Beats. Analise este substituto para o trecho anterior do YAML:

...
- condition.equals:
    kubernetes.annotations.prometheus.io/scrape: "true"
  config:
    - module: prometheus
      period: 10s
      hosts: ["${data.host}:${data.kubernetes.annotations.prometheus.io/port}"]
      metrics_path: /metrics
...

Fonte completa em GitHub

Agora, em vez de procurar por exportadores para pods do Redis, estamos procurando por exportadores para qualquer pod com uma anotação de kubernetes.annotations.prometheus.io/scrape definida como verdadeira. Isso é também como a autodescoberta do Prometheus é configurada. Geralmente, a autodescoberta do Metricbeat é orientada por uma anotação no namespace elastic.co, mas como estamos falando sobre a leitura dos exportadores do Prometheus, deveríamos honrar as anotações de k8s padrão associadas ao Prometheus. Se você analisar a lista de hosts anterior:

hosts: ["${data.host}:${data.kubernetes.annotations.prometheus.io/port}"]

Você poderá ver que não estamos mais fazendo hard coding da porta 9121, porque essa é a porta para o exportador do Redis. A anotação prometheus.io/port é configurada com o número de porta para o exportador. Para ser completo, aqui está um trecho do guestbook.yaml em que essas anotações foram configuradas:

...
kind: Deployment
metadata:
  name: redis-master
spec:
  replicas: 1
  template:
    metadata:
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "9121"
      labels:
        app: redis
...

Fonte completa em GitHub

Eu não mencionei que os metadados fazem o mundo dos k8s avançar? Vamos para o próximo tópico.

Visualização melhorada

Importar os dados para o Elastic Stack é excelente, mas é necessário poder interagir com os dados. No vídeo a seguir, veremos como abordar a criação de uma visualização útil usando métricas do Redis que passaram por scraping feito pelo Prometheus (e que foram importadas para o Elastic Stack) e os eventos do Kubernetes coletados das métricas com estado de kube com o Metricbeat diretamente.

Se quiser prosseguir com o vídeo e obter instruções detalhadas, veja o repositório de exemplo.

De volta à observabilidade

Na última seção, criamos uma visualização do Kibana para uma métrica do Redis crucial (operações instantâneas por segundo) exposta pelo exportador Redis do Oliver006. Nossa próxima etapa seria coletar logs e criar um painel e combinar logs e métricas entre nossos aplicativos.

Para saber como coletar logs em um ambiente do Kubernetes, minha sugestão seria seguir as instruções no repositório do GitHub elastic/examples. Em apenas alguns minutos, você pode ter o Filebeat, o Metricbeat e o Packetbeat coletando dados e publicando no Elasticsearch. Há painéis de amostra que são fornecidos com os Beats diferentes, e você ficar à vontade de criar suas próprias visualizações para os dados do Prometheus e misturar as visualizações para criar seus próprios painéis para a maneira que você trabalha. E se você tiver quaisquer problemas ou quiser falar sobre observabilidade, acesse os fóruns de discussão.