EC2 com logs centralizados utilizando Loki + FluentBit + Grafana
Paulo Alves
Posted on January 25, 2023
acessei via SSM e por ai vai. Se eu tivesse um lugar com os logs centralizados das instâncias EC2, eu poderia consultar os logs das instância com problemas e trabalhar na resolução.
Com isso surgiu a ideia de montar este artigo para documentar e ajudar outras pessoas. Neste artigo não reinventei a roda, fiz um compilado do que já existe nas documentações oficiais. Entre outras documentações que fui encontrando para facilitar na configurações.
Vou colocar aqui as adaptações que fiz para o meu cenário de atuação, mas também deixar de forma clara para que qualquer um possa utilizar.
OBS: Neste artigo estou seguindo com uma estrutura de VPC já criada na AWS para as 2 instâncias utilizadas no LAB
Vou fazer um apresentação rápida e básica dos serviços que serão utilizados neste artigo:
EC2 - é um serviço com recurso computacional, redimensionável e que pode ser utilizado para qualquer workload. Uma definição bem básica sobre este serviço disponibilizado pela AWS.
FluentBit - É o agente responsável por ler o arquivo de log e enviar para o Loki.
Grafana Loki - É uma stack de monitoramentos de logs.
Grafana Dashbord - É a ferramenta onde irei criar o dash de visualização de logs da instância que será utilizada como LAB.
Feito um breve resumo das ferramentas que serão utilizadas, vou iniciar a criação do servidor do Grafana.
Para criação do servidor que irá hospedar Grafana, Loki vou utilizar os comandos do awscli. Mas para criação deste ambiente poderia ter sido utilizado outras ferramentas de provisionamento e configurações, segue abaixo alguns exemplos de ferramentas
Um exemplo dessas ferramentas são: Terraform, Cloudformation, Ansible, Chef, Puppet
Criando uma instância do EC2
Para iniciar a criação da instância, ao invés de criar uma chave .pem vou importar a minha chave pública para acessar a instância:
aws ec2 import-key-pair --key-name "grafana-server" --public-key-material fileb://~/.ssh/id_rsa.pub
Na sequência vou criar um security group:
aws ec2 create-security-group --group-name grafana-server --description "Grafana EC2 Server" --vpc-id vpc-668d120f
Agora vou criar 2 regras de ingress no security group criado:
aws ec2 authorize-security-group-ingress --group-id sg-02c489bbdeffdca1d --protocol tcp --port 22 --cidr 192.168.15/32
aws ec2 authorize-security-group-ingress --group-id sg-02c489bbdeffdca1d --protocol tcp --port 3000 --cidr 192.168.15/32
aws ec2 authorize-security-group-ingress --group-id sg-02c489bbdeffdca1d --protocol tcp --port 3100 --cidr 192.168.15/32
Na última regra liberando a porta 3100 ela é necessária para que o fluent-bit possa se comunicar com o Loki e fazer o envio dos logs.
Deixei as regras do security group somente para acesso da minha rede local
Criando a instância:
aws ec2 run-instances --image-id ami-0b5eea76982371e91 --instance-type t3.medium --key-name grafana-server --security-group-ids sg-0aa58857d399d42d0 --subnet-id subnet-0f322466aad742642 --associate-public-ip-address
Instalando e configurando Docker, Grafana e o Loki
Com o ambiente criado, vou seguir com a instalação do Grafana e Loki. Neste ponto vou subir 2 containers, que irão se comunicar pela rede interna do docker. Vou acessar a console para pegar o endereço público da instância. Para criação da instância utilizei a AMI com Amazon Linux 2, então o acesso será feito desta forma:
ssh ec2-user@ec2-174-129-133-73.compute-1.amazonaws.com
Logado na instância vou fazer a instalação do serviço do docker:
sudo yum update -y
sudo yum install docker -y
sudo service docker start
sudo usermod -a -G docker ec2-user
Após ter feito a instalação se receber a seguinte mensagem:
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/json": dial unix /var/run/docker.sock: connect: permission denied
É necessário dar um logout e fazer o login novamente
Agora vou criar a rede no docker e subir o container do Grafana e do Loki
Criando a rede:
docker network create networklogs --driver bridge
Rede criada vou subir os 2 containers:
docker run -d --name=grafana --network monitoring -p 3000:3000 grafana/grafana-os
docker run -d --name=loki --network monitoring -p 3100:3100 grafana/loki
Se os 2 container subiram sem problemas, podemos acessar via browser a console do Grafana.
http://ec2-174-129-133-73.compute-1.amazonaws.com:3000
Se estiver tudo ok, essa tela deverá se exibida
Nessa tela o usuário e senha padrão é admin admin. Após logar você será solicitado a alterar a senha.
Logado na interface vamos fazer a config do Loki, para isso a engrenagem no painel lateral esquerdo > Plugins
Nos plugins vai na busca para procurar pelo plugin do Loki
Agora clique no botão azul Create a Loki data source
Agora vou preencher as informações solicitadas. Em url perceba que coloquei
http://loki:3100
Porque este endereço?
Lembra que incialmente eu cria uma rede interna docker, certo? Com isso ao invés de chamar
http://localhost:3100
Eu estou chamando na url pelo nome do container.
Feito as configs, pode clicar em Save & test. Caso aparece essa mensagem:
É porque ainda não estamos enviando os logs com os labels utilizado nas querys.
Ambiente do Grafana e Loki configurados, vamos configurar o ambiente que fará o envio dos logs. Aqui vou utilizar os mesmo comandos iniciais, já vou partir para o acesso via SSH e instalação do Nginx, que enviará os logs do access.log para o servidor do Loki.
Instalando Nginx no Amazon Linux 2
sudo yum install nginx -y
sudo service nginx start
Necessário somente instalar e dar start no serviço
Na instância onde o Nginx está instalado, é necessário que tenha o docker instalado também. Pois será necessário para subir o container do fluent-bit para que seja feito o envio dos logs.
Iniciando o container do fluent-bit para o envio dos logs, aqui vou utilizar a configuração padrão sem mexer em labels ou qualquer outra config. O valor da variável LOKI_URL vou colocar o ip interno da instância do servidor do Grafana, para que isso não passe pela internet para não termos gastos desnecessários.
docker run -d -v /var/log/nginx:/var/log/nginx -e LOG_PATH="/var/log/nginx/access.log" -e LOKI_URL="http://10.42.12.1:3100/loki/api/v1/push" grafana/fluent-bit-plugin-loki:latest
Assim que o container estiver up, de alguns acesse o Nginx pelo public DNS e de alguns F5 para gerar logs no access.log
Um detalhe, se for novamente na parte dos plugins, verá que aquela mensagem do Datasource que printei anteriormente na config do Loki não está mais aparecendo uma vez que estamos enviando os logs.
Vou validar se os logs estão chegando no Loki, para isso vou fazer um query. Na interface do Grafana, vá em Explore
Em label filters selecione o seguintes valores:
A query deverá fica desta forma. Agora vamos rodar a query e ver se temos os logs da instância do nginx.
Se na parte inferior, retornar desta forma
Funcionou com sucesso as configs.
Tentei demonstrar basicamente a criação de um servidor Grafana com plugin do Loki para coleta dos logs de um Nginx, instalado em uma instância EC2. Os logs aqui foram enviados utilizando o fluent-bit, com as configurações default. Aqui eu utilizei o fluent-bit para fazer a coleta e envio dos logs, mas poderia ser utilizado qualquer outro ship para o envio de logs, por exemplo o Promtail.
E ai vamos se conectar? Entre em contato comigo:
https://www.linkedin.com/in/pcmalves/
Referências:
https://hub.docker.com/r/grafana/fluent-bit-plugin-loki
https://grafana.com/docs/loki/latest/clients/fluentbit/
https://grafana.com/blog/2020/07/13/loki-tutorial-how-to-set-up-promtail-on-aws-ec2-to-find-and-analyze-your-logs/
Posted on January 25, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.