Azure MySQL Flexible Server 内网 DNS 集成方案

1. 前言

最近一直在和客户聊云上资源迁移的相关事宜,借着客户的需求测试了一下 Azure MySQL Flexible Server ( 后文简称 MySQLFS ) 集成 Custom DNS 的场景,其实官方文档是有一些说明的,不过为了使方案更直观,还是记录下来方便以后查询,包括其中遇到的“坑”。


2. 需求背景介绍

客户原本用的是 Azure MySQL Single Server,现要迁移 MySQLFS,由于 MySQLFS 的网络集成模型和 Single Server 有一些区别,所以在迁移的过程中顺便改造成更安全的内网集成方案。与之前不同的是,MySQLFS 支持 VNet integration 这种 Private access 网络集成方式,这种方式可以让 Azure MySQL 实例只拥有一个 Private IP,以 VNet Injection 的方式集成到 VNet 中,具体的网络部署模型可以参考以下这张图:

需求是在 VNet Peering 互联的前提下,能否在对端 VNet 中的 MySQL Client 使用 Custom DNS 配置来成功访问 VNet Integration MySQLFS,那答案肯定是可以的,不然这篇 Blog 也就没有存在的意义了,好了废话不多说了,直接开搞。


3. Azure MySQL Flexible Server 内网集成 Custom DNS 测试

具体的测试环境如下图所示:

简单介绍下架构: VNet1 和 VNet2 通过 VNet Peering 打通,分别划分两个 Subnet for DNS Server 和 MySQLFS 实例,每个 Subnet 分别挂 NSG,每个 VNet 有 Custom DNS Server,对应 vnet1-vmsn1-dns1 10.11.1.4vnet2-vmsn1-dns1 10.12.1.4,系统使用 CentOS 7.9,Custom Domain 为 example.com,所有资源都部署在 EastUS 进行测试,具体信息如以下几张图所示:

接下来我们来测试两个场景:
1. 启用 Private Access Azure MySQLFS 实例在对端 VNet Peering Client 进行访问;
2. 使用自定义域名访问 Private Access Azure MySQLFS 实例;

3.1 启用 Private Access Azure MySQLFS 实例在对端 VNet Peering Client 进行访问

首先先创建一个 Azure MySQLFS Private 实例,Azure 默认给实例分配的内网地址为 10.12.2.4( DB Subnet 第一个内网地址 ),同样地,Azure 也会给实例分配一个 Private DNS Zone,本实验采用创建实例时 Azure 默认分配的 Zone:vnet2-dbsn1-mysqlfs1.private.mysql.database.azure.com。 其实本质上,Azure 也是通过域名解析来集成 MySQLFS 内网服务的,当创建好实例之后,就会在域名解析服务中增加一条 A Record,如下图所示:

此实例的 Server Name 前缀名为:vnet2-dbsn1-mysqlfs1,部署在 VNet2 DB Subnet 中,也就是说和 vnet2-vmsn1-dns1 所处在一个 VNet 中。再不考虑 NSG 的前提条件下( 也就是说同 VNet 流量出入都放行 ),Client 直接就可以解析 Azure MySQLFS 的域名了。那下一个问题可能又来了,Azure MySQLFS 本身有一个 FQDN,那和这个 Private 域名有什么关系呢?我们来验证一下:

通过 nslookup 的解析结果能看到,默认的 FQDN:vnet2-dbsn1-mysqlfs1.mysql.database.azure.com 是一个 CNAME 指向了 Azure MySQLFS 的内网域名上:vnet2-dbsn1-mysqlfs1.vnet2-dbsn1-mysqlfs1.private.mysql.database.azure.com,然后内网域名在 Azure Private DNS Zone 有一条 A 记录解析到了实际的内网地址 10.12.2.4。那启用了 VNet Peering 的对端 Client 的解析结果又如何呢?在 vnet1-vmsn1-dns1 10.11.1.4 上测试下:

