Implementação de Cluster de Alta Disponibilidade com Nginx e Keepalived no CentOS 7

Preparação do Ambiente e Premissas

Para construir um cluster de alta disponibilidade (HA) robusto, utilizaremos o CentOS 7 como sistema operacional base. O cenário consiste em dois servidores de proxy reverso e um endereço IP virtual (VIP) que flutuará entre eles em caso de falhas.

  • Nó Primário (Master): 10.0.0.10
  • Nó Secundário (Backup): 10.0.0.20
  • IP Virtual (VIP): 10.0.0.100
  • Software: Nginx 1.12.2 e Keepalived 2.0.12

Antes de iniciar, certifique-se de que o serviço NTP está ativo para sincronização de tempo entre os nós e que o firewall local (firewalld) e o SELinux estão desativados ou devidamente configurados para permitir o tráfego VRRP (protocolo 112) e as portas do Nginx.

Compilação e Instalação do Nginx

Realize os proceidmentos abaixo no nó primário. O Nginx será compilado a partir do código-fonte para garantir a inclusão de módulos específicos de monitoramento e SSL.

# Download do código-fonte
wget http://nginx.org/download/nginx-1.12.2.tar.gz

# Instalação das dependências de compilação
yum -y install gcc gcc-c++ make pcre pcre-devel zlib zlib-devel openssl openssl-devel

# Extração e compilação
tar -zxvf nginx-1.12.2.tar.gz
cd nginx-1.12.2/

# Configuração dos módulos e definição do diretório de instalação em /opt
./configure --prefix=/opt/nginx \
            --with-http_ssl_module \
            --with-http_stub_status_module \
            --with-http_realip_module \
            --with-threads \
            --with-http_gzip_static_module

make && make install

# Transferência dos binários compilados para o nó secundário
scp -r /opt/nginx root@10.0.0.20:/opt/

Criação do Serviço Systemd para o Nginx

Para gerenciar o ciclo de vida do servidor web de forma nativa no CentOS 7, crie o arquivo de unidade do systemd:

cat <<EOF > /usr/lib/systemd/system/nginx.service
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target

[Service]
Type=forking
PIDFile=/opt/nginx/logs/nginx.pid
ExecStartPre=/opt/nginx/sbin/nginx -t
ExecStart=/opt/nginx/sbin/nginx
ExecReload=/opt/nginx/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT \$MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target
EOF

# Habilitar e iniciar o serviço
systemctl daemon-reload
systemctl enable nginx
systemctl start nginx

# Verificação da escuta na porta 80 e status do processo
netstat -tulnp | grep :80
ps -ef | grep nginx

# Replicar o arquivo de serviço para o nó secundário
scp /usr/lib/systemd/system/nginx.service root@10.0.0.20:/usr/lib/systemd/system/

No nó secundário (10.0.0.20), execute os comandos para enicializar o Nginx:

systemctl daemon-reload
systemctl enable nginx
systemctl start nginx

Compilação do Keepalived

O Keepalived será responsável pela negociação do VIP através do protocolo VRRP e pelo monitoramento da saúde do Nginx.

# Download do Keepalived
wget https://www.keepalived.org/software/keepalived-2.0.12.tar.gz

# Instalação de bibliotecas necessárias
yum install -y openssl-devel libnl3-devel ipset-devel iptables-devel libnfnetlink-devel

# Extração e compilação em diretório customizado
tar -zxvf keepalived-2.0.12.tar.gz
cd keepalived-2.0.12/
./configure --prefix=/opt/keepalived
make && make install

Configuração do Nó Primário (Master)

O arquivo de configuração define as regras de eleição, autenticação e os scripts de health check.

cd /opt/keepalived/etc/keepalived/
mv keepalived.conf keepalived.conf.bak

cat <<EOF > keepalived.conf
global_defs {
   router_id PROXY_MASTER
}

vrrp_script monitor_nginx {
    script "/opt/scripts/check_web.sh"
    interval 3
    weight -15
    fall 2
    rise 1
}

vrrp_instance WEB_CLUSTER {
    state MASTER
    interface eth0
    virtual_router_id 99
    priority 150
    advert_int 1
    nopreempt
    
    authentication {
        auth_type PASS
        auth_pass S3cur3VRRP!
    }
    
    virtual_ipaddress {
        10.0.0.100/24 dev eth0
    }
    
    track_script {
        monitor_nginx
    }
    
    notify_master "/opt/scripts/notify.sh master"
    notify_backup "/opt/scripts/notify.sh backup"
    notify_fault "/opt/scripts/notify.sh fault"
}
EOF

Ajuste de Logs e Variáveis de Ambiente

Por padrão, o Keepalived busca configurações em diretórios do sistema. Vamos isolá-lo no diretório /opt e direcionar seus logs para um arquivo específico.

# Configurar variáveis de inicialização
cat <<EOF > /opt/keepalived/etc/sysconfig/keepalived
KEEPALIVED_OPTIONS="-f /opt/keepalived/etc/keepalived/keepalived.conf -S 1 -D"
EOF

# Configurar rsyslog para isolar os logs do Keepalived
cat <<EOF > /etc/rsyslog.d/keepalived.conf
local1.*    /var/log/keepalived-ha.log
EOF

systemctl restart rsyslog

Configuração do Nó Secundário (Backup)

Transfira os diretórios de instalação e configuração do nó primário para o secundário:

scp -r /opt/keepalived root@10.0.0.20:/opt/
scp /etc/rsyslog.d/keepalived.conf root@10.0.0.20:/etc/rsyslog.d/
scp /opt/keepalived/etc/sysconfig/keepalived root@10.0.0.20:/opt/keepalived/etc/sysconfig/

