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

thaycafe

Thaynara Mendes

Posted on October 8, 2020

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/

💖 💪 🙅 🚩
thaycafe
Thaynara Mendes

Posted on October 8, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related