Перейти к содержанию

Отказоустойчивая версия#

Для повышения высокой доступности и минимизации времени простоя системы разверните отказоустойчивую Акуру (HA).

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

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

Для разворачивания отказоустойчивой версии достаточно

  • трех виртуальных машин, работающих на базе Ubuntu 24.04,
  • одной виртуальной машины для балансировщика нагрузки.

При необходимости увеличивайте количество узлов, адаптируя систему под потребности вашей организации.

Предварительная подготовка. Развертывание виртуальной машины#

Чтобы успешно развернуть отказоустойчивый кластер Акуры, разверните виртуальную машину с помощью Python 3.11. Мы рекомендуем использовать Ubuntu 24.04, однако, если вы используете более поздние версии, дополнительно установите pyenv для настройки Python 3.11. Подробная инструкция находится здесь.

Шаг 1. Подготовьте группу безопасности#

Перед развертыванием ознакомьтесь со следующими правилами входящего трафика:

Тип вещания Протокол IP Диапазон портов Префикс удаленного IP Удаленная группа безопасности Описание
IPv4 TCP 1 - 65535 - acura_ha Обратите внимание, что для созданной нами группы безопасности все порты TCP будут открыты. Это необходимо для связи Kubernetes между узлами (например, для кластеров etcd или MariaDB).
IPv4 TCP 22 (SSH) <IP*>/32 - Разрешить порт TCP/22 с моего публичного IP для протоколов SSH и Ansible.
IPv4 TCP 80 (HTTP) 0.0.0.0/6443 - Порт пользовательского интерфейса Акуры перенаправляет пользователя на порт HTTPS.
IPv4 TCP 443 (HTTPS) 0.0.0.0/6443 - Порт пользовательского интерфейса Акуры
IPv4 TCP 4443 0.0.0.0/6443 - Порт для начальных настроек
IPv4 TCP 6443 0.0.0.0/6443 - Порт для доступа к службе API Kubernetes
IPv4 TCP 30080 <IP*>/32 - Порт сервиса MariaDB
IPv4 TCP 30081 <IP*>/32 - Порт сервиса Kibana
IPv4 TCP 30082 <IP*>/32 - Порт сервиса Grafana
IPv4 UDP 12201 0.0.0.0/6443 - Порт для записи логов: используется агентами и модулями для отправки логов в стек ELK.

IP* - IP-адрес для доступа к Акуре

Note

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

Шаг 2. Создайте три виртуальные машины#

Создайте три экземпляра Ubuntu 24.04 с томами по 200 ГБ (рекомендуется использовать SSD-диски). Все 200 ГБ должны быть доступны как один раздел, без отдельных разделов для /home и т. д. Также рекомендуется выделить не менее 16 ГБ оперативной памяти и 8 виртуальных ЦП для каждого экземпляра.

Пример:

ha_deployment_010

Проверьте правильность DNS-серверов на всех узлах (cat /etc/resolv.conf). Они должны быть доступны с DHCP-сервера. Например, результат команды nslookup должен выглядеть следующим образом:

$ nslookup google.com
Server:     8.8.8.8
Address:    8.8.8.8#53

Non-authoritative answer:cd 
Name:   google.com
Address: 64.233.165.113
Name:   google.com
...

Если DNS-серверы не работают, проверьте конфигурацию DNS подсети (например, используйте 8.8.8.8 в качестве DNS-сервера). Имена хостов не должны быть полными доменными именами (FQDN); они не должны содержать точек.

ha_deployment_020

Шаг 3. Создайте балансировщик нагрузки#

Откройте следующие порты:

Имя Описание Протокол Порт
initconfig Порт интерфейса начальной настройки TCP 4443
http Порт HTTP TCP 80
k8s Порт API сервисов Kubernetes TCP 6443
https Порт HTTPS для интерфейса Акуры TCP 443

Пример конфигурации облаке

ha_deployment_030