很明显,只做了 VNet Peering 的对端 Client 没法直接解析,究其原因是对端 Client 并不知道 private zone 是什么,所以需要将 VNet1vnet2-dbsn1-mysqlfs1.private.mysql.database.azure.com Link 起来,VNet Peering 对端的 Client 就可以和 VNet2 内一样解析了。

同理,也就明白了为什么 VNet2 默认就可以解析,也是因为 Azure 在创建 Private DNS Zone 的同时加了一条 VNet2 Link,如图标红出所示。

3.2 使用自定义域名访问 Private Access Azure MySQLFS 实例

3.1 我们验证了使用默认的 Azure DNS Domain 来进行 Azure MySQLFS 的内网访问,那如果使用 Custom Domain 比如 example.com 是否可以做集成呢?答案也是可以的,主要验证在对端 Peering VNet 使用 Custom DNS Server 的集成情况。首先在 vnet1-vmsn1-dns1 10.11.1.4 上部署 DNS Server Linux Bind。Bind 就不多做介绍了,很经典的 Linux DNS Server Solution,部署过程不赘述了,不了解的同学们自行 Google 吧。重点主要在 3 个配置文件的配置上:

1. /etc/named.conf

DNS Forwarders 需要转发给 Azure Default DNS:168.63.129.16。

2. /etc/resolv.conf

系统 DNS Resolve File 要 search example.com domain 以及修改 nameserver 为 Local DNS Server 地址 10.11.1.4。

3. /var/named/example.com.zone

正向解析文件 example.com.zone 需要加一条 CNAME Record,如上图标红框所示。在 3.1 的基础上,可以直接通过 Custom Domain 的内网域名来做测试了:

能够看出来,自定义域名 vnet2-dbsn1-mysqlfs1.example.com CNAME 指向了 Azure MySQLFS FQDN,然后 FQDN CNAME 指向了最终的内网域名 vnet2-dbsn1-mysqlfs1.private.mysql.database.azure.com 并最终解析成内网地址 10.12.2.4。


4. 总结

至此,Azure MySQLFS 内网集成的两个场景就测试完毕了,其实大家应该能够感觉到 VNet Injection 这种网络模型其实基本上就是 VNet 里面的 VM,只是封装了一层变成 PaaS 服务暴露给用户,所以这么看的话大家是不是也知道网络层面的管控可以怎么做了?没错,就可以当作 VM 一样,通过 NSG 来限制出入口流量,这个测试下来也是没问题的,不过本篇就不做详细测试了,有需求的同学自己来做测试吧。最后再稍微提几个注意事项给到大家:

1. 关于 Read Replica


创建了两个只读副本,和 Master 一样,Azure 会根据 DHCP 继续向下分配内网地址给到只读副本,然后生成 A Record 解析。

2. 关于访问方式
和研发和后台支持的同学们聊下来,无论是使用 FQDN 亦或 Custom DNS Domain Name,都强烈不建议使用内网 IP 来访问实例,在进行一些平台层面的维护或者启用 HA 的实例,都会发生 IP Floating,所以生产环境一定要用域名。

3. 关于数据迁移
Azure DMS Service 针对 SingleServer - Flexbile Server 又推出了一个 online 的迁移方式,本来 online 这个功能都下线了,可能是为了方便客户做迁移,单独针对 MySQLFS 上线了,这个功能在这里提一句,后面我们也测试看看实际效果怎么样。

4. 域名解析
以 VNet Injection 方式嵌入的 Azure MySQLFS 在域名解析上和其他云厂商有些许不同,经过测试发现非 VNet 环境是无法解析 MySQLFS 的内网域名的,像 AWS RDS 就不一样了,是可以在公网解析的,解析成 Private IP,只是无法访问罢了。

暂时就能想到这些,先写这么多给大家参考吧,后面有啥补充我再查缺补漏,谢谢大家。