Monitorando seus servidores com Grafana e Prometheus

Aristides Neto • 05 October, 2022

devops grafana prometheus

Fala pessoal tudo beleza?

Neste artigo irei mostrar como subir uma stack de monitoramento usando o Grafana e Prometheus. Irei usar o docker para subir os containers com as imagens e o docker-compose para declarar os requisitos dos containers.

Esse artigo será dividido em algumas partes, mas os assuntos que irei abordar serão os seguintes:

  1. Configuração do Grafana e Prometheus
  2. Instalação e configuração dos exporters do Prometheus
  3. Criação de alertas no Prometheus
  4. Criação de alertas no Grafana
  5. Importar dashboards para o Grafana
  6. Configurar Grafana para enviar e-mail de alertas
  7. Instalação e configuração do Alert Manager para envio dos alertas por e-mail
  8. Instalação do Traefik como proxy reverso para toda a stack de monitoramento

Durante o percurso posso adicionar algum outro tema que seja importante para essa série.

Artigos da série

  1. Monitorando seus servidores com Grafana e Prometheus (Você está aqui!)
  2. Instalação e configuração do Node Exporter em servidores Linux
  3. Criando alertas com Prometheus e Alertmanager

Pré requisitos

Configurando o Grafana

O Grafana é um projeto Open Source que centraliza a análise e a visualização das métricas através de gráficos de aplicações, de serviços de nuvens, de serviços como o kubernetes entre outros.

Para saber mais acesse a documentação oficial.

Para iniciar, crie uma rede no docker para podermos usar em nossa stack de monitoramento:

docker network create monitoring

Crie o diretório grafana-prometheus e em seguida crie o arquivo docker-compose.yaml. De início esse arquivo terá o conteúdo abaixo:

# Arquivo: docker-compose.yaml
version: "3.8"

volumes:
  grafana_data:

networks:
  monitoring:
    external: true

services:

  grafana:
    image: grafana/grafana:9.1.6
    container_name: grafana
    restart: always
    volumes:
      - grafana_data:/var/lib/grafana
      - ./grafana/provisioning:/etc/grafana/provisioning/datasources
    environment:
      - GF_SECURITY_ADMIN_USER=${GF_SECURITY_ADMIN_USER}
      - GF_SECURITY_ADMIN_PASSWORD=${GF_SECURITY_ADMIN_PASSWORD}
      - GF_INSTALL_PLUGINS=${GF_INSTALL_PLUGINS}
    ports:
      - 3000:3000
    networks:
      - monitoring

Explicando algumas linhas importantes do arquivo docker-compose.yaml:

  1. networks: Nessa linha informamos ao docker-compose que iremos utilizar uma rede já criada por nós (external: true), que no caso é a rede monitoring.
  2. No serviço grafana, informamos a versão do Grafana que será utilizada que é a 9.1.6 (a mais recente na data desse artigo).
  3. Criamos dois volumes, o primeiro para armazenar o banco de dados do Grafana, com as informações de usuários, configurações, dashboards, etc. O segundo volume é o mapeamento da pasta de provisionamento onde definimos o datasource padrão que será usado pelo Grafana assim que ele iniciar.
  4. Nas variáveis de ambiente passamos alguns parâmetros do Grafana, esses valores estão sendo obtidos através de um arquivo .env na raiz do projeto.
  5. Em ports estamos expondo a porta 3000 do host para a porta 3000 do container.

Para saber mais sobre todas as possíveis configurações do Grafana, acesse a sessão de Configuração da documentação.

Provisionando datasource

Como visto no serviço do Grafana, foi criado um volume que podemos adicionar um datasource de forma automatizada assim que o serviço do Grafana subir. Para isso, crie um arquivo chamado ds-prometheus.yaml dentro do diretório grafana/provisioning/, e cole o conteúdo abaixo:

# Arquivo: grafana/provisioning/ds-prometheus.yaml
datasources:
- name: Prometheus
  access: proxy
  type: prometheus
  url: http://prometheus:9090

Nesse arquivo informamos ao Grafana que ele irá cadastrar um datasource com o nome de Prometheus, também é informamdo outras configurações, como a url da instância do Prometheus e o modo de acesso.

Esse mesmo passo pode ser feito manualmente na interface do Grafana, acessando o menu Configuração e Datasources.

Arquivo de variáveis

