Вступление
Высокая доступность - это функция проектирования системы, которая позволяет приложению автоматически перезапускать или перенаправлять работу на другую работоспособную систему в случае сбоя. С точки зрения серверов, существует несколько различных технологий, необходимых для настройки системы высокой доступности. Должен быть компонент, который может перенаправить работу, и должен быть механизм для отслеживания сбоя и перехода системы в случае обнаружения прерывания.
Демонkeepalived
может использоваться для мониторинга служб или систем и для автоматического переключения на резервный в случае возникновения проблем. В этом руководстве мы продемонстрируем, как использоватьkeepalived
для настройки высокодоступной веб-службы. Мы настроимfloating IP address, который можно перемещать между двумя совместимыми веб-серверами. Если основной сервер выходит из строя, плавающий IP-адрес автоматически перемещается на второй сервер, что позволяет возобновить работу службы.
Предпосылки
Чтобы выполнить это руководство, вам необходимо создать два сервера Ubuntu 14.04 под своей учетной записью DigitalOcean. Оба сервера должны быть расположены в одном центре обработки данных и иметь включенную частную сеть.
На каждом из этих серверов вам понадобится пользователь без полномочий root, настроенный с доступомsudo
. Вы можете следить за нашимиUbuntu 14.04 initial server setup guide, чтобы узнать, как настроить этих пользователей.
Когда вы будете готовы начать работу, войдите на оба сервера под своим пользователем без полномочий root.
Установите и настройте Nginx
Хотяkeepalived
часто используется для мониторинга и переключения балансировщиков нагрузки, чтобы уменьшить нашу операционную сложность, в этом руководстве мы будем использовать Nginx в качестве простого веб-сервера.
Начните с обновления локального индекса пакетов на каждом из ваших серверов. Затем мы можем установить Nginx:
sudo apt-get update
sudo apt-get install nginx
В большинстве случаев для высокодоступной установки вы хотите, чтобы оба сервера обслуживали один и тот же контент. Однако для ясности в этом руководстве мы будем использовать Nginx, чтобы указать, какой из двух серверов обслуживает наши запросы в любой момент времени. Для этого мы изменим страницуindex.html
по умолчанию на каждом из наших хостов. Откройте файл сейчас:
sudo nano /usr/share/nginx/html/index.html
На вашем первом сервере замените содержимое файла следующим:
/Usr/share/nginx/html/index.html основного сервера
Primary
На вашем втором сервере замените содержимое файла следующим:
/Usr/share/nginx/html/index.html вторичного сервера
Secondary
Сохраните и закройте файлы, когда вы закончите.
Сборка и установка 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
Сбор частных IP-адресов ваших серверов
Прежде чем мы создадим файл конфигурации, нам нужно найти частные IP-адреса обоих наших серверов. На серверах DigitalOcean вы можете получить наш частный IP-адрес через службу метаданных, набрав:
curl http://169.254.169.254/metadata/v1/interfaces/private/0/ipv4/address && echo
Output10.132.7.107
Это также можно найти с помощью инструментовiproute2
, набрав:
ip -4 addr show dev eth1
Значение, которое вы ищете, будет найдено здесь:
Output3: eth1: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
inet 10.132.7.107/16 brd 10.132.255.255 scope global eth1
valid_lft forever preferred_lft forever
Скопируйте это значение из обеих ваших систем. Нам нужно будет ссылаться на эти адреса внутри наших файлов конфигурации ниже.
Создание конфигурации основного сервера
Затем на основном сервере создайте основной файл конфигурацииkeepalived
. Демон ищет файл с именемkeepalived.conf
внутри каталога/etc/keepalived
:
sudo nano /etc/keepalived/keepalived.conf
Внутри мы начнем с определения проверки работоспособности нашей службы Nginx, открыв блокvrrp_script
. Это позволитkeepalived
отслеживать наш веб-сервер на предмет сбоев, чтобы он мог сигнализировать о том, что процесс не работает, и начать меры по восстановлению.
Наш чек будет очень простым. Каждые две секунды мы будем проверять, что процесс с именемnginx
по-прежнему требуетpid
:
/Etc/keepalived/keepalived.conf основного сервера
vrrp_script chk_nginx {
script "pidof nginx"
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_nginx {
script "pidof nginx"
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_nginx {
script "pidof nginx"
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_nginx
, для определения работоспособности локальной системы. Наконец, мы установим сценарийnotify_master
, который будет выполняться всякий раз, когда этот узел становится «мастером» пары. Этот скрипт будет ответственен за запуск переназначения плавающего IP-адреса. Мы на мгновение создадим этот скрипт:
/Etc/keepalived/keepalived.conf основного сервера
vrrp_script chk_nginx {
script "pidof nginx"
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_nginx
}
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_nginx {
script "pidof nginx"
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_nginx
}
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 нажмите «Создать новый токен»:
На следующей странице выберите имя для своего токена и нажмите кнопку «Создать токен»:
На странице API будет отображен ваш новый токен:
Скопируйте токенnow. В целях безопасности невозможно снова отобразить этот токен позже. Если вы потеряете этот токен, вам придется уничтожить его и создать еще один.
Настройте плавающий IP для вашей инфраструктуры
Далее мы создадим и назначим плавающий IP-адрес для использования на наших серверах.
На панели управления DigitalOcean щелкните вкладку «Сеть» и выберите элемент навигации «Плавающие IP-адреса». Выберите дроплет из списка, который вы назначили своим «основным» сервером:
Новый плавающий IP-адрес будет создан в вашей учетной записи и назначен указанной капле:
Если вы посетите плавающий IP-адрес в своем веб-браузере, вы должны увидеть страницу «основного» сервера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
Служба должна запускаться на каждом сервере и связываться со своим партнером, проходя аутентификацию с использованием общего секретного ключа, который мы настроили Каждый демон будет отслеживать локальный процесс Nginx и слушать сигналы от удаленного процессаkeepalived
.
Когда оба сервера исправны, если вы посещаете свой плавающий IP-адрес в веб-браузере, вы должны перейти на страницу Nginx основного сервера:
Теперь мы готовы протестировать возможности отработки отказа нашей конфигурации.
Аварийное переключение должно происходить при возникновении любого из следующих условий:
-
When the Nginx health check on the primary server indicates that Nginx is no longer running. В этом случае демон первичного сервера
keepalived
перейдет в состояние «сбой». Он уведомит вторичный сервер о том, что он должен перейти в главное состояние, и запросит плавающий IP-адрес. -
When the secondary server loses its
keepalived
connection to the primary server. Если вторичный сервер не может связаться с первичным сервером по какой-либо причине, он перейдет в «главное» состояние и попытается запросить плавающий IP-адрес.
Если основной сервер позднее восстанавливается, он переходит обратно в главное состояние и восстанавливает плавающий IP-адрес, потому что он инициирует новые выборы (он по-прежнему будет иметь самый высокий приоритетный номер).
Тестирование Nginx Failure
Мы можем проверить первое условие, остановив службу Nginx на основном сервере:
sudo service nginx stop
Если вы обновите свой веб-браузер, вы можете сначала получить ответ, указывающий, что страница недоступна:
Однако через несколько секунд, если вы обновите страницу несколько раз, вы увидите, что дополнительный сервер запросил плавающий IP-адрес:
Мы можем восстановиться после сбоя, перезапустив демон Nginx на основном сервере:
sudo service nginx start
Через несколько секунд, если вы обновите страницу, вы обнаружите, что основной сервер снова получил право владения плавающим IP:
Отказ сервера тестирования
Другой сценарий, который мы должны проверить, заключается в том, правильно ли вторичный сервер переходит в основное состояние, если он не может подключиться к первичному серверу. Мы можем перезагрузить главный сервер, чтобы проверить это:
sudo reboot
Опять же, сначала мы должны увидеть прерывание службы на плавающем IP-адресе:
Через несколько секунд вторичный сервер примет запросы:
Через мгновение, когда основной сервер завершит перезагрузку, он восстановит IP-адрес:
Это подтверждает наш второй сценарий сбоя.
Заключение
В этом руководстве мы настроили среду веб-сервера с высокой доступностью, используяkeepalived
, API DigitalOcean и плавающий IP-адрес. Фактическая инфраструктура была довольно простой, но концепции можно применять к любому типу инфраструктуры, где важны доступность и время безотказной работы.