OpenUDS HA

Материал из ALT Linux Wiki
Перейти к навигации Перейти к поиску

HA-кластер с OpenUDS[править]

Компоненты OpenUDS можно настроить в режиме высокой доступности (HA).

Для обеспечения высокой доступности среды VDI, кроме настройки нескольких OpenUDS-Server и OpenUDS-Tunnel, необходимо настроить репликацию базы данных. Также следует настроить балансировщик нагрузки, который будет распределять подключения к компонентам OpenUDS-Server и OpenUDS-Tunnel.

В этом документе приведён пример настройки работы OpenUDS в режиме высокой доступности с программным балансировщиком нагрузки (HAProxy) и базой данных MySQL.

Системные требования[править]

Основные элементы OpenUDS HA

Основные элементы отказоустойчивого решения:

  1. MySQL сервер — база данных является одним из наиболее существенных компонентов среды VDI с OpenUDS. Поэтому настоятельно рекомендуется иметь резервную копию этого компонента, либо посредством полной резервной копии машины, либо посредством конфигурации активной/пассивной реплики. В данном руководстве описана настройка двух серверов MySQL, главного и подчиненного, в режиме активной/пассивной репликации.
  2. HAProxy-сервер — сервер, отвечающий за распределение подключений к OpenUDS-Server и OpenUDS-Tunnel. Через него осуществляется доступ пользователей к OpenUDS и выполняются подключения к различным сервисам. На серверах HAProxy также будет настроен IP-адрес, который будет активен только на основном сервере. В случае отказа основного сервера IP-адрес будет автоматически активирован на другом сервере HAProxy.
  3. OpenUDS Server — наличие нескольких машин OpenUDS-Server обеспечит непрерывный доступ пользователей к OpenUDS, даже при отказе одного из OpenUDS-Server.
  4. OpenUDS Tunnel — наличие нескольких машин OpenUDS-Tunnel позволит получить доступ к службам (рабочим столам или приложениям) через туннелированные соединения и HTML5, даже при отказе одного из OpenUDS-Tunnel.
Примечание: Если пользователь подключается к сервису (рабочему столу или приложению) и сервер OpenUDS-Tunnel, через который он подключен, падает, соединение будет потеряно. Но при повторном подключении доступ будет автоматически восстановлен через другой активный сервер OpenUDS-Tunnel.


Системные требования
Компонент Количество ОЗУ ЦП Диск
MySQL Server 2 1 ГБ 2 vCPUs 10 ГБ
HAProxy 2 1 ГБ 2 vCPUs 10 ГБ
OpenUDS Server 2 2 ГБ 2 vCPUs 8 ГБ
OpenUDS Tunnel 2 2 ГБ 2 vCPUs 10 ГБ
Примечание: Для HAProxy необходимо 3 IP-адреса, по одному для каждого сервера (Master-Slave) и общий виртуальный IP-адрес, который будет использоваться для балансировки.


Конфигурация серверов MySQL[править]

Узел Имя IP-адрес
Основной (Master) mysql01 192.168.0.128
Вторичный (Slave) mysql02 192.168.0.129

На обоих серверах установить MySQL (MariaDB):

# apt-get install mariadb
# systemctl enable --now mariadb.service
# mysql_secure_installation

Настройка репликации между серверами[править]

Главный узел (Master)[править]

В файле /etc/my.cnf.d/server.cnf:

  • закомментировать параметр skip-networking;
  • раскомментировать параметры server-id и log_bin;
  • убедиться, что для параметра server-id установлено значение 1;
  • раскомментировать параметр bind-address и указать IP-адрес сервера (в этом случае главного):
bind-address 192.168.0.128

Перезагрузить службу MySQL:

# systemctl restart mariadb

Создать нового пользователя, с правами которого будет производиться репликация:

  1. Войти в консоль MySQL с правами root:
    $ mysql -p
    
  2. Создать пользователя (в примере пользователь «replica» с паролем «uds»):
    MariaDB [(none)]> CREATE USER 'replica'@'%' IDENTIFIED BY 'uds';
    Query OK, 0 rows affected (0.009 sec)
    
  3. Предоставить права «replication slave» пользователю:
    MariaDB [(none)]> GRANT REPLICATION SLAVE ON *.* TO 'replica'@'%' IDENTIFIED BY 'uds';
    Query OK, 0 rows affected (0.002 sec)
    
  4. Выполнить следующую команду, чтобы получить информацию об имени двоичного файла и его позиции:
    MariaDB [(none)]> SHOW MASTER STATUS\G
    *************************** 1. row ***************************
                File: mysql-bin.000002
            Position: 328
        Binlog_Do_DB:
    Binlog_Ignore_DB:
    1 row in set (0.001 sec)
    

