пятница, 10 июля 2015 г.

Балансировщик трафика для Exchange 2013

Продолжим рассматривать балансировку, отказоустойчивость и масштабирование приложений. Поскольку используется все тот же keepalived вместе с ipvs, то я не буду расписывать все подробно и рекомендую обратится к предыдущим статьям 1 и 2.
Цель задачи состоит в замене Windows Network Load Balancing(WNLB) для балансировки соединений к Exchange. Почему не устраивает WNLB?
  1. Не отслеживает доступность сервиса.
  2. Не обеспечивает равномерную балансировку
  3. Повышенная нагрузка на сетевую инфраструктуру
  4. Работает не устойчиво при нагрузке на сервера Exchange.
IP адреса нод кластера балансировки пусть будут 192.168.3.10 и 192.168.3.11. Для минимизации изменений в существующей инфраструктуре наш балансир должен иметь IP ранее принадлежащий WNLB (192.168.3.110). Следовательно, чтобы соединение прошло от клиента к кластеру Exchange (четыре сервера 192.168.3.111 - 192.168.3.114), необходимо осуществить трансляцию адреса назначения - Destination NAT. А чтобы ответные пакеты от Exchange серверов не ушли напрямую к клиенту, нужен Source NAT. Последняя ремарка: в отличие от уже упомянутых статей - это исключительно выделенный кластер для балансировки, который состоит из двух серверов (активный и резервный), в моем случае ОС это OEL6 с ядром UEK R2, это важно, поскольку более старое ядро не позволит реализовать задуманное, т.е. ядро из rhel6 не подойдет.

Итак, конфигурационный файл keepalived:

! Configuration File for keepalived

global_defs {
   notification_email {
      unix_adm@domain.ru
   }
   notification_email_from exchange_balancer01.domain.ru
   smtp_server 192.168.3.1
   smtp_connect_timeout 30
   router_id exchange_balancer01.domain.ru
}

vrrp_instance exchange_relay {
    state MASTER
    interface eth0
    virtual_router_id 117
    priority 100
    lvs_sync_daemon_interface eth0
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass mrelay
    }
    virtual_ipaddress {
        192.168.3.110
    }
    preempt
    notify_master "/etc/keepalived/snat.py -a 192.168.3.111 -a 192.168.3.112 -a 192.168.3.113 -a 192.168.3.114 -s 192.168.3.110"
    notify_backup "/etc/keepalived/snat.py -r 192.168.3.111 -r 192.168.3.112 -r 192.168.3.113 -r 192.168.3.114 -s 192.168.3.110"
    notify_fault "/etc/keepalived/snat.py -r 192.168.3.111 -r 192.168.3.112 -r 192.168.3.113 -r 192.168.3.114 -s 192.168.3.110"
}

virtual_server 192.168.3.110 443 {
    delay_loop 20
    lb_algo wlc
    lb_kind NAT
    protocol TCP

    real_server 192.168.3.111 443 {
        weight 1
          MISC_CHECK {
            misc_path "/etc/keepalived/check_exchange.sh 192.168.3.111"
            misc_timeout 18
          }
        }
    
    #Идентичные описания Exchange серверов
}

Что здесь нового:
  • lvs_sync_daemon_interface eth0 - На резервную ноду передается информация об открытых соединениях. Это позволяет оставить рабочими все текущие соединения в случае выхода из строя master ноды. Проверить работоспособность механизма передачи  на резервной ноде можно путем просмотра состояния текущих соединений:
         # ipvsadm -Lnc
  • Скрипт snat.py - в отличие от предыдущих статей, скрипт добавляет правила iptables на активную ноду, чтобы реализовать SNAT, соответственно он же убирает правила на резервной ноде. Правила в виде:
        -A POSTROUTING -d 192.168.3.111/32 -p tcp -j SNAT --to-source 192.168.3.110
  •  lb_kind NAT - Метод передачи пакетов, DNAT.
Чуть подробнее взглянем на скрипт проверки доступности приложения - check_exchange.sh.

#!/bin/sh

error=0
for i in `seq 1 3`
  do
    echo "GET /rpc/healthcheck.htm" | openssl s_client -connect $1:443 -crlf -quiet 2>/dev/null | grep "200 OK" || let error=$error+1
  done
[ $error -lt 3 ] && exit 0 || exit 1

Производится запрос состояния Exchange 2013 Outlook Anywhere путем обращения к странице https://exchange_server/rpc/healthcheck.htm. Если страница содержит 200 OK - состояние рабочее. Скрипт запрашивает три раза, и если хотя бы одна проверка верная, считается что сервис функционирует штатно. Почему так? Сервера exchange, в моем случае, работают под нагрузкой и не всегда успевают выдать страницу проверки. Если есть желание, можете дополнить скрипт на проверку других служб:

owa - Exchange 2013 Outlook Web App
ews - Exchange 2013 Web Services
microsoft-Server-ActiveSync - Exchange 2013 ActiveSync
ecp - Exchange 2013 Control Panel
autodiscover - Exchange 2013 Autodiscover Service
oab - Exchange 2013 Offline Address Book

И последнее, установите переменную ядра:

net.ipv4.vs.conntrack = 1

Без нее не будет работать контроль состояния соединения - это приведет к тому, что правила SNAT и DNAT будут работать не корректно.