Как настроить высокодоступные HAProxy-серверы с поддержкой активности и плавающими IP-адресами в Ubuntu 14.04

Вступление

Высокая доступность - это функция проектирования системы, которая позволяет приложению автоматически перезапускать или перенаправлять работу на другую работоспособную систему в случае сбоя. С точки зрения серверов, существует несколько различных технологий, необходимых для настройки системы высокой доступности. Должен быть компонент, который может перенаправить работу, и должен быть механизм для отслеживания сбоя и перехода системы в случае обнаружения прерывания.

Демонkeepalived может использоваться для мониторинга служб или систем и для автоматического переключения на резервный в случае возникновения проблем. В этом руководстве мы продемонстрируем, как использоватьkeepalived для настройки высокой доступности для ваших балансировщиков нагрузки. Мы настроимfloating IP address, который можно перемещать между двумя способными балансировщиками нагрузки. Каждый из них будет настроен для разделения трафика между двумя серверными веб-серверами. Если основной балансировщик нагрузки выходит из строя, плавающий IP-адрес автоматически перемещается на второй балансировщик нагрузки, что позволяет возобновить обслуживание.

High Availability diagram

[.note] #Note:DigitalOcean Load Balancers - это полностью управляемая высокодоступная служба балансировки нагрузки. Служба Load Balancer может выполнять ту же роль, что и описанная здесь ручная настройка высокой доступности. Следуйте нашимguide on setting up Load Balancers, если хотите оценить этот вариант.
#

Предпосылки

Чтобы выполнить это руководство, вам потребуется создать четыре сервера Ubuntu 14.04 в вашей учетной записи DigitalOcean. Все серверы должны быть расположены в одном центре обработки данных и иметь включенную частную сеть.

На каждом из этих серверов вам понадобится пользователь без полномочий root, настроенный с доступомsudo. Вы можете следить за нашимиUbuntu 14.04 initial server setup guide, чтобы узнать, как настроить этих пользователей.

Поиск информации о сети сервера

Прежде чем мы начнем фактическую настройку наших компонентов инфраструктуры, лучше всего собрать некоторую информацию о каждом из ваших серверов.

Для завершения этого руководства вам понадобится следующая информация о ваших серверах:

  • web servers: частный IP-адрес

  • load balancers Частный и привязанный IP-адреса

Поиск частных IP-адресов

Самый простой способ найти частный IP-адрес вашего Droplet - использоватьcurl для получения частного IP-адреса из службы метаданных DigitalOcean. Эта команда должна быть запущена из ваших капель. На каждой капле введите:

curl 169.254.169.254/metadata/v1/interfaces/private/0/ipv4/address && echo

Правильный IP-адрес должен быть напечатан в окне терминала:

Output10.132.20.236

Нахождение якорных IP-адресов

«Якорный IP» - это локальный частный IP-адрес, с которым будет связан плавающий IP-адрес при подключении к серверу DigitalOcean. Это просто псевдоним для обычного адресаeth0, реализованный на уровне гипервизора.

Самый простой и наименее подверженный ошибкам способ получения этого значения - прямо из сервиса метаданных DigitalOcean. Используяcurl, вы можете связаться с этой конечной точкой на каждом из ваших серверов, набрав:

curl 169.254.169.254/metadata/v1/interfaces/public/0/anchor_ipv4/address && echo

Якорный IP будет напечатан в отдельной строке:

Output10.17.1.18

Установите и настройте веб-сервер

После сбора данных выше, мы можем перейти к настройке наших сервисов.

Note

[.note] # В этой настройке программное обеспечение, выбранное для уровня веб-сервера, довольно взаимозаменяемо. В этом руководстве будет использоваться Nginx, потому что оно универсальное и довольно простое в настройке. Если вам удобнее использовать Apache или (производительный) языковой веб-сервер, используйте его вместо этого. HAProxy просто будет передавать клиентские запросы на внутренние веб-серверы, которые могут обрабатывать запросы аналогично тому, как он будет обрабатывать прямые клиентские подключения.
#

Мы начнем с настройки наших серверных веб-серверов. Оба этих сервера будут обслуживать один и тот же контент. Они будут принимать веб-соединения только через свои частные IP-адреса. Это поможет гарантировать, что трафик направляется через один из двух серверов HAProxy, которые мы будем настраивать позже.

Настройка веб-серверов за балансировщиком нагрузки позволяет нам распределять нагрузку по запросам среди некоторого числа идентичных веб-серверов. Поскольку потребности в нашем трафике меняются, мы можем легко масштабироваться в соответствии с новыми требованиями, добавляя или удаляя веб-серверы этого уровня.

Установка Nginx