Конфигурация NGINX

Не забудьте заменить X.X.X.X, Y.Y.Y.Y и Z.Z.Z.Z на IP-адреса ваших узлов. X.X.X.X - IP-адрес первого узла, Y.Y.Y.Y - второго и Z.Z.Z.Z - третьего.

$ cat /etc/nginx/nginx.conf
user www-data;
worker_processes auto;
worker_rlimit_nofile 70000;
pid /run/nginx.pid;

events {
        worker_connections 70000;
    # multi_accept on;
}

stream {
    upstream stream_http {
        least_conn;
        server X.X.X.X:80;
        server Y.Y.Y.Y:80;
        server Z.Z.Z.Z:80;
    }

    upstream stream_https {
        least_conn;
        server X.X.X.X:443;
        server Y.Y.Y.Y:443;
        server Z.Z.Z.Z:443;
    }

    upstream stream_initial_config {
        least_conn;
        server X.X.X.X:4443;
        server Y.Y.Y.Y:4443;
        server Z.Z.Z.Z:4443;
    }

    upstream stream_kubernetes {
        least_conn;
        server X.X.X.X:6443;
        server Y.Y.Y.Y:6443;
        server Z.Z.Z.Z:6443;
    }

    upstream stream_elk {
        least_conn;
        server X.X.X.X:12201;
        server Y.Y.Y.Y:12201;
        server Z.Z.Z.Z:12201;
    }

    upstream stream_registry {
        least_conn;
        server X.X.X.X:15000;
        server Y.Y.Y.Y:15000;
        server Z.Z.Z.Z:15000;
    }

    server {
        listen        80;
        proxy_pass    stream_http;
    }

    server {
        listen        443;
        proxy_pass    stream_https;
        proxy_buffer_size 10m;
    }

    server {
        listen        4443;
        proxy_pass    stream_initial_config;
    }

    server {
        listen        6443;
        proxy_pass    stream_kubernetes;
        proxy_timeout 10s;
        proxy_connect_timeout 10s;
    }

    server {
        listen     12201 udp;
        proxy_pass stream_elk;
        proxy_timeout 30s;
        proxy_connect_timeout 60s;
    }

    server {
        listen        15000;
        proxy_pass    stream_registry;
    }
}

Устранение неполадок

  • Если после изменения конфигурации у вас возникли проблемы с запуском или перезапуском NGINX, вы можете проверить правильность конфигурации с помощью команды: nginx -t

  • Если при запуске NGINX возникает ошибка, например, неизвестная директива «stream», добавьте следующую строку в начало конфигурации:

load_module /usr/lib/nginx/modules/ngx_stream_module.so;

Проверьте доступ по SSH из развернутой виртуальной машины к виртуальным машинам Акуры

Чтобы сэкономить время, проверьте доступ к порту 22 перед запуском любых установок. Это можно сделать с помощью простой команды Bash:

$ for i in X.X.X.X Y.Y.Y.Y Z.Z.Z.Z; do nc -vz -w 2 $i 22 ; done
Connection to X.X.X.X 22 port [tcp/ssh] succeeded!
Connection to Y.Y.Y.Y 22 port [tcp/ssh] succeeded!
Connection to Z.Z.Z.Z 22 port [tcp/ssh] succeeded!

X.X.X.X, Y.Y.Y.Y и Z.Z.Z.Z - целевые публичные IP-адреса. Если доступ невозможен, то вы увидите сообщения подобного рода:

$ for i in X.X.X.X Y.Y.Y.Y Z.Z.Z.Z; do nc -vz -w 2 $i 22 ; done
nc: connect to X.X.X.X port 22 (TCP) timed out: Operation now in progress
nc: connect to Y.Y.Y.Y port 22 (TCP) timed out: Operation now in progress
nc: connect to Z.Z.Z.Z port 22 (TCP) timed out: Operation now in progress

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

Шаг 4. Подготовьте localhost#

