Отказоустойчивый кластер OpenNebula используя алгоритм Raft
Настройка High Available облачной платформы OpenNebula используя распределенный консенсусный протокол для обеспечения отказоустойчивости и согласованности состояния Raft.
Что такое Raft?
Raft - это консенсусный алгоритм, который предназначен для простого понимания. Он эквивалентен привычному Paxos в отказоустойчивости и производительности. Разница заключается в том, что он разлагается на относительно независимые подзадачи и четко рассматривает все основные части, необходимые для практических систем.
Консенсусный алгоритм построен на основе двух концепций:
Состояние системы, в OpenNebula состояние системы - это данные, хранящиеся в таблицах базы данных (пользователи, ACL или виртуальные машины в системе).
Log, последовательность операторов SQL, которые последовательно применяются к базе данных OpenNebula на всех серверах для развития состояния системы.
Чтобы сохранить согласованное представление системы между серверами, изменения состояния системы выполняются через специальный узел, лидер (в дальнейшем Leader). Серверы в кластере OpenNebula выбирают один узел, чтобы быть лидером. Лидер периодически посылает запросы (heartbeats) другим серверам, последователям (в дальнейшем Follower), чтобы сохранить свое лидерство. Если лидер не может послать запрос, последователи продвигаются к кандидатам и начинают новые выборы.
Всякий раз, когда система изменяется (например, в систему добавляется новый виртуальный сервер), лидер обновляет журнал и реплицирует запись у большинства последователей, прежде чем записывать её в базу данных. Таким образом, латентность операций БД увеличивается, но состояние системы безопасно реплицируется, и кластер может продолжить свою работу в случае сбоя узла.
Рекомендации и требования
Рекомендуемый размер для разворачивания кластера - это минимум 3 или 5 серверов, что обеспечивает отказоустойчивость при сбое 1-2 серверов. Добавлять дополнительные сервера или удалять старые можно после запуска кластера.
Для настройки High Available требуется:
- Нечетное количество серверов (от 3-х минимум).
- Рекомендуется идентичная конфигурация серверов (объем памяти, вычислительная мощность).
- Идентичная настройка программного обеспечения серверов (различие в поле
SERVER_ID
файла/etc/one/oned.conf
). - Рекомендуется использовать соединение с базой данных того же типа, MySQL (Galera сервер не требуется).
- Серверы должны иметь беспарольный доступ для связи друг с другом.
- Плавающий IP, который будет назначен лидеру (Floating IP).
- Общая файловая система(Ceph, NFS и пр.)
- Sunstone без проксирования должен быть установлен и запущен на всех узлах кластера.
Настройка High Available кластера
В данном примере я покажу как настроить HA кластер из 5-и серверов:
- 10.0.1.10 vmm01.devservers.network
- 10.0.1.20 vmm02.devservers.network
- 10.0.1.30 vmm03.devservers.network
- 10.0.1.40 vmm04.devservers.network
- 10.0.1.50 vmm05.devservers.network
- 10.0.1.100 Floating IP
Для того, чтобы поддерживать работу кластера в нормальном режиме работы во время процедуры добавления серверов, убедитесь, что вы добавляете только один сервер за раз. В противном случае это может привести к дублированию данных в базе данных.
Шаг 1. Первоначальная конфигурация Leader
Запускаем сервис OpenNebula и добавляем локальный сервер в существующую или новую зону.
1 | $ onezone list |
Добавляем сервер, который будет лидером в рабочую зону.
В данном случае зона с ID 0
и сервер vmm01.devservers.network
1 | $ onezone server-add 0 --name vmm01.devservers.network --rpc http://10.0.1.10:2633/RPC2 |
Проверяем:
1 | $ onezone show 0 |
Останавливаем сервис opennebula
и обновляем конфигурацию SERVER_ID
в файле /etc/one/oned.conf
.
1 | FEDERATION = [ |
Активируем Raft-хуки для того, чтобы добавить плавающий адрес в кластер.
1 | # Executed when a server transits from follower->leader |
Запускаем сервис opennebula
и проверяем зону.
Насколько мы видим, то сервер vmm01.devservers.network
стал Leader-сервером.
1 | $ onezone show 0 |
Так же ему был присвоен плавающий адрес (Floating IP).
1 | $ ip -o a sh eth0|grep 10.0.1 |
Шаг 2. Добавление дополнительных серверов
Данная процедура удалит полностью базу на сервере и заменит её актуальной с Leader-сервера.
Рекомендуется добавлять по одному хосту за раз, чтобы избежать конфликта в базе данных. После добавления хоста и проверки статуса - приступайте к следующему серверу.
На Leader создайте полный бэкап актуальной базы и перенесите его на другие сервера вместе с файлами из директории /var/lib/one/.one/
1 | $ onedb backup -u oneadmin -d opennebula -p oneadmin |
Копируем дамп базы на сервера, которые будут участниками кластера:
1 | $ scp mysql_localhost_opennebula_2018-9-20_17:15:20.sql <ip>:/tmp |
Удаляем на хостах директорию /var/lib/one/.one
и копируем её же с Leader-сервера (сохраняйте при копировании привилегии oneadmin:oneadmin
):
1 | $ ssh <ip> rm -rf /var/lib/one/.one |
Останавливаем сервис opennebula
на Follower хостах и ресторим скопированную базу.
1 | $ onedb restore -f -u oneadmin -p oneadmin -d opennebula /var/lib/one/mysql_localhost_opennebula_2018-9-20_17:15:20.sql |
Переходим на Leader сервере и добавляем в зону новые хосты (рекомендую добавлять сервера по-одному!)
1 | $ onezone server-add 0 --name vmm02.devservers.network --rpc http://10.0.1.20:2633/RPC2 |
Проверяем зону на Leader-сервере. Новый сервер находится в состоянии ошибки, так как OpenNebula на новом сервере не запущена. Запомните идентификатор сервера, в этом случае он равен 1.
1 | $ onezone show 0 |
Ошибка будет отображаться пр причине того, что сервис OpenNebula не запущен на Follower хосте. Это нормально.
Переключаемся на добавленный Follower-сервер и обновляем конфигурацию SERVER_ID
в файле /etc/one/oned.conf
, указывая в качестве SERVER_ID
значение из предыдущего шага, исходя из предыдущего шага. Обязательно включаем хуки Raft, как это было выполнено на Leader.
Запускаем сервис OpenNebula на Follower-сервере и проверяем на Leader-сервере состояние зоны.
1 | $ onezone show 0 |
Может случиться так, что значения
TERM/INDEX/COMMIT
не соответствуют указанным выше. Это не важно! Они будут автоматически синхронизироваться при изменении базы данных.
Повторяем Шаг 2 для того, чтобы добавить дополнительные сервера в кластер.
Обратите внимание, что вы можете добавлять сервера в кластер, только в случае его нормальной работы. Это означает, что работает Leader, а остальные находятся в состоянии Follower. Если в состоянии error присутствует хотя бы один сервер - исправьте это перед продолжением.
В конечном итоге результат будет приблизительно следующим:
1 | $ onezone show 0 |