Публикация 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. Выглядит оно полностью работоспособным, но подойдёт ли оно для прода - без понятия.
На этом всё, как всегда, вопросы можете задавать в комментариях.
Комментариев нет:
Отправить комментарий