вторник, 16 октября 2018 г.

Публикация Azure SQL Database Managed Instance на внешнем IP

Официально, Azure SQL Database Managed Instance поддерживает подключения только по внутреннему IP адресу. Но у меня появилась задача, где потребовалось обеспечить доступ через внешний IP. При этом вариант с использованием сервиса Azure SQL Databases нам не подходил. Почему - вопрос отдельный. Есть задача, значит надо решать. Поехали!



В документации по Azure SQL Database Managed Instance предлагается использовать два варианта подключения к сервису:

1. Network peering

2. VPN / Express Route



По данной схеме, которую я взял из официальной документации, мы видим,  что работа с нашим SQL Managed Instance возможна только из внутренней сети. Внешний IP, который есть в левой части изображения, принадлежит виртуальной машине с установленной SQL Server Management Studio (SSMS).

У меня появилась задача, для которой потребовалось обеспечить доступ к базам данных, расположенных в Azure SQL Database Managed Instance, через внешний IP адрес. Единственная возможность это обеспечить - настроить NAT. Изначально я попробовал сделать это с помощью Azure Load Balancer. Но, к сожалению, работать с Azure SQL Database Managed Instance его пока не научили. Указать произвольный IP адрес в качестве эндпоинта в нём нельзя.

Ничего страшного, мы построим свой лунапарк! Для этого создадим отдельную виртуальную машину и выполним проброс порта 1433 с помощью haproxy.

1. Создадим Subnet в той же VNet, где у нас находится Azure SQL Database Managed Instance.

2. Создадим VM Linux Centos (я для своего PoC использовал версию 6.9), сетевой интерфейс должен использовать подсеть, которую мы создали в п.1. Так же она должна иметь внешний IP адрес.

3. Когда машина создана, подключаемся к ней по SSH и устанавливаем haproxy:

sudo yum -y install haproxy

4. Редактируем файл /etc/haproxy/haproxy.cfg (например, с помощью vi, vim или nano):

sudo vim /etc/haproxy/haproxy.cfg 

Базовый пример конфига:

global
    log         127.0.0.1 local2
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon
    stats socket /var/lib/haproxy/stats

defaults
    mode                    tcp
    log                     global
    option                  dontlognull
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000

frontend tcp-in-mssql
  bind :1433
  mode tcp
  option tcplog
  use_backend mssql

backend mssql
  mode tcp
server mssqlserver sqlmi02.d3e136377b44.database.windows.net:1433 check

5. Запускаем сервис haproxy:

sudo service haproxy start

6. Если для ВМ или подсети есть NSG, не забываем добавить в него правило для входящих подключений на порт 1433.

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

sqlmi02.d3e136377b44.database.windows.net



Данное имя отлично резолвится на внешних DNS. Но, правда, во внутренний IP адрес :) Единственный вариант, который я нашел - поправить файл hosts на клиенте:

Windows - C:\Windows\System32\Drivers\etc\hosts

Linux - \etc\hosts

В него добавить запись вида:

Внешний_IP DNS_имя_SqlDbMi

Например:

40.122.106.101 sqlmi02.d3e136377b44.database.windows.net

Если данный вариант вам подходит, то все должно работать корректно. При необходимости можно создать дополнительную виртуальную машину и использовать балансировку, например, с помощью Azure Traffic Manager. Тогда данное решение станет ещё и отказоустойчивым.

К сожалению, мне этот вариант не подошел, поэтому я протестировал решение только на PoC. Выглядит оно полностью работоспособным, но подойдёт ли оно для прода - без понятия.

На этом всё, как всегда, вопросы можете задавать в комментариях. 

Комментариев нет:

Отправить комментарий