Поиск по сайту:

Как настроить высокодоступные веб-серверы с Keepalived и зарезервированными IP-адресами в Ubuntu 14.04


Введение

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

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

Предпосылки

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

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

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

Установить и настроить Nginx

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

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

  1. sudo apt-get update
  2. sudo apt-get install nginx

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

  1. sudo nano /usr/share/nginx/html/index.html

На вашем первом сервере замените содержимое файла следующим:

<h1>Primary</h1>

На втором сервере замените содержимое файла следующим:

<h1>Secondary</h1>

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

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

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

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

  1. sudo apt-get install build-essential libssl-dev

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

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

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

  1. tar xzvf keepalived*
  2. cd keepalived*

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

  1. ./configure
  2. make
  3. sudo make install

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

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

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

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

  1. sudo nano /etc/init/keepalived.conf

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

description "load-balancing and high-availability service"

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

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

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. Создайте этот каталог сейчас на обоих ваших серверах:

  1. sudo mkdir -p /etc/keepalived

Сбор частных IP-адресов ваших серверов

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

  1. curl http://169.254.169.254/metadata/v1/interfaces/private/0/ipv4/address && echo
Output
10.132.7.107

Это также можно найти с помощью инструментов iproute2, набрав:

  1. ip -4 addr show dev eth1

Значение, которое вы ищете, будет найдено здесь:

Output
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> 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:

  1. sudo nano /etc/keepalived/keepalived.conf

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

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

vrrp_script chk_nginx {
    script "pidof nginx"
    interval 2
}

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

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

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

vrrp_script chk_nginx {
    script "pidof nginx"
    interval 2
}

vrrp_instance VI_1 {
    interface eth1
    state MASTER
    priority 200


}

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

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 задайте общий секрет, который будет использоваться обоими узлами. К сожалению, только первые восемь символов имеют значение:

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-адреса. Мы создадим этот скрипт на мгновение:

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 на вашем вторичном сервере:

  1. sudo nano /etc/keepalived/keepalived.conf

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

  • состояние: следует изменить на \BACKUP на вторичном сервере, чтобы узел инициализировался в резервное состояние до того, как произойдут выборы.
  • priority: для него должно быть установлено более низкое значение, чем для основного сервера. В этом руководстве мы будем использовать значение \100.
  • unicast_src_ip: это должен быть частный IP-адрес вторичного сервера.
  • unicast_peer: должен содержать частный IP-адрес основного сервера.

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

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), который можно использовать для переназначения зарезервированного IP-адреса дроплету с использованием API DigitalOcean. Мы должны загрузить этот файл в каталог /usr/local/bin:

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

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

  1. python /usr/local/bin/assign-ip reserved_ip droplet_ID

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

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

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

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

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

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

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

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

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

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

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

Если вы посещаете зарезервированный IP-адрес в своем веб-браузере, вы должны увидеть страницу \основного сервера index.html:

Скопируйте зарезервированный IP-адрес вниз. Это значение понадобится вам в приведенном ниже сценарии.

Создайте сценарий оболочки

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

Создайте файл сейчас на обоих серверах, набрав:

  1. sudo nano /etc/keepalived/master.sh

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

export DO_TOKEN='digitalocean_api_token'
IP='reserved_ip_addr'

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

export DO_TOKEN='digitalocean_api_token'
IP='reserved_ip_addr'
ID=$(curl -s http://169.254.169.254/metadata/v1/id)
HAS_RESERVED_IP=$(curl -s http://169.254.169.254/metadata/v1/reserved_ip/ipv4/active)

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

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

export DO_TOKEN='digitalocean_api_token'
IP='reserved_ip_addr'
ID=$(curl -s http://169.254.169.254/metadata/v1/id)
HAS_RESERVED_IP=$(curl -s http://169.254.169.254/metadata/v1/reserved_ip/ipv4/active)

if [ $HAS_RESERVED_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 мог его вызывать:

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

Запустите службу Keepalived и проверьте отказоустойчивость

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

  1. sudo start keepalived

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

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

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

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

  • Когда проверка работоспособности Nginx на основном сервере показывает, что Nginx больше не работает. В этом случае демон keepalived основного сервера перейдет в состояние \сбой. Он уведомит дополнительный сервер о том, что он должен перейти в основное состояние и потребовать зарезервированный IP-адрес.
  • Когда дополнительный сервер теряет соединение keepalived с основным сервером. Если дополнительный сервер по какой-либо причине не может связаться с основным сервером, он перейдет в состояние «главный» и попытается получить зарезервированный IP-адрес.

Если первичный сервер позже восстановится, он вернется в состояние master и вернет зарезервированный IP-адрес, поскольку он инициирует новые выборы (он по-прежнему будет иметь наивысший номер приоритета).

Тестирование сбоя Nginx

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

  1. sudo service nginx stop

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

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

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

  1. sudo service nginx start

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

Сбой тестового сервера

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

  1. sudo reboot

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

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

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

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

Заключение

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