24 января 2016

NGINX Proxy High Availability (Active/Passive)

Организация кластера проксирующих Nginx серверов в режиме Active/Passive с синхронизацией конфирураций.




Все описанное относится к ОС Ubuntu 14.04.
Требоывания к системе:

  • Общий виртуальный IP.
  • Синхронизация конфигураций Nginx между нодами.
  • Nginx, в случае переезда на другую ноду должен работать в актуальной конфигурации.
  • Мониторинг консистенции конфигураций Nginx на пасивной ноде(расскажу в другой раз).

Предполагается что сам Nginx ты уже настроил.
Костяк системы heartbeat отвечающий за выделение виртуального IP. Ресурсами управляет corosync + pacemaker. Синхронизирует файлы Lsyncd.

Устанавливаем необходимые пакеты:
apt-get install nginx lsyncd pacemaker crmsh heartbeat corosync rsync haveged

Разрешаем системе биндить не принадлежащий ей IP:
echo "net.ipv4.ip_nonlocal_bind=1" >> /etc/sysctl.conf && sysctl -p

Правим файлы /etc/hosts на обеих нодах:
##### Node-1 /etc/hosts #####
10.10.102.100 sr-ngx-active.prod-s.uniservers.ru sr-ngx-active
10.10.102.101 sr-ngx01-p01-01.prod-s.uniservers.ru sr-ngx01-p01-01
10.10.102.102 sr-ngx01-p01-02.prod-s.uniservers.ru sr-ngx01-p01-02 sr-ngx-standby

##### Node-2 /etc/hosts #####
10.10.102.100 sr-ngx-active.prod-s.uniservers.ru sr-ngx-active
10.10.102.101 sr-ngx01-p01-01.prod-s.uniservers.ru sr-ngx01-p01-01 sr-ngx-standby
10.10.102.102 sr-ngx01-p01-02.prod-s.uniservers.ru sr-ngx01-p01-02

Создаем пользователя для синхронизации файлов, генерируем для него SSH ключ и отправляем его на другую ноду (на каждой ноде).
useradd -m syncbot
sudo usermod -a -G sudo syncbot
passwd syncbot

chown syncbot. /etc/nginx/conf.d/*
chown syncbot. /etc/nginx/conf.d

sudo -u syncbot ssh-keygen -t rsa
sudo -u syncbot ssh-copy-id -i /home/syncbot/.ssh/id_rsa syncbot@sr-ngx-standby

Настраиваем Lsyncd и отключаем его автозапуск (на каждой ноде):
mkdir /etc/lsyncd
mkdir /var/log/lsyncd
cat << END > /etc/lsyncd/lsyncd.conf.lua
settings{
        logfile    = "/var/log/lsyncd/lsyncd.log",
        statusFile = "/var/log/lsyncd/lsyncd-status.log",
        statusInterval = 2,
        insist = true
        }
sync{
        default.rsync,
        source="/etc/nginx/conf.d",
        target="sr-ngx-standby:/etc/nginx/conf.d",
        rsync = {
                archive = true,
                compress = false,
                whole_file = false,
                _extra = {"-P", "-e", "/usr/bin/ssh -l syncbot -i /home/syncbot/.ssh/id_rsa -o StrictHostKeyChecking=no"}
        }
}
END

cat << END > /etc/init/lsyncd.override
manual
END

Генерируем ключи для Corosync и копируем их на другую ноду:
mkdir /var/log/cluster
touch /var/log/cluster/corosync.log

### on Node1
corosync-keygen
scp /etc/corosync/authkey syncbot@sr-ngx-standby:/tmp
### on Node2
sudo mv /tmp/authkey /etc/corosync
sudo chown root: /etc/corosync/authkey
sudo chmod 400 /etc/corosync/authkey

Насраиваем Corosync:
cat << END > /etc/corosync/corosync.conf
aisexec {
        user: root
        group: root
}
service {
        ver: 1
        name: pacemaker
}
totem {
        version: 2
        cluster_name: NGINX-CLUSTER
        transport: udpu
        secauth: on
        interface {
                ringnumber: 0
                bindnetaddr: 10.10.102.0
                mcastport: 5405
        }
}
quorum {
        provider: corosync_votequorum
        two_node: 1
}
amf {
        mode: disabled
}
logging {
        fileline: off
        to_stderr: no
        to_logfile: no
        to_syslog: no
        syslog_facility: daemon
        debug: off
        logfile: /var/log/cluster/corosync.log
        timestamp: on
        logger_subsys {
                subsys: AMF
                debug: off
                tags: enter|leave|trace1|trace2|trace3|trace4|trace6
        }
}
nodelist {
        node {
        ring0_addr: sr-ngx01-p01-01
        nodeid: 1
        }
node {
        ring0_addr: sr-ngx01-p01-02
        nodeid: 2
        }
}
END

Включаем его автозагрузку при старте системы:
### vi /etc/default/corosync
START=yes
###

Отключаем автозапуск Nginx и запускаем Corosync и Pacemaker:
mv /etc/init/nginx.conf /etc/init/nginx.conf.off
service corosync restart
service pacemaker start

Самая важная часть. Настраиваем ресурсы в Corosync. Добавляем 3 ресурса- IP адрес, Nginx и Lsyncd. Склеиваем их(чтобы всегда были на одной и тойже ноде) и гасим эти ресурсы на пасивной ноде:
crm configure property stonith-enabled=false
crm configure property no-quorum-policy=ignore
crm configure property resource-stickiness="0"

crm configure primitive ClusterIP ocf:heartbeat:IPaddr2 \
 params ip="10.10.102.100" \
 op monitor depth="0" timeout="20s" interval="10s"

crm configure primitive NGINX lsb:nginx \
 op start timeout="40s" interval="0" \
 op monitor timeout="30s" interval="10s" \
 op stop timeout="60s" interval="0" meta migration-threshold=1 \
 meta multiple-active="stop_start" 

crm configure primitive LSYNCD lsb:lsyncd \
 op monitor interval="5s" \
 meta multiple-active="stop_start"
  
crm configure colocation IP-NGINX-LSYNCD inf: ClusterIP NGINX LSYNCD

Ваш дедушка/