В данном примере:

  • mysql-bin.000002 — имя файла;
  • 328 — позиция.

Эти данные будут необходимы для настройки Slave-сервера.

Примечание: Просмотреть лог можно, выполнив команду:
# mysqlbinlog --no-defaults /var/lib/mysql/db/mysql-bin.000002


Вторичный узел (Slave)[править]

В файле /etc/my.cnf.d/server.cnf:

  • закомментировать параметр skip-networking;
  • раскомментировать параметры log_bin и server-id;
  • в параметре server-id установить значение 2:
server-id = 2
  • раскомментировать параметр bind-address и указать IP-адрес сервера (в этом случае вторичного):
bind-address 192.168.0.129

Перезагрузить службу MySQL:

# systemctl restart mariadb

Настроить параметры, которые вторичный сервер (Slave) будет использовать для подключения к основному серверу (Master):

  1. Войти в консоль MySQL с правами root:
    $ mysql -p
    
  2. Остановить репликацию:
    MariaDB [(none)]> STOP SLAVE;
    Query OK, 0 rows affected, 1 warning (0.001 sec)
    
  3. Настроить репликацию между основным сервером и вторичным сервером:
    MariaDB [(none)]>CHANGE MASTER TO MASTER_HOST='192.168.0.128', MASTER_USER='replica', MASTER_PASSWORD='uds', MASTER_LOG_FILE='mysql-bin.000002', MASTER_LOG_POS=328;
    Query OK, 0 rows affected (0.020 sec)
    
    где
    • 192.168.0.128 — IP-адрес основного сервера;
    • replica — пользователь, с правами которого будет производиться репликация;
    • uds — пароль пользователя replica;
    • myslq-bin.000002 — имя файла полученного на предыдущем шаге;
    • 328 — позиция двоичного файла.
  4. Запустить репликацию:
    MariaDB [(none)]> START SLAVE;
    Query OK, 0 rows affected (0.001 sec)
    
  5. Убедиться, что конфигурация верна:
    MariaDB [(none)]> SHOW SLAVE STATUS\G
    *************************** 1. row ***************************
                    Slave_IO_State: Waiting for master to send event
                       Master_Host: 192.168.0.128
                       Master_User: replica
                       Master_Port: 3306
                     Connect_Retry: 60
                   Master_Log_File: mysql-bin.000004
               Read_Master_Log_Pos: 328
                    Relay_Log_File: mysqld-relay-bin.000006
                     Relay_Log_Pos: 555
             Relay_Master_Log_File: mysql-bin.000004
                  Slave_IO_Running: Yes
                 Slave_SQL_Running: Yes
    
    

IP-адрес основного сервера должен быть указан корректно, параметры Slave_IO_Running и Slave_SQL_Running должны быть установлены в значение «Yes».

Проверка репликации[править]

Для проверки репликации можно создать БД на главном сервере и убедиться, что она автоматически реплицируется на вторичном сервере:

  1. Получить доступ к консоли MySQL главного сервера и создать новую тестовую БД «replicatest»:
    MariaDB [(none)]> CREATE DATABASE replicatest;
    Query OK, 1 row affected (0.001 sec)
    
  2. Убедиться, что БД создана:
    MariaDB [(none)]> SHOW DATABASES;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | replicatest        |
    +--------------------+
    4 rows in set (0.001 sec)
    
  3. Получить доступ к консоли MySQL вторичного сервера и убедиться, что БД, созданная на основном сервере, успешно реплицировалась на этот сервер:
    MariaDB [(none)]> SHOW DATABASES;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | replicatest        |
    +--------------------+
    4 rows in set (0.002 sec)
    
Примечание: После проверки работы репликации можно удалить БД «replicatest», выполнив команду на основном сервере:
MariaDB [(none)]> DROP DATABASE replicatest;


