DEV Community

Thaynara Mendes for Sysadminas

Posted on • Edited on

Guia de como criar um cluster com o centralizador de logs Graylog 3.3

Heeey!

Fiz um lab utilizando a arquitetura do Graylog de alta disponibilidade e resolvi criar um guia com os passos que fiz nessa jornada.

Na documentação do graylog essa configuração se chama "Multi-node Setup". Utilizaremos 3 servidores com Graylog e MongoDB, 3 servidores com Elasticsearch e 1 com HAProxy.

Para ter uma ideia. Nossa arquitetura vai ficar desta forma:

OBS:Os servidores foram criados com a distro CentOS 7. Logo, se fizer em outra distro vai ter que rever os processo de instalação. Vamos lá ;)

Elasticsearch

O Elasticsearch é o mecanismo de busca e análise de dados que o Graylog utiliza para indexar os logs recebidos.

Instalação

O Graylog apenas suporta até a versão 6.x do Elasticsearch.

eu que sempre instalo a última versão das coisas descobri isso após ter finalizado o cluster </3

Um pré-requisito para todos servidores é o java. Então vamos começar por ele.

yum update && yum -y install java-1.8.0-openjdk-headless.x86_64 
Enter fullscreen mode Exit fullscreen mode

Para a instalação do Elasticsearch, vamos importar a Elastic GPG key.

rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch 
Enter fullscreen mode Exit fullscreen mode

E adicionar o arquivo elasticsearch.repo no /etc/yum.repos.d/.

$ vim elasticsearch.repo [elasticsearch-6.x] name=Elasticsearch repository for 6.x packages baseurl=https://artifacts.elastic.co/packages/oss-6.x/yum gpgcheck=1 gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch enabled=1 autorefresh=1 type=rpm-md 
Enter fullscreen mode Exit fullscreen mode

Após isso basta instalar

yum install elasticsearch-oss 
Enter fullscreen mode Exit fullscreen mode

Configuração

Como os meus servidores eu coloquei o mínimo de RAM (1G) precisei mudar algumas opções do Java, limitando o uso de memória dele. Caso tiver mais que 1G não precisa fazer essa etapa.
Altere as linhas:

$ vim /etc/elasticsearch/jvm.options -Xms512m -Xmx512m 
Enter fullscreen mode Exit fullscreen mode

Edite o arquivo de configuração:

$ vim /etc/elasticsearch/elasticsearch.yml cluster.name: graylog node.name: ${HOSTNAME} network.host: 0.0.0.0 http.port: 9200 discovery.zen.ping.unicast.hosts: ["elastic1.lab", "elastic2.lab", "elastic3.lab"] 
Enter fullscreen mode Exit fullscreen mode

OBS: Para ficar melhor a identificação dos servers, configurei o DNS no /etc/hosts

Após configurar basta subir o serviço:

systemctl daemon-reload systemctl enable elasticsearch.service systemctl restart elasticsearch.service 
Enter fullscreen mode Exit fullscreen mode

Você consegue checar o status do Elasticsearch através do curl:

$ curl http://elastic1.lab:9200 { "name" : "elastic1", "cluster_name" : "graylog", "cluster_uuid" : "qMtqk9hUTcm9gT8a6wF7-w", "version" : { "number" : "6.8.12", "build_flavor" : "oss", "build_type" : "rpm", "build_hash" : "7a15d2a", "build_date" : "2020-08-12T07:27:20.804867Z", "build_snapshot" : false, "lucene_version" : "7.7.3", "minimum_wire_compatibility_version" : "5.6.0", "minimum_index_compatibility_version" : "5.0.0" }, "tagline" : "You Know, for Search" } 
Enter fullscreen mode Exit fullscreen mode

No meu caso não foi de primeira, por um bloqueio do SELinux. Então caso não conseguir verifique se o SELinux ou o firewall está bloqueando a conexão.

Você pode apenas desabilitar o firewall ou deixá-lo ativo e liberar a conexão do elasticsearch.

Para desabilitar basta rodar o comando:

$ systemctl disable firewalld 
Enter fullscreen mode Exit fullscreen mode

Após replicar esses processos nos outros dois servidores, o nosso cluster do Elasticsearch estará pronto!

MongoDB

OBS: Agora vamos configurar 3 servidores com mongo e Graylog, então recomendo no mínimo 2G

O MongoDB é um serviço de banco de dados NoSQL que o Graylog utiliza para armazenar os dados de configuração.

Instalação

Crie um arquivo mongodb-org-4.4.repo no /etc/yum.repos.d/