No nó secundário (10.0.0.20), ajuste o arquivo keepalived.conf para atuar como Backup, reduzindo a prioridade:

cat <<EOF > /opt/keepalived/etc/keepalived/keepalived.conf
global_defs {
   router_id PROXY_BACKUP
}

vrrp_script monitor_nginx {
    script "/opt/scripts/check_web.sh"
    interval 3
    weight -15
    fall 2
    rise 1
}

vrrp_instance WEB_CLUSTER {
    state BACKUP
    interface eth0
    virtual_router_id 99
    priority 100
    advert_int 1
    nopreempt
    
    authentication {
        auth_type PASS
        auth_pass S3cur3VRRP!
    }
    
    virtual_ipaddress {
        10.0.0.100/24 dev eth0
    }
    
    track_script {
        monitor_nginx
    }
    
    notify_master "/opt/scripts/notify.sh master"
    notify_backup "/opt/scripts/notify.sh backup"
    notify_fault "/opt/scripts/notify.sh fault"
}
EOF

Criação do Serviço Systemd para o Keepalived

Se o processo de compilação não gerou o arquivo de serviço automaticamente, crie-o manualmente em ambos os nós:

cat <<EOF > /usr/lib/systemd/system/keepalived.service
[Unit]
Description=LVS and VRRP High Availability Monitor
After=network-online.target syslog.target
Wants=network-online.target

[Service]
Type=forking
PIDFile=/var/run/keepalived.pid
KillMode=process
EnvironmentFile=-/opt/keepalived/etc/sysconfig/keepalived
ExecStart=/opt/keepalived/sbin/keepalived \$KEEPALIVED_OPTIONS
ExecReload=/bin/kill -HUP \$MAINPID

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable keepalived

Script de Health Check

Este script monitora a existência dos processos do Nginx. Caso o serviço esteja inativo, ele tentará reiniciá-lo. Se a reinicialização falhar, o script encerrará o Keepalived local, forçando a migração imediata do VIP para o nó saudável.

# Execute em ambos os nós
mkdir -p /opt/scripts

cat <<'EOF' > /opt/scripts/check_web.sh
#!/bin/bash
# Contagem de processos Nginx ativos
PROC_COUNT=$(pgrep -c nginx)

if [ "$PROC_COUNT" -eq 0 ]; then
    # Tenta iniciar o Nginx
    /opt/nginx/sbin/nginx
    sleep 2
    
    # Verifica se a inicialização foi bem sucedida
    if [ $(pgrep -c nginx) -eq 0 ]; then
        # Falha crítica: derruba o Keepalived para disparar o failover
        systemctl stop keepalived
    fi
fi
EOF

chmod +x /opt/scripts/check_web.sh

Nota: Os scripts de notificação (notify.sh) referenciados no keepalived.conf devem ser criados conforme a ferramenta de alerta da sua infraestrutura (Slack, PagerDuty, E-mail, etc).

Validação e Testes de Failover

Prepare as páginas de índice para identificar visualmente qual nó está respondendo às requisições:

# No nó Master (10.0.0.10)
echo "Resposta do No Primario (10.0.0.10)" > /opt/nginx/html/index.html

# No nó Backup (10.0.0.20)
echo "Resposta do No Secundario (10.0.0.20)" > /opt/nginx/html/index.html

Inicie os serviços de cluster e reinicie o rsyslog em ambos os servidores:

systemctl restart rsyslog
systemctl start keepalived

Verificação Inicial do VIP

Consulte as interfaces de rede no nó primário para confirmar que o endereço virtual foi anexado:

ip addr show eth0 | grep 10.0.0

A saída deve exibir tanto o IP físico (10.0.0.10) quanto o VIP (10.0.0.100). No nó secundário, apenas o IP físico (10.0.0.20) deve estar presente. Teste a resposta HTTP:

curl http://10.0.0.100

O retorno esperado é: Resposta do No Primario (10.0.0.10).

Simulação de Falha do Keepalived

Interrompa o daemon do Keepalived no nó primário para simular uma pane no sistema de alta disponibilidade:

# No nó Master
systemctl stop keepalived
ip addr show eth0 | grep 10.0.0

O VIP (10.0.0.100) desaparecerá. Verificando o nó secundário, o endereço virtual já estará ativo. Uma nova requisição curl retornará:

curl http://10.0.0.100
# Saída: Resposta do No Secundario (10.0.0.20)

Ao reiniciar o Keepalived no nó primário (systemctl start keepalived), o VIP não retornará automaticamente, pois a diretiva nopreempt (modo não preemptivo) está habilitada, evitando oscilações desnecesssárias de rede.

Simulação de Falha do Nginx

Com o VIP atualmente residindo no nó secundário, vamos testar o script de health check. Interrompa o Nginx no nó secundário:

# No nó Backup (onde o VIP está ativo)
systemctl stop nginx
ip addr show eth0 | grep 10.0.0

O script check_web.sh detectará a ausência do processo, tentará reiniciá-lo e, como o serviço foi intencionalmente desativado, a reinicialização automática poderá falhar ou o script forçará a parada do Keepalived local. Consequentemente, o VIP migrará de volta para o nó primário. Verificando o nó primário:

# No nó Master
ip addr show eth0 | grep 10.0.0

O endereço 10.0.0.100 estará presente, garantindo que o tráfego continue sendo atendido sem interrupção para o cliente final.

Tags: CentOS nginx Keepalived vrrp Alta Disponibilidade

Publicado em 7-27 11:47