Теперь можно создать на основном сервере БД:

 
mysql> CREATE DATABASE dbuds CHARACTER SET utf8 COLLATE utf8_general_ci;
mysql> CREATE USER 'dbuds'@'%' IDENTIFIED BY 'password';
mysql> GRANT ALL PRIVILEGES ON dbuds.* TO 'dbuds'@'%';
mysql> FLUSH PRIVILEGES;

И подключить серверы OpenUDS к БД основного сервера.

Отказ сервера[править]

При недоступности одного из серверов БД необходимо выполнить ряд задач. Задачи, которые следует выполнить, зависят от того к какому серверу (Master или Slave) нет доступа.

Главный узел (Master)[править]

Если недоступен основной сервер БД (Master), то будет потерян доступ к среде VDI. В этом случае необходимо вручную подключить OpenUDS-Server к вторичной БД (Slave), в которой находится вся информация среды VDI до момента падения основной БД. Чтобы настроить новое подключение к БД на OpenUDS-Server следует в конфигурационном файле /var/server/server/settings.py указать параметры новой БД (это необходимо сделать на всех серверах OpenUDS-Server).

После изменения IP-адреса БД необходимо перезапустить сервер (это необходимо сделать на всех серверах OpenUDS-Server).

После перезапуска сервера доступ к среде VDI будет восстановлен.

Затем необходимо настроить новый сервер для репликации БД.

Для этого есть несколько вариантов, в том числе:

  1. Настроить текущий сервер БД как главный и создать новый сервер-реплику, который нужно настроить и восстановить БД из резервной копии с существующими данными (поскольку реплицируются только новые данные).
  2. Напрямую сделать резервную копию текущего сервера БД (предварительно остановив все машины OpenUDS-Server). Создать новый сервер БД Master, восстановить туда резервную копию БД и перенастроить репликацию.
Примечание: Чтобы не потерять какие-либо данные, перед применением любого метода перестроения репликации, рекомендуется сделать резервную копию БД. Для получения резервной копии можно использовать следующую команду:
# mysqldump -u dbuds -ppassword --databases dbuds > dbuds_dump.sql

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


Вторичный узел (Slave)[править]

Если недоступен вторичный сервер БД (Slave), доступ к среде VDI сохранится, но будет необходимо перенастроить вторичный сервер-реплику. Перед выполнением данной настройки необходимо восстановить резервную копию с текущим состоянием основной БД, так как будут синхронизированы только новые данные реплики (существующие данные не будут реплицированы в базе данных).

Важно, чтобы во время всего этого процесса машины OpenUDS-Server были выключены, чтобы не возникало различий между БД Master и Slave серверов.

Настройка серверов HAProxy[править]

Узел Имя IP-адрес
Основной (Master) Haproxy01 192.168.0.52
Вторичный (Slave) Haproxy02 192.168.0.53

192.168.0.49 — виртуальный IP-адрес по которому будут доступны серверы OpenUDS.

Конфигурация балансировщика нагрузки

В данной конфигурации используется служба Keepalived и виртуальный IP-адрес, общий для главного (Master) и резервного (Slave) узлов. Служба Keepalived связывает виртуальный IP-адрес с главным узлом и отслеживает доступность HAProxy. Если служба обнаруживает, что HAProxy не отвечает, то она связывает виртуальный адрес с вспомогательным узлом, что минимизирует время недоступности сервера. Пользователи при обращении к OpenUDS должны использовать этот виртуальный IP-адрес. Этот же виртуальный IP-адрес следует использовать при регистрации OpenUDS Actor (см. Подготовка шаблона ВМ).

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

На основном узле сгенерировать сертификат:

# openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout /root/ssl.key -out /root/ssl.crt

Создать файл .pem, выполнив команду (предварительно может понадобиться создать каталог /etc/openssl/private):

# cat /root/ssl.crt /root/ssl.key > /etc/openssl/private/haproxy.pem
Примечание: Сертификат, созданный на первичном сервере HAProxy, необходимо скопировать в каталог /etc/openssl/private на вторичном сервере. Если используется собственный сертификат, его необходимо скопировать на оба сервера (основной и дополнительный).


Внимание! Порты, используемые HAProxy (в примере 80, 443, 1443, 10443), должны быть свободны.