Como visto acima, o Grafana recebe algumas variáveis que estão vindo do arquivo .env. Esse arquivo será responsável em armazenar todas as informações de senhas e algumas outras.

O uso desse arquivo torna o processo mais simples para manutenção, podendo reaproveitar variáveis quando necessário.

Crie o arquivo .env na raiz do diretório grafana-prometheus e cole o conteúdo abaixo:

# Arquivo: .env
GF_SECURITY_ADMIN_USER=admin
GF_SECURITY_ADMIN_PASSWORD=password
GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource,grafana-worldmap-panel,percona-percona-app

Configurando o Prometheus

O Prometheus é um projeto Open Source usado para monitoramento e alertas. O Prometheus busca as métricas nos targets e grava em um banco de séries temporais, podendo visualizar essas métricas em tempo real.

Para saber mais acesse a documentação oficial.

Vamos agora adicionar ao arquivo docker-compose.yaml criado, o serviço do Prometheus. Adicione após o serviço do Grafana as seguintes linhas:

# Arquivo: docker-compose.yaml
...
volumes:
  grafana_data:
  prometheus_data: <-- volume adicionado

services:

  # Serviço do Prometheus adicionado
  prometheus:
    image: prom/prometheus:v2.37.1
    container_name: prometheus
    restart: always
    volumes:
      - ./prometheus/:/etc/prometheus/
      - prometheus_data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yaml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.console.libraries=/etc/prometheus/console_libraries'
      - '--web.console.templates=/etc/prometheus/consoles'
      - '--storage.tsdb.retention.time=360h'
      - '--web.enable-lifecycle'
    ports:
      - 9090:9090
    networks:
      - monitoring

Além do serviço do Prometheus, foi adicionado um volume para que o Prometheus possa salvar os dados dos seus alvos.

Explicando algumas linhas importantes do serviço do Prometheus:

  1. No serviço prometheus informamos a versão do Prometheus que será usada, que no caso é a v2.37.1 (a mais recente no momento).
  2. Criamos dois volumes, o primeiro é o diretório que contém o arquivo de configuração do Prometheus, o segundo volume é referente ao volume criado para salvar todas as métricas obtidas dos seus alvos.
  3. Em command são passados alguns parâmetros de configuração para o Prometheus.
  4. Em ports estamos expondo a porta 9000 do host para a porta 9000 do container.

Arquivo de configuração do Prometheus

O Prometheus precisa de um aquivo que irá determinar quais são os alvos que ele terá que raspar para obter as métricas.

Esses alvos podem ser uma aplicação web, um servidor linux, um banco de dados, um serviço na nuvem e todos eles devem exportar essas métricas em algum endpoint HTTP para que o Prometheus possa raspar e gravar esses valores em seu banco.

Crie um arquivo chamado prometheus.yaml dentro do diretório prometheus. Esse arquivo terá o seguinte conteúdo:

# Arquivo: prometheus/prometheus.yaml
global:
  scrape_interval: 15s  # Por padrão, o alvo será 'raspado' a cada 15 segundos

scrape_configs:

  - job_name: 'prometheus'

    # Esse valor irá sobreescrever o valor padrão global para esse alvo
    scrape_interval: 5s

    metrics_path: /metrics # Endpoint padrão para a raspagem das métricas
    static_configs:
      - targets: ['localhost:9090']

Nesse exemplo simples, o Prometheus irá se auto monitorar através de um endpoint, veja que o endpoint para isso é localhost:9090/metrics. Caso queira alterar o path padrão, basta alterar o atributo metrics_path.

Há diversas configurações possíveis para esse arquivo, você pode ver mais na documentação oficial.

Subindo a stack de monitoramento

Agora que passamos pelos dois serviços e falamos um pouco sobre suas configurações, vamos ver isso funcionar. Mas antes, vamos ver como ficou todo o arquivo do docker-compose.yaml.

# Arquivo: docker-compose.yaml
version: "3.8"

volumes:
  grafana_data:
  prometheus_data:

networks:
  monitoring:
    external: true

