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

Вступление

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

Демон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 нажмите «Создать новый токен»:

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-адрес в своем веб-браузере, вы должны увидеть страницу «основного» сервераindex.html:

DigitalOcean primary 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 основного сервера:

DigitalOcean primary index.html

Теперь мы готовы протестировать возможности отработки отказа нашей конфигурации.

Аварийное переключение должно происходить при возникновении любого из следующих условий:

  • 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

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

DigitalOcean page not available

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

DigitalOcean secondary index.html

Мы можем восстановиться после сбоя, перезапустив демон Nginx на основном сервере:

sudo service nginx start

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

DigitalOcean primary index.html

Отказ сервера тестирования

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

sudo reboot

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

DigitalOcean page not available

Через несколько секунд вторичный сервер примет запросы:

DigitalOcean secondary index.html

Через мгновение, когда основной сервер завершит перезагрузку, он восстановит IP-адрес:

DigitalOcean primary index.html

Это подтверждает наш второй сценарий сбоя.

Заключение

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

Related