На обоих узлах:

  1. Установить пакеты haproxy и keepalived:
    # apt-get install haproxy keepalived
    
  2. Заменить содержимое файла /etc/haproxy/haproxy.cfg следующим:
    global
            log /dev/log    local0
            log /dev/log    local1 notice
            chroot /var/lib/haproxy
            stats socket /var/lib/haproxy/admin.sock mode 660 level admin  
            stats timeout 30s
            maxconn 2048
            user _haproxy
            group _haproxy
            daemon
    
            # Default SSL material locations
    #        ca-base /etc/openssl/certs
    #        crt-base /etc/openssl/private
    
            # Default ciphers to use on SSL-enabled listening sockets.
            # For more information, see ciphers(1SSL). This list is from:
            #  https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
            ssl-default-bind-options ssl-min-ver TLSv1.2 prefer-client-ciphers
    #        ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA267:TLS_AES_267_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA267
            ssl-default-bind-ciphers ECDH+AESGCM:ECDH+CHACHA20:ECDH+AES267:ECDH+AES128:!aNULL:!SHA1:!AESCCM
    
            # ssl-default-server-options ssl-min-ver TLSv1.2
            # ssl-default-server-ciphersuites TLS_AES_128_GCM_SHA267:TLS_AES_267_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA267
            # ssl-default-server-ciphers ECDH+AESGCM:ECDH+CHACHA20:ECDH+AES267:ECDH+AES128:!aNULL:!SHA1:!AESCCM
    
           tune.ssl.default-dh-param 2048
    
    
    defaults
            log     global
            mode    http
            option  httplog
            option  dontlognull
            option  forwardfor
            retries 3
            option  redispatch
    
            stats enable
            stats uri /haproxystats
            stats realm Strictly\ Private
            stats auth stats:haproxystats
    
            timeout connect 5000
            timeout client  50000
            timeout server  50000
    
    frontend http-in
            bind *:80
            mode http
            http-request set-header X-Forwarded-Proto http
            default_backend openuds-backend
    frontend https-in
            bind *:443 ssl crt /etc/openssl/private/haproxy.pem
            mode http
            http-request set-header X-Forwarded-Proto https
            default_backend openuds-backend
    
    frontend tunnel-in
            bind *:1443
            mode tcp
            option tcplog
            default_backend tunnel-backend-ssl
    
    frontend tunnel-in-guacamole    # HTML5
            bind *:10443
            mode tcp
            option tcplog
            default_backend tunnel-backend-guacamole
    backend openuds-backend
            option http-keep-alive
            balance roundrobin
            server udss1 192.168.0.85:80 check inter 2000 rise 2 fall 5
            server udss2 192.168.0.86:80 check inter 2000 rise 2 fall 5
    backend tunnel-backend-ssl
            mode tcp
            option tcplog
            balance roundrobin
            server udst1 192.168.0.87:443 check inter 2000 rise 2 fall 5
            server udst2 192.168.0.88:443 check inter 2000 rise 2 fall 5
    
    backend tunnel-backend-guacamole
            mode tcp
            option tcplog
            balance source
            server udstg1 192.168.0.87:8080 check inter 2000 rise 2 fall 5
            server udstg2 192.168.0.88:8080 check inter 2000 rise 2 fall 5
    
  3. Включить в ядре поддержку двух IP-адресов:
    echo "net.ipv4.ip_nonlocal_bind = 1" >> /etc/sysctl.conf
    # sysctl -p
    
  4. Настроить службу Keepalived. Для этого создать файл /etc/keepalived/keepalived.conf. Содержимое файла зависит от узла, который настраивается:
    • на главном узле:
      global_defs {
          # Keepalived process identifier
          lvs_id haproxy_DH
      }
      # Script used to check if HAProxy is running
      vrrp_script check_haproxy {
          script "killall -0 haproxy"
          interval 2
          weight 2
      }
      # Виртуальный интерфейс
      # The priority specifies the order in which the assigned interface to take over in a failover
      vrrp_instance VI_01 {
          state MASTER
          interface enp0s3
          virtual_router_id 51
          priority 101
          # Виртуальный IP-адрес
          virtual_ipaddress {
              192.168.0.49
          }
          track_script {
              check_haproxy
          }
      }
      
      где enp0s3 — интерфейс, для виртуального IP (узнать имя сетевого интерфейса можно, выполнив команду ip a).
    • на вторичном узле:
      global_defs {
          # Keepalived process identifier
          lvs_id haproxy_DH_passive
      }
      # Script used to check if HAProxy is running
      vrrp_script check_haproxy {
          script "killall -0 haproxy"
          interval 2
          weight 2
      }
      # Виртуальный интерфейс
      # The priority specifies the order in which the assigned interface to take over in a failover
      vrrp_instance VI_01 {
          state SLAVE
          interface eth0
          virtual_router_id 51
          priority 100
          # Виртуальный IP-адрес
          virtual_ipaddress {
              192.168.0.49
          }
          track_script {
              check_haproxy
          }
      }
      
      где eth0 — интерфейс, для виртуального IP (узнать имя сетевого интерфейса можно, выполнив команду ip a).
  5. Для запуска сервисов выполнить команды:
    # systemctl enable --now haproxy 
    # systemctl enable --now keepalived
    
  6. Убедиться, что балансирующий виртуальный IP активен на основном сервере:
    $ ip a |grep enp0s3
    2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
        inet 192.168.0.52/24 brd 192.168.0.255 scope global noprefixroute enp0s3
        inet 192.168.0.49/32 scope global enp0s3
    