1. Установите пакеты

sudo apt install python3-pip sshpass
pip3 install --upgrade pip==20.3.4
pip3 install "virtualenv<20.0"

2. Скачайте архив от Хайстекс по указанному URL адресу

3. Распакуйте архив “hystax-ha-archive.tar.gz”

tar xvzf hystax-ha-archive.tar.gz

4. Установите модули и пакеты, необходимые для работы

cd hystax_ha_archive
source venv.sh
pip install -r requirements.txt

В случае ошибки при установке, попробуйте следующую последовательность действий:

  • установите пакет: sudo apt install libffi-dev
  • повторите команду pip install -r requirements.txt.

5. Создайте файл “ha_env_file” с описанием отказоустойчивой среды

<HOSTNAME1> ansible_ssh_host=<X.X.X.X>
<HOSTNAME2> ansible_ssh_host=<Y.Y.Y.Y>
<HOSTNAME3> ansible_ssh_host=<Z.Z.Z.Z>

Note

HOSTNAME1 — имя хоста первой машины Ubuntu, X.X.X.X — публичный IP-адрес первой машины Ubuntu и т. д.

Устранение неполадок

Если хосты Акуры используют разные SSH ключи (не ~/.ssh/id_rsa), для удобства добавьте их в файл ha_env_file:

ansible_ssh_private_key_file=<path_to_your_private_key>

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

1. Запустите в фоне SSH агента:

$ eval "$(ssh-agent -s)"

2. Добавьте закрытый ключ SSH к агенту:

$ ssh-add ~/.ssh/id_rsa"

Шаг 5. Установите мастера Kubernetes#

Разверните мастер Kubernetes HA

export ANSIBLE_HOST_KEY_CHECKING=False
ansible-playbook -e "ansible_ssh_user=<SSH_USER_NAME>" \
-e "lb_address=<LOAD_BALANCER_IP>" \
-e "ansible_python_interpreter=/usr/bin/python3" \
-e "logstash_host=127.0.0.1" \
-i ha_env_file ansible/k8s-master.yaml

Устранение неполадок

Если при введении команды требуется постоянный ввод пароля, используйте SSH ключи от виртуальных машин, созданных на шаге 2. Для этого добавьте приватные SSH ключи машин в файл ha_env_file, как описано на шаге 4

ansible_ssh_private_key_file=<path_to_your_private_key>

Это позволит избежать необходимости вводить пароль заново.

Если у пользователя нет прав root, добавьте к команде флаг -K, чтобы сразу при запуске сценария запрашивать пароль.

Шаг 6. Развертывание Акуры#

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

export ANSIBLE_HOST_KEY_CHECKING=False
ansible-playbook -e "ansible_ssh_user=<SSH USER NAME>" \
-e '{"overlay_list": ["overlay/ha.yaml", "overlay/golden-image.yml", "overlay/distr-dr.yaml", "overlay/startup_reconfigure.yaml"]}' \
-e "copy_patch=true" \
-e "copy_ca=true" \
-i ha_env_file ansible/ha-acura.yaml

Note

Данная команда разворачивает Акура для аварийного восстановления и резервного копирования. Если нужно развернуть решение для облачной миграции, замените название файла distr-dr.yaml на distr-migration.yaml.

После развертывания

1. Удостоверьтесь, что все поды Kubernetes запущены.

2. Настройте Акуру, для этого перейдите по адресу:

https://<LOAD-BALANCER-PUBLIC-IP>

Пример: https://89.208.86.10.

Как ...#

... обновить уже развернутую Акуру#

1. Выполните Шаг 4. Подготовьте localhost. После этого выполните команду, чтобы получить список существующих оверлеев, использованных при создании кластера:

kubectl exec -ti etcd-0 -- etcdctl get /overlay_list

При необходимости измените список оверлеев в etcd:

kubectl exec -ti etcd-0 -- etcdctl set /overlay_list ["old_overlay1","old_overlay2",<...>,"new_overlay"]