services:

  grafana:
    image: grafana/grafana:9.1.6
    container_name: grafana
    restart: always
    volumes:
      - grafana_data:/var/lib/grafana
      - ./grafana/provisioning:/etc/grafana/provisioning/datasources
    environment:
      - GF_SECURITY_ADMIN_USER=${GF_SECURITY_ADMIN_USER}
      - GF_SECURITY_ADMIN_PASSWORD=${GF_SECURITY_ADMIN_PASSWORD}
      - GF_INSTALL_PLUGINS=${GF_INSTALL_PLUGINS}
    ports:
      - 3000:3000
    networks:
      - monitoring

  prometheus:
    image: prom/prometheus:v2.37.1
    container_name: prometheus
    restart: always
    volumes:
      - ./prometheus/:/etc/prometheus/
      - prometheus_data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yaml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.console.libraries=/etc/prometheus/console_libraries'
      - '--web.console.templates=/etc/prometheus/consoles'
      - '--storage.tsdb.retention.time=360h'
      - '--web.enable-lifecycle'
    ports:
      - 9090:9090
    networks:
      - monitoring

E a estrutura de diretórios e arquivos ficou assim:

grafana-prometheus
├── docker-compose.yaml
├── .env
├── .env.example
├── grafana
│   └── provisioning
│       └── ds-prometheus.yaml
└── prometheus
    └── prometheus.yaml

3 directories, 5 files

Podemos validar nosso arquivo compose para certificar que as variáveis de ambiente estão sendo passadas corretamente para o docker-compose:

$ docker-compose config

Todo o conteúdo do arquivo será impresso na tela e os valores das variáveis contidas no .env deverá assumir as variáveis do serviço do Grafana.

Se tudo tiver ok, execute o comando docker-compose up -d para subir os containers e aguarde até que seja feito o download das imagens e estejam prontos. Assim que terminar você pode executar o comando abaixo para certificar que tudo está rodando como deveria:

$ docker-compose ps

NAME                COMMAND                  SERVICE             STATUS              PORTS
grafana             "/run.sh"                grafana             running             0.0.0.0:3000->3000/tcp, :::3000->3000/tcp
prometheus          "/bin/prometheus --c…"   prometheus          running             0.0.0.0:9090->9090/tcp, :::9090->9090/tcp

Agora você poderá acessar o Grafana pelo link localhost:3000 e o Prometheus por esse link localhost:9090.

Acessando a aplicação

Grafana

Ao acessar o Grafana, você verá a tela de login, sendo necessário informar o usuário e senha. No arquivo .env que foi criado contém as credenciais de acesso.

Para acessar, entre com o usuário admin e senha password.

Para validarmos que foi provisionado corretamente um datasource, vá no menu lateral no ícone de engrenagens e clique em Datasources. Verá que foi criado um com o nome de Prometheus.

Ao clicar nele irá abrir as configurações de acesso ao Prometheus. Ao adicionar esse datasource, por padrão há disponível três opções de Dashboards para ser utilizado.

Clique na segunda aba Dashboards e clique em Import para criar o dashboard.

Tela inicial do laravel

Ao clicar em importar clique em cima do nome do Dashboard, por exemplo o Prometheus 2.0 Stats. Você verá o Dashboard apresentar os valores da própria instância do Prometheus.

Dashboard Prometheus 2.0 Stats

Esse é o início de uma configuração para usar o Grafana. Você pode procurar por mais tipos de Dashboard direto do site do Grafana.

Prometheus

Ao acessar o Prometheus, você verá a seguinte tela:

Tela inicial do Prometheus

Nessa tela é possível visualizar as métricas que estão sendo exportadas do container do Prometheus.

Visualizar métricas no Prometheus

Download código

Todo o código dessa stack você pode baixar pelo link do Github.

Conclusão

Esse é apenas o começo de uma stack de monitoramento, existem muitas outras configurações a se fazer para um ambiente de produção. Nesse artigo o objetivo principal é subir o Grafana e Prometheus com uma configuração simples mas seguindo boas práticas e com algumas pequenas customizações.

Pretendo e quero lançar uma série de artigos para subir uma stack pronta para produção, focando também em segurança, alertas entre outras possíveis configurações.

Espero que tenha ajudado até aqui.

Se você encontrar algum erro, sugestões de melhorias ou se tiver alguma dúvida, deixe seu comentário abaixo.

Até a próxima.

Imagem Aristides Neto

Aristides Neto

Atuando na área de Cloud/DevSecOps, com foco em Kubernetes e segurança no processo de CI/CD das aplicações. Entusiasta em gerenciamento de servidores Linux, impressionado com a automatização de processos e provisionamento de máquinas.