$ vim mongodb-org-4.4.repo [mongodb-org-4.4] name=MongoDB Repository baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/4.4/x86_64/ gpgcheck=1 enabled=1 gpgkey=https://www.mongodb.org/static/pgp/server-4.4.asc 
Enter fullscreen mode Exit fullscreen mode

Após isso basta instalar
yum update && yum install -y mongodb-org

Configuração

Crie os diretórios:

mkdir -p /var/lib/mongo mkdir -p /var/log/mongodb mkdir -p /data/db 
Enter fullscreen mode Exit fullscreen mode

Configure as permissões do usuário mongod:

chown -R mongod:mongod /var/lib/mongo chown -R mongod:mongod /var/log/mongodb 
Enter fullscreen mode Exit fullscreen mode

Na documentação do mongo, tem uma seção para configurar a política do SELinux para que permita os acessos. Caso sua distro não use SELinux, pode pular essa etapa.

$ yum install checkpolicy policycoreutils-python 
Enter fullscreen mode Exit fullscreen mode
cat > mongodb_cgroup_memory.te <<EOF module mongodb_cgroup_memory 1.0; require { type cgroup_t; type mongod_t; class dir search; class file { getattr open read }; } #============= mongod_t ============== allow mongod_t cgroup_t:dir search; allow mongod_t cgroup_t:file { getattr open read }; EOF 
Enter fullscreen mode Exit fullscreen mode
$ checkmodule -M -m -o mongodb_cgroup_memory.mod mongodb_cgroup_memory.te $ semodule_package -o mongodb_cgroup_memory.pp -m mongodb_cgroup_memory.mod $ semodule -i mongodb_cgroup_memory.pp 
Enter fullscreen mode Exit fullscreen mode

Após configurar basta subir o serviço:

$ systemctl daemon-reload $ systemctl enable mongod $ systemctl start mongod 
Enter fullscreen mode Exit fullscreen mode

Você consegue testar a conexão rodando:

mongo 
Enter fullscreen mode Exit fullscreen mode

OBS:Caso mostrar alguma falha, verifique o firewall.

Para a configuração das réplicas do mongo basta executar (antes é preciso parar a instancia do mongod que está rodando):

mongod --replSet "rs0" --bind_ip localhost,mongodb1.lab --fork --logpath /var/log/mongodb/mongod 
Enter fullscreen mode Exit fullscreen mode

Sobre o esta linha de comando:

  • mude mongodb1.lab para o endereço do server
  • --fork é para que o processo seja executado em segundo plano
  • --replSet para inserir o nome da configuração de replicação.

Após fazer esses procedimentos nos 3 servers. Em apenas um, conecte ao mongo shell:

$ mongo 
Enter fullscreen mode Exit fullscreen mode

e inicialize a configuração da replica:

rs.initiate( { _id : "rs0", members: [ { _id: 0, host: "mongodb1.devops.lab:27017" }, { _id: 1, host: "mongodb2.devops.lab:27017" }, { _id: 2, host: "mongodb3.devops.lab:27017" } ] }) 
Enter fullscreen mode Exit fullscreen mode

você consegue verificar a configuração rodando:

rs.status() 
Enter fullscreen mode Exit fullscreen mode

a saída deve estar mais ou menos desta forma:

