Инфраструктура для бизнеса: высокая доступность

Неважно, что вы разрабатываете – маленький блог, большое приложение, API; важно, чтобы ваше детище всегда было онлайн.

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

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

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

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

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

Читайте также: Инфраструктура для бизнеса: начальная настройка среды

Цели

В этой главе мы расскажем, как развернуть балансировку нагрузки в инфраструктуре.

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

Существует несколько способов реализовать такую настройку.

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

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

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

Читайте также: Использование плавающих IP-адресов

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

В этом примере мы используем кластеризованные балансировщики нагрузки HAProxy v1.8 и плавающие IP-адреса.

1: Настройка HAProxy

На контроллере перейдите в этот каталог:

cd /root/navigators-guide/example-code/02-scale/ch04/haproxy_loadbalancer

В нем должен быть файл terraform.tfvars.sample. Он включает комментарии и примечания, с помощью которых вы быстро найдете нужную информацию.

Без комментариев файл выглядит так:

do_token = ""
project = "HAPROXY-LB"
region = "sfo2"
image_slug = "debian-9-x64"
keys = ""
private_key_path = ""
ssh_fingerprint = ""
public_key = ""

Заполните переменные согласно комментариям в файле, а затем переименуйте этот файл в terraform.tfvars.

mv terraform.tfvars.sample terraform.tfvars

Затем подготовьте и выполните развертывание Terraform. Сначала проанализируйте планы и модули с помощью команды terraform init. При желании вы можете запустить команду terraform plan, чтобы увидеть, что произойдет, когда вы запустите реальный скрипт. Когда все будет готово, запустите terraform apply для выполнения запросов на создание через API.

terraform init
terraform apply

Вам нужно будет подтвердить выполнение, введя yes; вы получите уведомление, когда заявка будет обработана.

Если прямо сейчас вы запустите terraform show, вы увидите ресурсы, которые вы развернули. Каждый набор ресурсов (т. е. сервер) помещается в группу в соответствии с именем ресурса в файле конфигурации Terraform. В этом примере объявление в файле haproxy.tf определяет три группы: это load_balancer для HAProxy, web_node для Nginx и fip для плавающих IP-адресов. Вы можете взглянуть на файл с помощью terraform-inventory -inventory, чтобы получить инвентарь Ansible в формате INI, или вывести JSON с помощью опции -list.

На этом этапе необходимые вам серверы созданы и работают, но их все еще необходимо настроить.

2: Настройка серверов с помощью Ansible

Теперь нужно автоматизировать настройку серверов через Ansible. У нас есть базовый плейбук Ansible, который загружает несколько ролей. Эти роли перечислены в файле requirements.yml. Устанавливать их по очереди не нужно. Вы можете загрузить необходимые роли с помощью Ansible Galaxy.

Эта команда поместит роли в каталог roles:

ansible-galaxy install -r requirements.yml

Для этой роли осталось установить еще несколько переменных. Вернитесь в каталог /root/navigators-guide/example-code/02-scale/ch04/haproxyloadbalancer/groupvars/load_balancer/.

Если вы откроете файл vars.yml, вы увидите, что переменным do_token и ha_auth_key присвоены значения vault_do_token и vault_ha_auth_key соответственно. Теперь нужно создать вторичный файл vault.yml и инициализировать переменные vault_.

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

cd /root/navigators-guide/example-code/02-scale/ch04/haproxy_loadbalancer/
./gen_auth_key

Создав необходимые ключи, создайте файл vars/load_balancer/vault.yml. Файл должен заканчиваться такими строками.

---
vault_do_token: "79da2e7b8795a24c790a367e4929afd22bb833f59bca00a008e2d91cb5e4285e"
vault_ha_auth_key: "c4b25a9f95548177a07d425d6bc9e00c36ec4ff8"

Безопасность и секретность этих ключей жизненно важна для инфраструктуры. Вы должны ограничить доступ, чтобы не все могли просматривать или редактировать файл vault.yml. Ansible имеет встроенную систему шифрования ansible-vault.

Используйте эту команду для шифрования файла:

ansible-vault encrypt vault.yml