Мы будем устанавливать Nginx на наших веб-серверах, чтобы обеспечить эту функциональность.

Начните с входа в систему с вашим пользователемsudo на двух машинах, которые вы хотите использовать в качестве веб-серверов. Обновите локальный индекс пакетов на каждом из ваших веб-серверов и установите Nginx, введя:

sudo apt-get update
sudo apt-get install nginx

Настройте Nginx, чтобы разрешать только запросы от балансировщиков нагрузки

Далее мы настроим наши экземпляры Nginx. Мы хотим, чтобы Nginx прослушивал только запросы на частном IP-адресе сервера. Кроме того, мы будем обслуживать только запросы, поступающие с частных IP-адресов наших двух балансировщиков нагрузки.

Чтобы внести эти изменения, откройте файл блока сервера Nginx по умолчанию на каждом из ваших веб-серверов:

sudo nano /etc/nginx/sites-available/default

Для начала изменим директивыlisten. Измените директивуlisten, чтобы прослушивать текущийweb server’s private IP address на порту 80. Удалите лишнюю строкуlisten. Это должно выглядеть примерно так:

/etc/nginx/sites-available/default

server {
    listen web_server_private_IP:80;

    . . .

После этого мы настроим две директивыallow, чтобы разрешить трафик, исходящий с частных IP-адресов двух наших балансировщиков нагрузки. Мы продолжим это с помощью правилаdeny all, чтобы запретить весь другой трафик:

/etc/nginx/sites-available/default

server {
    listen web_server_private_IP:80;

    allow load_balancer_1_private_IP;
    allow load_balancer_2_private_IP;
    deny all;

    . . .

Сохраните и закройте файлы, когда вы закончите.

Проверьте, что внесенные вами изменения представляют правильный синтаксис Nginx, набрав:

sudo nginx -t

Если о проблемах не сообщалось, перезапустите демон Nginx, набрав:

sudo service nginx restart

Тестирование изменений

Чтобы проверить, правильно ли ограничены ваши веб-серверы, вы можете делать запросы, используяcurl из разных мест.

На своих веб-серверах вы можете попробовать простой запрос локального контента, набрав:

curl 127.0.0.1

Из-за ограничений, которые мы установили в наших файлах блоков сервера Nginx, этот запрос будет фактически отклонен:

Outputcurl: (7) Failed to connect to 127.0.0.1 port 80: Connection refused

Это ожидается и отражает поведение, которое мы пытались реализовать.

Теперь из любого изload balancers мы можем сделать запрос для любого из публичных IP-адресов нашего веб-сервера:

curl web_server_public_IP

Еще раз, это должно потерпеть неудачу. Веб-серверы не прослушивают общедоступный интерфейс, и, кроме того, при использовании общедоступного IP-адреса наши веб-серверы не будут видеть разрешенные частные IP-адреса в запросе от наших балансировщиков нагрузки:

Outputcurl: (7) Failed to connect to web_server_public_IP port 80: Connection refused

Однако, если мы изменим вызов, чтобы сделать запрос с использованиемprivate IP address веб-сервера, он должен работать правильно:

curl web_server_private_IP

Должна быть возвращена страница Nginxindex.html по умолчанию:

Output


Welcome to nginx!

. . .

Проверьте это с обоих балансировщиков нагрузки на оба веб-сервера. Каждый запрос на частный IP-адрес должен быть успешным, в то время как каждый запрос к публичным адресам должен завершаться сбоем.

Как только вышеприведенное поведение продемонстрировано, мы можем двигаться дальше. Настройка нашего внутреннего веб-сервера завершена.

Установите и настройте HAProxy

Далее мы настроим балансировщики нагрузки HAProxy. Каждый из них будет находиться перед нашими веб-серверами и распределять запросы между двумя внутренними серверами. Эти балансировщики нагрузки полностью избыточны. Только один будет получать трафик в любой момент времени.

Конфигурация HAProxy будет передавать запросы на оба веб-сервера. Балансировщики нагрузки будут прослушивать запросы на их якорные IP-адреса. Как упоминалось ранее, это IP-адрес, с которым будет связан плавающий IP-адрес при подключении к дроплету. Это гарантирует, что будет пересылаться только трафик, исходящий с плавающего IP-адреса.

Установить HAProxy

Первым шагом, который нам нужно предпринять для наших балансировщиков нагрузки, будет установка пакетаhaproxy. Мы можем найти это в стандартных репозиториях Ubuntu. Обновите локальный индекс пакетов на ваших балансировщиках нагрузки и установите HAProxy, введя:

sudo apt-get update
sudo apt-get install haproxy

Настроить HAProxy

Первый элемент, который нам нужно изменить при работе с HAProxy, - это файл/etc/default/haproxy. Откройте этот файл сейчас в вашем редакторе:

sudo nano /etc/default/haproxy

Этот файл определяет, будет ли HAProxy запускаться при загрузке. Поскольку мы хотим, чтобы служба запускалась автоматически каждый раз при включении сервера, нам нужно изменить значениеENABLED на «1»:

/etc/default/haproxy

# Set ENABLED to 1 if you want the init script to start haproxy.
ENABLED=1
# Add extra flags here.
#EXTRAOPTS="-de -m 16"

Сохраните и закройте файл после выполнения вышеуказанного редактирования.

Далее мы можем открыть основной файл конфигурации HAProxy:

sudo nano /etc/haproxy/haproxy.cfg

Первый пункт, который нам нужно настроить, это режим, в котором будет работать HAProxy. Мы хотим настроить TCP или уровень 4 для балансировки нагрузки. Для этого нам нужно изменить строкуmode в разделеdefault. Мы также должны изменить параметр сразу после того, что касается журнала:

/etc/haproxy/haproxy.cfg

. . .

defaults
    log     global
    mode    tcp
    option  tcplog

. . .

В конце файла нам нужно определить конфигурацию нашего интерфейса. Это будет диктовать, как HAProxy прослушивает входящие соединения. Мы свяжем HAProxy с IP-адресом привязки балансировщика нагрузки. Это позволит ему прослушивать трафик, исходящий с плавающего IP-адреса. Мы будем называть наш интерфейс «www» для простоты. Мы также определим бэкэнд по умолчанию для передачи трафика (который мы будем настраивать через минуту):

/etc/haproxy/haproxy.cfg

. . .

defaults
    log     global
    mode    tcp
    option  tcplog

. . .

frontend www
    bind    load_balancer_anchor_IP:80
    default_backend nginx_pool

Далее мы можем настроить наш бэкэнд-раздел. Это будет указывать нижестоящие местоположения, где HAProxy будет передавать полученный трафик. В нашем случае это будут частные IP-адреса обоих веб-серверов Nginx, которые мы настроили. Мы зададим традиционную циклическую балансировку и снова установим режим «tcp»:

/etc/haproxy/haproxy.cfg

. . .

defaults
    log     global
    mode    tcp
    option  tcplog

. . .

frontend www
    bind load_balancer_anchor_IP:80
    default_backend nginx_pool

backend nginx_pool
    balance roundrobin
    mode tcp
    server web1 web_server_1_private_IP:80 check
    server web2 web_server_2_private_IP:80 check

Когда вы закончите вносить вышеуказанные изменения, сохраните и закройте файл.

Проверьте, что внесенные нами изменения конфигурации представляют правильный синтаксис HAProxy, набрав:

sudo haproxy -f /etc/haproxy/haproxy.cfg -c

Если об ошибках не сообщалось, перезапустите службу, введя:

sudo service haproxy restart

Тестирование изменений

Мы можем убедиться, что наша конфигурация действительна, снова протестировав сcurl.

С серверов балансировки нагрузки попробуйте запросить локальный хост, собственный публичный IP-адрес балансировщика нагрузки или собственный IP-адрес сервера:

curl 127.0.0.1
curl load_balancer_public_IP
curl load_balancer_private_IP

Они все должны потерпеть неудачу с сообщениями, которые похожи на это:

Outputcurl: (7) Failed to connect to address port 80: Connection refused

Однако если вы сделаете запрос кanchor IP address балансировщика нагрузки, он должен успешно завершиться:

curl load_balancer_anchor_IP

Вы должны увидеть страницу Nginxindex.html по умолчанию, перенаправленную с одного из двух внутренних веб-серверов:

Output


Welcome to nginx!

. . .

Если это поведение соответствует поведению вашей системы, балансировщики нагрузки настроены правильно.

Сборка и установка Keepalived

Наш фактический сервис уже запущен и работает. Однако наша инфраструктура еще недостаточно доступна, потому что у нас нет способа перенаправить трафик, если у нашего активного балансировщика нагрузки возникают проблемы. Чтобы исправить это, мы установим демонkeepalived на наши серверы балансировки нагрузки. Это компонент, который обеспечит возможности отработки отказа, если наш активный балансировщик нагрузки станет недоступным.

В репозиториях Ubuntu по умолчанию есть версияkeepalived, но она устарела и страдает несколькими ошибками, которые могут помешать работе нашей конфигурации. Вместо этого мы установим последнюю версиюkeepalived из исходников.

Прежде чем мы начнем, мы должны получить зависимости, которые нам понадобятся для создания программного обеспечения. Мета-пакетbuild-essential предоставит необходимые инструменты компиляции, а пакетlibssl-dev содержит библиотеки разработки SSL, с которымиkeepalived должен строить:

sudo apt-get install build-essential libssl-dev

Как только зависимости установлены, мы можем загрузить архив дляkeepalived. Посетитеthis page, чтобы найти последнюю версию программного обеспечения. Щелкните правой кнопкой мыши последнюю версию и скопируйте адрес ссылки. Вернувшись на свои серверы, перейдите в свой домашний каталог и используйтеwget, чтобы захватить скопированную ссылку:

cd ~
wget http://www.keepalived.org/software/keepalived-1.2.19.tar.gz

Используйте командуtar, чтобы развернуть архив. Перейдите в получившийся каталог:

tar xzvf keepalived*
cd keepalived*

Создайте и установите демон, набрав:

./configure
make
sudo make install

Теперь демон должен быть установлен в обеих системах балансировки нагрузки.

Создать поддерживающий сценарий Upstart

При установкеkeepalived все двоичные и вспомогательные файлы были перемещены на место в нашей системе. Однако одним из элементов, который не был включен, был сценарий Upstart для наших систем Ubuntu 14.04.

Мы можем создать очень простой сценарий Upstart, который сможет обрабатывать нашу службуkeepalived. Чтобы начать работу, откройте файл с именемkeepalived.conf в каталоге/etc/init:

sudo nano /etc/init/keepalived.conf

Внутри мы можем начать с простого описания функциональности, которую предоставляетkeepalived. Мы будем использовать описание с включенной страницыman. Далее мы укажем уровни запуска, на которых служба должна запускаться и останавливаться. Мы хотим, чтобы эта служба была активна во всех нормальных условиях (уровни запуска 2-5) и остановлена ​​для всех остальных уровней запуска (например, при запуске перезагрузки, выключения питания или однопользовательского режима):

/etc/init/keepalived.conf

description "load-balancing and high-availability service"

start on runlevel [2345]
stop on runlevel [!2345]

Поскольку этот сервис является неотъемлемой частью обеспечения доступности нашего веб-сервиса, мы хотим перезапустить этот сервис в случае сбоя. Затем мы можем указать фактическую строкуexec, которая запустит службу. Нам нужно добавить параметр--dont-fork, чтобы Upstart мог правильно отслеживатьpid:

/etc/init/keepalived.conf

description "load-balancing and high-availability service"

start on runlevel [2345]
stop on runlevel [!2345]

respawn

exec /usr/local/sbin/keepalived --dont-fork

Сохраните и закройте файлы, когда вы закончите.

Создайте файл конфигурации Keepalived

Создав файлы Upstart, мы можем перейти к настройкеkeepalived.

Сервис ищет свои файлы конфигурации в каталоге/etc/keepalived. Создайте этот каталог сейчас на обоих ваших балансировщиках нагрузки:

sudo mkdir -p /etc/keepalived

Создание конфигурации основного балансировщика нагрузки

Затем на сервере балансировки нагрузки, который вы хотите использовать в качестве сервераprimary, создайте основной файл конфигурацииkeepalived. Демон ищет файл с именемkeepalived.conf внутри каталога/etc/keepalived:

sudo nano /etc/keepalived/keepalived.conf

Внутри мы начнем с определения проверки работоспособности для нашей службы HAProxy, открыв блокvrrp_script. Это позволитkeepalived отслеживать наш балансировщик нагрузки на предмет сбоев, чтобы он мог сигнализировать о том, что процесс остановлен, и начать меры по восстановлению.

Наш чек будет очень простым. Каждые две секунды мы будем проверять, что процесс с именемhaproxy по-прежнему требуетpid:

/Etc/keepalived/keepalived.conf основного сервера

vrrp_script chk_haproxy {
    script "pidof haproxy"
    interval 2
}

Далее мы откроем блок под названиемvrrp_instance. Это основной раздел конфигурации, который определяет способ, которымkeepalived реализует высокую доступность.

Мы начнем с того, что скажемkeepalived связываться со своими коллегами черезeth1, наш частный интерфейс. Поскольку мы настраиваем наш основной сервер, мы установим конфигурациюstate на «MASTER». Это начальное значение, котороеkeepalived будет использовать до тех пор, пока демон не сможет связаться со своим партнером и провести выборы.

Во время выборов опцияpriority используется для решения, какой член будет избран. Решение просто зависит от того, какой сервер имеет наибольшее число для этого параметра. Мы будем использовать «200» для нашего основного сервера:

/Etc/keepalived/keepalived.conf основного сервера

vrrp_script chk_nginx {
    script "pidof nginx"
    interval 2
}

vrrp_instance VI_1 {
    interface eth1
    state MASTER
    priority 200


}

Далее мы назначим идентификатор для этой кластерной группы, который будет использоваться обоими узлами. Мы будем использовать «33» для этого примера. Нам нужно установитьunicast_src_ip на частный IP-адрес балансировщика нагрузкиprimary. Мы установимunicast_peer на частный IP-адрес балансировщика нагрузкиsecondary:

/Etc/keepalived/keepalived.conf основного сервера

vrrp_script chk_haproxy {
    script "pidof haproxy"
    interval 2
}

vrrp_instance VI_1 {
    interface eth1
    state MASTER
    priority 200

    virtual_router_id 33
    unicast_src_ip primary_private_IP
    unicast_peer {
        secondary_private_IP
    }


}

Затем мы можем настроить простую аутентификацию для наших демоновkeepalived для связи друг с другом. Это просто базовая мера, обеспечивающая законность контакта с партнером. Создайте подблокauthentication. Внутри укажите аутентификацию по паролю, установивauth_type. Для параметраauth_pass установите общий секрет, который будет использоваться обоими узлами. К сожалению, только первые восемь символов имеют значение:

/Etc/keepalived/keepalived.conf основного сервера

vrrp_script chk_haproxy {
    script "pidof haproxy"
    interval 2
}

vrrp_instance VI_1 {
    interface eth1
    state MASTER
    priority 200

    virtual_router_id 33
    unicast_src_ip primary_private_IP
    unicast_peer {
        secondary_private_IP
    }

    authentication {
        auth_type PASS
        auth_pass password
    }


}

Затем мы скажемkeepalived использовать созданную нами в верхней части файла проверку, помеченную какchk_haproxy, для определения работоспособности локальной системы. Наконец, мы установим сценарийnotify_master, который будет выполняться всякий раз, когда этот узел становится «мастером» пары. Этот скрипт будет ответственен за запуск переназначения плавающего IP-адреса. Мы на мгновение создадим этот скрипт:

/Etc/keepalived/keepalived.conf основного сервера

vrrp_script chk_haproxy {
    script "pidof haproxy"
    interval 2
}

vrrp_instance VI_1 {
    interface eth1
    state MASTER
    priority 200

    virtual_router_id 33
    unicast_src_ip primary_private_IP
    unicast_peer {
        secondary_private_IP
    }

    authentication {
        auth_type PASS
        auth_pass password
    }

    track_script {
        chk_haproxy
    }

    notify_master /etc/keepalived/master.sh
}

После того, как вы настроили информацию выше, сохраните и закройте файл.

Создание конфигурации вторичного балансировщика нагрузки

Далее мы создадим сопутствующий скрипт на нашем дополнительном балансировщике нагрузки. Откройте файл в/etc/keepalived/keepalived.conf на вторичном сервере:

sudo nano /etc/keepalived/keepalived.conf

Внутри сценарий, который мы будем использовать, будет в значительной степени эквивалентен сценарию основного сервера. Элементы, которые нам нужно изменить:

  • state: это должно быть изменено на «РЕЗЕРВНОЕ КОПИРОВАНИЕ» на вторичном сервере, чтобы узел инициализировал состояние резервного копирования до того, как произойдут выборы.

  • priority: должно быть установлено меньшее значение, чем у основного сервера. Мы будем использовать значение «100» в этом руководстве.

  • unicast_src_ip: это должен быть частный IP-адрес сервераsecondary.

  • unicast_peer: он должен содержать частный IP-адрес сервераprimary.

Когда вы изменяете эти значения, скрипт для вторичного сервера должен выглядеть следующим образом:

/Etc/keepalived/keepalived.conf дополнительного сервера

vrrp_script chk_haproxy {
    script "pidof haproxy"
    interval 2
}

vrrp_instance VI_1 {
    interface eth1
    state BACKUP
    priority 100

    virtual_router_id 33
    unicast_src_ip secondary_private_IP
    unicast_peer {
        primary_private_IP
    }

    authentication {
        auth_type PASS
        auth_pass password
    }

    track_script {
        chk_haproxy
    }

    notify_master /etc/keepalived/master.sh
}

После того, как вы ввели скрипт и изменили соответствующие значения, сохраните и закройте файл.

Создайте плавающие сценарии перехода IP

Затем нам нужно создать пару сценариев, которые мы можем использовать для переназначения плавающего IP-адреса текущей капле, когда локальный экземплярkeepalived становится главным сервером.

Загрузите скрипт назначения плавающего IP

Сначала мы загрузим общий скрипт Python (написанныйDigitalOcean community manager), который можно использовать для переназначения плавающего IP-адреса капле с помощью DigitalOcean API. Мы должны загрузить этот файл в каталог/usr/local/bin:

cd /usr/local/bin
sudo curl -LO http://do.co/assign-ip

Этот скрипт позволяет переназначить существующий плавающий IP, выполнив:

python /usr/local/bin/assign-ip floating_ip droplet_ID

Это будет работать только в том случае, если у вас есть переменная окруженияDO_TOKEN, для которой установлен действительный токен API DigitalOcean для вашей учетной записи.

Создать токен API DigitalOcean

Чтобы использовать приведенный выше скрипт, нам нужно создать токен API DigitalOcean в нашей учетной записи.

На панели управления нажмите на ссылку «API» вверху. В правой части страницы API нажмите «Создать новый токен»:

DigitalOcean generate API token

На следующей странице выберите имя для своего токена и нажмите кнопку «Создать токен»:

DigitalOcean make new token

На странице API будет отображен ваш новый токен:

DigitalOcean token

Скопируйте токенnow. В целях безопасности невозможно снова отобразить этот токен позже. Если вы потеряете этот токен, вам придется уничтожить его и создать еще один.

Настройте плавающий IP для вашей инфраструктуры

Далее мы создадим и назначим плавающий IP-адрес для использования на наших серверах.

На панели управления DigitalOcean щелкните вкладку «Сеть» и выберите элемент навигации «Плавающие IP-адреса». Выберите основной балансировщик нагрузки в меню для начального назначения:

DigitalOcean add floating IP

Новый плавающий IP-адрес будет создан в вашей учетной записи и назначен указанной капле:

DigitalOcean floating IP assigned

Если вы посещаете плавающий IP-адрес в своем веб-браузере, вы должны увидеть страницу Nginx по умолчанию, обслуживаемую одним из внутренних веб-серверов:

DigitalOcean default index.html

Скопируйте плавающий IP-адрес вниз. Вам понадобится это значение в сценарии ниже.

Создайте скрипт Wrapper

Теперь у нас есть элементы, необходимые для создания сценария-оболочки, который будет вызывать наш сценарий/usr/local/bin/assign-ip с правильными учетными данными.

Создайте файл сейчас наboth ваших балансировщиков нагрузки, набрав:

sudo nano /etc/keepalived/master.sh

Внутри начните с назначения и экспорта переменнойDO_TOKEN, которая содержит только что созданный токен API. Ниже мы можем назначить переменную с именемIP, которая содержит ваш плавающий IP-адрес:

/etc/keepalived/master.sh

export DO_TOKEN='digitalocean_api_token'
IP='floating_ip_addr'

Затем мы будем использоватьcurl, чтобы запросить у службы метаданных идентификатор капли того сервера, на котором мы сейчас работаем. Это будет присвоено переменной с именемID. Мы также спросим, ​​есть ли у этой капли в данный момент назначенный плавающий IP-адрес. Мы сохраним результаты этого запроса в переменной с именемHAS_FLOATING_IP:

/etc/keepalived/master.sh

export DO_TOKEN='digitalocean_api_token'
IP='floating_ip_addr'
ID=$(curl -s http://169.254.169.254/metadata/v1/id)
HAS_FLOATING_IP=$(curl -s http://169.254.169.254/metadata/v1/floating_ip/ipv4/active)

Теперь мы можем использовать указанные выше переменные для вызова сценарияassign-ip. Мы будем вызывать скрипт только в том случае, если плавающий IP-адрес еще не связан с нашей каплей. Это поможет минимизировать вызовы API и предотвратить конфликтующие запросы к API в случаях, когда основное состояние быстро переключается между вашими серверами.

Чтобы обработать случаи, когда плавающий IP-адрес уже имеет событие в процессе, мы повторим сценарийassign-ip несколько раз. Ниже мы пытаемся запустить скрипт 10 раз с интервалом в 3 секунды между каждым вызовом. Цикл закончится немедленно, если перемещение с плавающим IP-адресом будет успешным:

/etc/keepalived/master.sh

export DO_TOKEN='digitalocean_api_token'
IP='floating_ip_addr'
ID=$(curl -s http://169.254.169.254/metadata/v1/id)
HAS_FLOATING_IP=$(curl -s http://169.254.169.254/metadata/v1/floating_ip/ipv4/active)

if [ $HAS_FLOATING_IP = "false" ]; then
    n=0
    while [ $n -lt 10 ]
    do
        python /usr/local/bin/assign-ip $IP $ID && break
        n=$((n+1))
        sleep 3
    done
fi

Сохраните и закройте файл, когда вы закончите.

Теперь нам просто нужно сделать скрипт исполняемым, чтобыkeepalived мог его вызывать:

sudo chmod +x /etc/keepalived/master.sh

Запустите сервис Keepalived и тестовый отказоустойчивый

Демонkeepalived и все его сопутствующие сценарии теперь должны быть полностью настроены. Мы можем запустить сервис на обоих наших балансировщиках нагрузки, набрав:

sudo start keepalived

Служба должна запускаться на каждом сервере и связываться со своим партнером, проходя аутентификацию с использованием общего секретного ключа, который мы настроили Каждый демон будет отслеживать локальный процесс HAProxy и слушать сигналы от удаленного процессаkeepalived.

Ваш основной балансировщик нагрузки, которому в настоящее время должен быть назначен плавающий IP-адрес, будет направлять запросы на каждый из внутренних серверов Nginx по очереди. Обычно применяется некоторая простая привязка к сеансу, что повышает вероятность того, что вы получите тот же бэкэнд при выполнении запросов через веб-браузер.

Мы можем проверить отказоустойчивость простым способом, просто отключив HAProxy на нашем основном балансировщике нагрузки:

sudo service haproxy stop

Если мы посетим наш плавающий IP-адрес в нашем браузере, мы можем на мгновение получить ошибку, указывающую, что страница не может быть найдена:

http://floating_IP_addr

DigitalOcean page not available

Если мы обновим страницу несколько раз, через мгновение наша страница по умолчанию Nginx вернется:

DigitalOcean default index.html

Наша служба HAProxy все еще не работает с нашим основным балансировщиком нагрузки, поэтому это означает, что наш вторичный балансировщик нагрузки вступил во владение. Используяkeepalived, вторичный сервер смог определить, что произошло прерывание обслуживания. Затем он перешел в «главное» состояние и запросил плавающий IP с помощью API DigitalOcean.

Теперь мы можем снова запустить HAProxy на основном балансировщике нагрузки:

sudo service haproxy start

Основной балансировщик нагрузки мгновенно восстановит контроль над плавающим IP-адресом, хотя это должно быть довольно прозрачно для пользователя.

Визуализация перехода

Чтобы лучше представить переход между балансировщиками нагрузки, мы можем отслеживать некоторые из наших журналов сервера во время перехода.

Поскольку информация о том, какой прокси-сервер используется, не возвращается клиенту, лучшее место для просмотра журналов - с реальных серверных веб-серверов. Каждый из этих серверов должен вести журналы о том, какие клиенты запрашивают активы. С точки зрения сервиса Nginx, клиент - это балансировщик нагрузки, который делает запросы от имени реального клиента.

Хвост журналы на веб-серверах

На каждом из наших внутренних веб-серверов мы можемtail местоположение/var/log/nginx/access.log. Это покажет каждый запрос, сделанный на сервер. Поскольку наши балансировщики нагрузки равномерно распределяют трафик с помощью циклического чередования, каждый внутренний веб-сервер должен видеть около половины выполненных запросов.

К счастью, адрес клиента - самое первое поле в журнале доступа. Мы можем извлечь значение с помощью простой командыawk. Выполните следующее наboth ваших веб-серверов Nginx:

sudo tail -f /var/log/nginx/access.log | awk '{print $1;}'

Скорее всего, они покажут один адрес:

Output. . .

primary_lb_private_IP
primary_lb_private_IP
secondary_lb_private_IP
secondary_lb_private_IP
primary_lb_private_IP
primary_lb_private_IP
primary_lb_private_IP
primary_lb_private_IP

Если вы ссылаетесь на IP-адреса вашего сервера, вы заметите, что они в основном исходят от вашего основного балансировщика нагрузки. Обратите внимание, что фактическое распределение, вероятно, будет немного отличаться из-за некоторой простой липкости сеанса, которую реализует HAProxy.

Продолжайте выполнять командуtail на обоих веб-серверах.

Автоматизировать запросы к плавающему IP

Теперь на вашем локальном компьютере мы будем запрашивать веб-контент с плавающим IP-адресом каждые 2 секунды. Это позволит нам легко увидеть изменение балансировки нагрузки. В локальном терминале введите следующее (мы отбрасываем фактический ответ, потому что он должен быть одинаковым независимо от того, какой балансировщик нагрузки используется):

while true; do curl -s -o /dev/null floating_IP; sleep 2; done

На ваших веб-серверах вы должны начать видеть новые запросы. В отличие от запросов, отправленных через веб-браузер, простые запросыcurl не демонстрируют такой же липкости сеанса. Вы должны увидеть более равномерное распределение запросов к вашим серверным веб-серверам.

Прервать службу HAProxy на основном балансировщике нагрузки

Теперь мы можем снова отключить службу HAProxy на нашем основном балансировщике нагрузки:

sudo service haproxy stop

Через несколько секунд на ваших веб-серверах вы увидите список перехода IP-адресов с частного IP-адреса основного балансировщика нагрузки на частный IP-адрес дополнительного балансировщика нагрузки:

Output. . .

primary_lb_private_IP
primary_lb_private_IP
primary_lb_private_IP
primary_lb_private_IP
primary_lb_private_IP
secondary_lb_private_IP
secondary_lb_private_IP
secondary_lb_private_IP
secondary_lb_private_IP

Все новые запросы сделаны из вашего дополнительного балансировщика нагрузки.

Теперь снова запустите экземпляр HAProxy на основном балансировщике нагрузки:

sudo service haproxy start

Через несколько секунд вы увидите, как клиентские запросы возвращаются к частному IP-адресу основного балансировщика нагрузки:

Output. . .

primary_lb_private_IP
primary_lb_private_IP
primary_lb_private_IP
primary_lb_private_IP
primary_lb_private_IP
secondary_lb_private_IP
secondary_lb_private_IP
secondary_lb_private_IP
secondary_lb_private_IP
primary_lb_private_IP
primary_lb_private_IP
primary_lb_private_IP

Основной сервер восстановил контроль над плавающим IP-адресом и возобновил свою работу в качестве основного балансировщика нагрузки для инфраструктуры.

Настройте Nginx для регистрации фактического IP-адреса клиента

Как вы видели, журналы доступа Nginx показывают, что все клиентские запросы поступают с частного IP-адреса текущего балансировщика нагрузки, а не с фактического IP-адреса клиента, который первоначально сделал запрос (т.е. ваша локальная машина). Часто полезно регистрировать IP-адрес исходного клиента, а не сервера балансировки нагрузки. Это легко сделать, внеся несколько изменений в конфигурацию Nginx на всех ваших серверных веб-серверах.

На обоих веб-серверах откройте файлnginx.conf в редакторе:

sudo nano /etc/nginx/nginx.conf

Найдите раздел «Настройки журнала» (в блокеhttp) и добавьте следующую строку:

добавить в /etc/nginx/nginx.conf

log_format haproxy_log 'ProxyIP: $remote_addr - ClientIP: $http_x_forwarded_for - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent "$http_referer" ' '"$http_user_agent"';

Сохранить и выйти. Это определяет новый формат журнала с именемhaproxy_log, который добавляет значение$http_x_forwarded_for - IP-адрес клиента, который сделал исходный запрос - к записям журнала доступа по умолчанию. Мы также включаем$remote_addr, который является IP-адресом балансировщика нагрузки обратного прокси (т.е. активный сервер балансировки нагрузки).

Затем, чтобы использовать этот новый формат журнала, нам нужно добавить строку в наш блок сервера по умолчанию.

На обоих веб-серверах откройте конфигурацию сервераdefault:

sudo nano /etc/nginx/sites-available/default

В блокеserver (подходящее место прямо под директивойlisten) добавьте следующую строку:

добавить в / etc / nginx / sites-available / default

        access_log /var/log/nginx/access.log haproxy_log;

Сохранить и выйти. Это сообщает Nginx о необходимости записи журналов доступа в формате журналаhaproxy_log, который мы создали выше.

На обоих веб-серверах перезапустите Nginx, чтобы изменения вступили в силу:

sudo service nginx restart

Теперь ваши журналы доступа Nginx должны содержать фактические IP-адреса клиентов, делающих запросы. Проверьте это, следя за логи ваших серверов приложений, как мы делали в предыдущем разделе. Записи в журнале должны выглядеть примерно так:

New Nginx access logs:. . .
ProxyIP: load_balancer_private_IP - ClientIP: local_machine_IP - - [05/Nov/2015:15:05:53 -0500] "GET / HTTP/1.1" 200 43 "-" "curl/7.43.0"
. . .

Если ваши журналы выглядят хорошо, все готово!

Заключение

В этом руководстве мы прошли весь процесс настройки высокодоступной инфраструктуры с балансировкой нагрузки. Эта конфигурация работает хорошо, потому что активный сервер HAProxy может распределить нагрузку на пул веб-серверов на сервере. Вы можете легко масштабировать этот пул по мере роста или сокращения вашего спроса.

Конфигурация с плавающим IP-адресом иkeepalived устраняет единую точку отказа на уровне балансировки нагрузки, позволяя вашей службе продолжать работу даже при полном выходе из строя основного балансировщика нагрузки. Эта конфигурация является достаточно гибкой и может быть адаптирована к вашей собственной прикладной среде путем настройки предпочитаемого веб-стека за серверами HAProxy.

Related