Настройка OpenUDS[править]

После настройки серверов MySQL и HAProxy можно приступить к установке и настройке компонентов OpenUDS-Server и OpenUDS-Tunnel.

Настройка OpenUDS-Server[править]

Узел Имя IP-адрес
Основной (Master) udss01 192.168.0.85
Вторичный (Slave) udss02 192.168.0.86

На обоих узлах OpenUDS-Server:

  1. Установить OpenUDS Server:
    # apt-get install openuds-server-nginx
    
  2. Отредактировать /etc/openuds/settings.py, указав корректные данные для подключения к основному MySQL-серверу:
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql', 
            'OPTIONS': {
                'isolation_level': 'read committed',
            },
            'NAME': 'dbuds',  # Or path to database file if using sqlite3.
            'USER': 'dbuds',  # Not used with sqlite3.
            'PASSWORD': 'password',  # Not used with sqlite3.
            'HOST': '192.168.0.128',  # Set to empty string for localhost. Not used with sqlite3.
            'PORT': '3306',  # Set to empty string for default. Not used with sqlite3.
        }
    }
    
  3. "Заполнить" базу данных первоначальными данными (выполнить только на одном узле!):
    # su -s /bin/bash - openuds
    $ cd /usr/share/openuds
    $ python3 manage.py migrate
    $ exit
    
  4. Запустить gunicorn:
     # systemctl enable --now openuds-web.service
    
  5. Запустить nginx:
     # ln -s ../sites-available.d/openuds.conf /etc/nginx/sites-enabled.d/openuds.conf
     # systemctl enable --now nginx.service
    
  6. Запустить менеджер задач OpenUDS:
     # systemctl enable --now openuds-taskmanager.service
    
  7. Подключиться к серверу OpenUDS http://<Виртуальный IP-адрес> (в примере http://192.168.0.49).

Настройка OpenUDS-Tunnel[править]

Узел Имя IP-адрес
Основной (Master) udst01 192.168.0.87
Вторичный (Slave) udst02 192.168.0.88

На обоих узлах OpenUDS-Tunnel:

  1. Установить OpenUDS Tunnel:
    # apt-get install openuds-tunnel
    
  2. Привести файл /etc/uds.conf к виду:
     http://192.168.0.49/pam
    
    где 192.168.0.49 — виртуальный IP-адрес.
  3. Переименовать каталог /var/lib/tomcat/webapps/openuds-tunnel в /var/lib/tomcat/webapps/transport:
    # mv /var/lib/tomcat/webapps/openuds-tunnel /var/lib/tomcat/webapps/transport
    
  4. Запустить сервисы:
    # systemctl enable --now guacd tomcat
    


Внимание! Т.к. tomcat по умолчанию работает на порту 8080, то перед запуском tomcat необходимо, либо остановить службу ahttpd:
# systemctl disable --now ahttpd

Либо изменить порт 8080 на другой допустимый номер порта в файле /etc/tomcat/server.xml:

<Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />


Примечание: При создании транспорта «HTML5 RDP (tunneled)» в поле «Tunnel Server» следует указывать виртуальный IP-адрес и порт, указанный в разделе frontend tunnel-in-guacamole файла /etc/haproxy/haproxy.cfg (в данном примере: 10443):

OpenUDS. HTML5 RDP — вкладка «Tunnel»

Пример подключения с использованием HTML5:

OpenUDS. Пример подключения с использованием HTML5