Этот процесс запросит пароль. Каждый раз, когда вы будете запускать плейбук Ansible, вам снова будет предложено ввести этот пароль. Если вам нужно отредактировать зашифрованный файл, вы можете сделать это через ansible-vault. Документация по Ansible Vault содержит полный список всех возможностей этой функции.

ansible-vault edit vault.yml

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

echo 'password' > ~/.vaultpass.txt

или использовать текстовый редактор для создания файла вручную. Вам необходимо убедиться, что непривилегированные пользователи не имеют никакого доступа к этому файлу. Раскомментируйте строку vault_password_file в файле конфигурации /root/navigators-guide/example-code/02-scale/ch04/haproxy_loadbalancer/ansible.cfg. После этого Ansible не будет запрашивать пароль хранилища при каждом запуске плейбука. Вы также можете изменить путь к файлу и имя файла, который вы хотите использовать для хранения своего пароля, но при этом не забудьте сохранить его вне своего репозитория git. Иначе вы рискуете случайно добавить его в коммит и раскрыть свои пароли или секретные токены.

Теперь можно запустить основной плейбук Ansible. Вернитесь в корневой каталог репозитория и выполните команду:

ansible-playbook -i /usr/local/bin/terraform-inventory site.yml

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

PLAY RECAP *********************************************************************
138.68.50.232              : ok=1    changed=0    unreachable=0    failed=0
159.65.78.225              : ok=1    changed=0    unreachable=0    failed=0
165.227.9.176              : ok=40   changed=38   unreachable=0    failed=0
178.128.128.168            : ok=1    changed=0    unreachable=0    failed=0
178.128.3.35               : ok=40   changed=38   unreachable=0    failed=0
206.189.174.220            : ok=1    changed=0    unreachable=0    failed=0

Теперь вы можете перейти на свой сайт (в нашем примере – на простую HTML-страницу), посетив плавающий IP-адрес, или же вы можете добавить домен, который указывает на плавающий IP-адрес.

3: Тестирование доступности кластера

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

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

while true; do curl -k floating_ip; sleep 1; done
Welcome to HAPROXY-LB-backend-01!
Welcome to HAPROXY-LB-backend-02!
Welcome to HAPROXY-LB-backend-03!
Welcome to HAPROXY-LB-backend-01!
Welcome to HAPROXY-LB-backend-02!
Welcome to HAPROXY-LB-backend-03!

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

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

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

4: Масштабирование кластера

Первоначальный кластер использует 3 сервера на бэкэнде. Настройка количества этих серверов находится в объявлении переменной в файле variables.tf. Вы можете переопределить количество серверов, добавив строку в terraform.tfvars с переменной node_count со значением 5.

terraform apply

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

После внесения любых изменений в объем ресурсов вам нужно запустить Ansible, который настроит ваши серверы и изменить параметры HAProxy.

ansible-playbook -i /usr/local/bin/terraform-inventory site.yml

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

Welcome to HAPROXY-LB-backend-02!
Welcome to HAPROXY-LB-backend-03!
Welcome to HAPROXY-LB-backend-01!
Welcome to HAPROXY-LB-backend-02!
Welcome to HAPROXY-LB-backend-03!
Welcome to HAPROXY-LB-backend-04!
Welcome to HAPROXY-LB-backend-05!
Welcome to HAPROXY-LB-backend-01!
Welcome to HAPROXY-LB-backend-02!
Welcome to HAPROXY-LB-backend-03!
Welcome to HAPROXY-LB-backend-04!
Welcome to HAPROXY-LB-backend-05!
Welcome to HAPROXY-LB-backend-01!

Закончив работу, вы можете удалить ресурсы, созданные Terraform, с помощью команды destroy. Имейте в виду: вы потеряете все свои данные, если уничтожите кластер.

terraform destroy

Что дальше?

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

В следующей главе мы расскажем, как поддерживать конфигурацию балансировщика нагрузки, как управлять приложением и серверами, на которых оно находится, как обрабатывать пользовательские сеансы, хранение файлов и базу данных. Мы используем Terraform и Ansible для развертывания WordPress в кластере из восьми серверов.

Tags: , , ,