rs0:PRIMARY> rs.status() { "set" : "rs0", "date" : ISODate("2020-10-07T04:23:25.190Z"), "myState" : 1, "term" : NumberLong(12), "syncSourceHost" : "", "syncSourceId" : -1, "heartbeatIntervalMillis" : NumberLong(2000), "majorityVoteCount" : 2, "writeMajorityCount" : 2, "votingMembersCount" : 3, "writableVotingMembersCount" : 3, "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1602044601, 9), "t" : NumberLong(12) }, "lastCommittedWallTime" : ISODate("2020-10-07T04:23:21.627Z"), "readConcernMajorityOpTime" : { "ts" : Timestamp(1602044601, 9), "t" : NumberLong(12) }, "readConcernMajorityWallTime" : ISODate("2020-10-07T04:23:21.627Z"), "appliedOpTime" : { "ts" : Timestamp(1602044604, 11), "t" : NumberLong(12) }, "durableOpTime" : { "ts" : Timestamp(1602044602, 11), "t" : NumberLong(12) }, "lastAppliedWallTime" : ISODate("2020-10-07T04:23:24.975Z"), "lastDurableWallTime" : ISODate("2020-10-07T04:23:22.958Z") }, "lastStableRecoveryTimestamp" : Timestamp(1602044492, 7), "electionCandidateMetrics" : { "lastElectionReason" : "electionTimeout", "lastElectionDate" : ISODate("2020-10-07T04:19:54.787Z"), "electionTerm" : NumberLong(12), "lastCommittedOpTimeAtElection" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) }, "lastSeenOpTimeAtElection" : { "ts" : Timestamp(1601673721, 7), "t" : NumberLong(11) }, "numVotesNeeded" : 2, "priorityAtElection" : 1, "electionTimeoutMillis" : NumberLong(10000), "numCatchUpOps" : NumberLong(0), "newTermStartDate" : ISODate("2020-10-07T04:19:55.550Z"), "wMajorityWriteAvailabilityDate" : ISODate("2020-10-07T04:19:56.455Z") }, "members" : [ { "_id" : 0, "name" : "mongodb1.devops.lab:27017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 424, "optime" : { "ts" : Timestamp(1602044604, 11), "t" : NumberLong(12) }, "optimeDate" : ISODate("2020-10-07T04:23:24Z"), "syncSourceHost" : "", "syncSourceId" : -1, "infoMessage" : "", "electionTime" : Timestamp(1602044395, 1), "electionDate" : ISODate("2020-10-07T04:19:55Z"), "configVersion" : 1, "configTerm" : 12, "self" : true, "lastHeartbeatMessage" : "" }, { "_id" : 1, "name" : "mongodb2.devops.lab:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 219, "optime" : { "ts" : Timestamp(1602044604, 6), "t" : NumberLong(12) }, "optimeDurable" : { "ts" : Timestamp(1602044601, 9), "t" : NumberLong(12) }, "optimeDate" : ISODate("2020-10-07T04:23:24Z"), "optimeDurableDate" : ISODate("2020-10-07T04:23:21Z"), "lastHeartbeat" : ISODate("2020-10-07T04:23:24.801Z"), "lastHeartbeatRecv" : ISODate("2020-10-07T04:23:25.012Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "", "syncSourceHost" : "mongodb1.devops.lab:27017", "syncSourceId" : 0, "infoMessage" : "", "configVersion" : 1, "configTerm" : 12 }, { "_id" : 2, "name" : "mongodb3.devops.lab:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 212, "optime" : { "ts" : Timestamp(1602044604, 6), "t" : NumberLong(12) }, "optimeDurable" : { "ts" : Timestamp(1602044601, 5), "t" : NumberLong(12) }, "optimeDate" : ISODate("2020-10-07T04:23:24Z"), "optimeDurableDate" : ISODate("2020-10-07T04:23:21Z"), "lastHeartbeat" : ISODate("2020-10-07T04:23:24.801Z"), "lastHeartbeatRecv" : ISODate("2020-10-07T04:23:25.031Z"), "pingMs" : NumberLong(1), "lastHeartbeatMessage" : "", "syncSourceHost" : "mongodb1.devops.lab:27017", "syncSourceId" : 0, "infoMessage" : "", "configVersion" : 1, "configTerm" : 12 } ], "ok" : 1, "$clusterTime" : { "clusterTime" : Timestamp(1602044604, 11), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } }, "operationTime" : Timestamp(1602044604, 11) } 
Enter fullscreen mode Exit fullscreen mode

Crie um banco de dados e um usuário para o Graylog:

use graylog; db.createUser( { user: "mongo_admin", pwd: "graylog", roles: [ { role: "root", db: "admin" } ] } ) 
Enter fullscreen mode Exit fullscreen mode

Certo, com o Elasticsearch e o MongoDB configurados, vamos para o Graylog!

Graylog

Instalação

$ rpm -Uvh https://packages.graylog2.org/repo/packages/graylog-3.3-repository_latest.rpm $ yum update && yum -y install java-1.8.0-openjdk-headless.x86_64 graylog-server 
Enter fullscreen mode Exit fullscreen mode

Configuração

Você também consegue alterar o uso de memória do Java, o arquivo de configuração dessas opções que fica em /etc/sysconfig/graylog-server.

Antes de editar o arquivo de configuração, você irá precisar gerar duas senhas.

Para gerar a password_secret basta rodar o comando:

pwgen -N 1 -s 96 
Enter fullscreen mode Exit fullscreen mode

obs: caso não tenha o pwgen instalado basta seguir esses passos:

$ yum install epel-release $ yum install pwgen 
Enter fullscreen mode Exit fullscreen mode

Para gerar a root_password_sha2, rode esse comando:

echo -n "Enter Password: " && head -1 </dev/stdin | tr -d '\n' | sha256sum | cut -d" " -f1 
Enter fullscreen mode Exit fullscreen mode

Após isso, edite o arquivo de configuração:

$ vim /etc/graylog/server/server.conf is_master = true password_secret = [gerada anteriormente] root_password_sha2 = [gerada anteriormente] root_timezone = America/Sao_Paulo http_bind_address = graylog1.lab:9000 http_publish_uri = http://graylog.1.lab:9000/ elasticsearch_hosts = http://elastic1.lab:9200,http://elastic2.lab:9200,http://elastic3.lab:9200 elasticsearch_shards = 3 mongodb_uri = mongodb://mongo_admin:graylog@mongodb1.lab:27017,mongodb2.lab:27017,mongodb3.lab:27017/graylog?replicaSet=rs0 
Enter fullscreen mode Exit fullscreen mode

obs:

  • apenas deixe is_master = true em um dos servidores
  • modifique web.graylog1 para o endereço do server
  • modifique a linha elasticsearch_hosts com os endereços dos servidores do elasticsearch
  • modifique a linha mongodb_uricom os endereços dos servidores do mongo

Agora basta subir o server do graylog:

$ systemctl daemon-reload $ systemctl enable graylog-server $ systemctl start graylog-server 
Enter fullscreen mode Exit fullscreen mode

Após alguns minutos você irá conseguir acessar o endereço do graylog http://graylog1.lab:9000/. O login é admin e a senha é a que você inseriu no campo root_password_sha2.

Alt Text

HAProxy

o HAProxy vai servir como um balanceador de carga para o nosso cluster. Isso quer dizer que ao configurar o envio de logs, nós iremos mandar para o endereço do servidor que está o HAProxy e ele que vai ser o responsável por enviar para os servidores do graylog.

Instalação

yum update && yum install haproxy 
Enter fullscreen mode Exit fullscreen mode

Configuração

Edite o arquivo de configuração e insira os blocos:

$ vim /etc/haproxy/haproxy.cfg listen stats bind :32700 stats enable stats uri / stats hide-version stats auth devops:devopslab listen syslog_1514 bind *:1514 mode tcp option tcplog timeout client 120s timeout server 120s default-server inter 2s downinter 5s rise 3 fall 2 maxconn 64 maxqueue 128 weight 100 server graylog1 graylog1.lab:1514 check server graylog2 graylog2.lab:1514 check server graylog3 graylog3.lab:1514 check 
Enter fullscreen mode Exit fullscreen mode

O primeiro bloco é para a página de estatísticas que o HAProxy exibe, ao acessá-la você conseguirá ver o balanceamento de dados entres os servidores do graylog. Basta acessar o endereço do server na porta 32700:

http://web.graylog.lab:32700/

O segundo bloco é a configuração da porta onde o HAProxy irá "ouvir" e depois realizar o balanceamento entre os servers. O "check" é para que ele verifique se o server está up antes de enviar.

Enviando log para o Graylog

Você consegue enviar praticamente qualquer log de sistema para o servidor do graylog. Neste guia eu vou demonstrar apenas como configurar o envio utilizando o rsyslog.

Para outros tipos de log, você pode utilizar o Graylog Sidecar, é um serviço que roda em segundo plano coletando logs que deseja enviar para a API do Graylog.

O primeiro passo para isso é configurar o Input na API do graylog, ele é o responsável por criar uma porta específica para os variados tipos de log.

Acesse a API do Graylog (no meu caso http://graylog1.lab:9000/) e siga os passos:

  1. Vá em System
  2. Depois em Inputs
  3. Selecione SysLog TCP
  4. Selecione Launch new Input

Ao seguir esses passos irá abrir uma janela para que preencha os detalhes do Input então vamos preencher os campos:

  1. Marque a opção Global
  2. Title: “Log Syslog”
  3. Bind address: 0.0.0.0
  4. Port:1514
  5. Clique em Salvar.

Ao clicar em salvar, verá que o status do input passará de NOT RUNNING para RUNNING.

Agora que você já configurou o input, basta configurar o rsyslog da máquina que irá enviar os logs:

$ vim /etc/rsyslog.d/graylog.conf *.* @@web.graylog.lab:1514;RSYSLOG_SyslogProtocol23Format 
Enter fullscreen mode Exit fullscreen mode

obs:Troque web.graylog.lab para o endereço do servidor do HAProxy

Reinicie o serviço

systemctl restart rsyslog 
Enter fullscreen mode Exit fullscreen mode

Alt Text
Após todos esses passos, ao acessar a API do Graylog, na aba Search você conseguirá visualizar, fazer consultas e criar dashboards personalizadas :)

última observação: Quando lidamos com cluster é muito importante que todos os servidores estejam com o mesmo horário, a divergência pode gerar erros no graylog.

Vlw pessoal! \o/

Top comments (0)