2. Выполните Шаг 6. Развертывание Акуры. При развертывании Акуры добавьте параметр -e "update_cluster=true" в ansible-playbook. Например:

export ANSIBLE_HOST_KEY_CHECKING=False
ansible-playbook -e "ansible_ssh_user=<SSH_USER_NAME>" \
-e '{"overlay_list": ["overlay/ha.yaml", "overlay/golden-image.yml", "overlay/distr-dr.yaml", "overlay/startup_reconfigure.yaml", "overlay/big-heat-stack-timeout.yaml"]}' \
-e "copy_patch=true" \
-e "copy_ca=true" \
-e "update_cluster=true" \
-i ha_env_file ansible/ha-acura.yaml

... удалить неработающий узел из отказоустойчивой Акура#

1. Войдите на работающий узел.

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

kubectl get nodes

3. Выполните команду kubectl delete node <DEAD_NODE_NAME>, чтобы удалить неработающий узел из Kubernetes. Вместо <DEAD_NODE_NAME> используйте имя узла с предыдущего шага.

4. Запустите команду, чтобы идентифицировать ID неработающего узла из etcd (первая колонка) Вместо <LIVE_NODE_NAME> используйте имя узла, с которого запускаете команду.

kubectl exec etcd-<LIVE_NODE_NAME> -n kube-system -- etcdctl --cacert /etc/kubernetes/pki/etcd/ca.crt --cert /etc/kubernetes/pki/etcd/peer.crt --key /etc/kubernetes/pki/etcd/peer.key member list

5. Запустите команду, чтобы удалить нерабочий узел из кластера etcd. Вместо <LIVE_NODE_NAME> используйте имя узла, с которого запускаете команду. Вместо <DEAD_MEMBER_ID> используйте ID неработающего узла из etcd с предыдущего шага.

kubectl exec etcd-<LIVE_NODE_NAME> -n kube-system -- etcdctl --cacert /etc/kubernetes/pki/etcd/ca.crt --cert /etc/kubernetes/pki/etcd/peer.crt --key /etc/kubernetes/pki/etcd/peer.key member remove <DEAD_MEMBER_ID>

... добавить новый узел#

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

2. Выполните шаги 2-3 из раздела по развертыванию новой виртуальной машины:

3. Войдите на работающий узел и выполните следующие команды:

  • Создайте токен присоединения:

    kubeadm token create --print-join-command

    В результате выполнения команда выведет master_token и master_discovery_token. Скопируйте их в надежное место.

  • Загрузите сертификаты:

    sudo kubeadm init phase upload-certs --upload-certs

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

4. Действуйте согласно инструкции Шаг 4. Подготовьте localhost.

5. Используйте токены и ключ сертификата, сгенерированные ранее, для добавления нового узла в кластер:

source venv.sh
pip install -r requirements.txt
patch_url='<link-to-patch>'
ca_url='<link-to-ca-image>'
export ANSIBLE_HOST_KEY_CHECKING=False
ansible-playbook -e "ansible_ssh_user=<SSH_USER_NAME>" \
-e "ansible_python_interpreter=/usr/bin/python3" \
-e "lb_address=<LOAD_BALANCER_IP>" \
-e "logstash_host=127.0.0.1" \
-e "master_token=ae9wn..." \
-e "master_discovery_token=bf917..." \
-e "master_cert_key=4cc2c..." \
-e "copy_patch=true" \
-e "copy_ca=true" \
-i "<NEWLY_PROVISIONED_INSTANCE_IP>," \
ansible/k8s-add-node.yaml

Замечания

  • Вместо lb_address укажите адрес балансировщика нагрузки.
  • Вместо master_token, master_discovery_token и master_cert_key укажите токены, которые вы получили ранее. Ознакомьтесь с примером, чтобы проверить формат.
  • После -i установите IP-адрес нового подготовленного экземпляра.