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.