一句话简述问题
AWS RDS 服务并没有官方提供 private link 的链接通路,需要手动配置。
方案设计
如图所示,需要申请规划
- VPC、Subnet、Security Group
- RDS-MySQL
- Proxy
- NLB
- Private Link Service
最后通过在需要访问 RDS-MySQL 的 VPC 中申请 Endpoint,从而打通网络。
- 为什么引入NLB
Private link service 申请需要绑定一个 NLB 来实现。 - 为什么需要引入Proxy?
RDS MySQL 暴露的链接串是 DNS 链路,绑定的实际的后端的 ip 是会因为主备倒换等发生不可控的改变,我们必须确定到具体的 ip,保证 nlb 挂在的后端 ip 正确。
Proxy 会在每个 az 的 subnet 拉起进程,其 ip 会保持不变。引入 Proxy,将 Proxy 的 ip 作为 NLB 的后端 ip。
PS:其实 Proxy 本质上也使用了 Privatelink Service,但是这个由 RDS 服务托管,不允许用户私自建立 endpoint 进行链接。
AWS 手动验证方案步骤
账号准备
这边需要准备两个AWS账号。
- 每个账户一个 VPC,其中有 2 个公有/私有子网。
- 每个账户(公共子网)中有一个 EC2 实例,用于测试访问
VPC、subnet规划
两个账号都新建一个VPC,其中包含两个子网
新建安全组
在service端账号的VPC下创建两个安全组,一个名为sgEC2,另一个名为sgRDS。
- 对于sgEC2组,允许来自某些 IP 的 SSH,例如来自工作/家庭的 IP。我们将创建的 EC2 实例将位于公共子网中。
- 对于sgRDS组,允许来自sgEC2组的实际子网 ID 的端口 3306 (MySQL) 和另一个规则以允许从其自身访问 3306。这就是sgRDS规则的样子。
现在,对consumer端帐户执行相同的操作,但只创建sgEC2组。
- sgEC2:
- sgRDS:
新建EC2
在两个账号都创建一台EC2。
- 挂载在公网subnet下,且需要绑定公网ip,用于登录验证使用。
- 登录时证书权限需要缩小。如下操作即可
申请RDS MySQL
选择私网子网,不激活公网且安全组绑定 sgRDS 即可。
Test:登录 EC2,测试直接连接 RDS 的 DNS 地址能够正常登录
mysql -h${link} -u${root} -p${pws}
申请RDS PROXY
申请RDS PROXY的时候需要选择一个secert。这个secert的账号密码需要和RDS MYSQL的保持一致。
创建新的secert时候,需要创建一个KMS KEY,类型选择默认即可
RDS PROXY 需要一个新建一个 IAM ROLE,托管给 RDS 服务使用,这个 ROLE 需要绑定刚才新建的 secert 还有 KMS KEY 的相关使用权限,并且允许 RDS 进行 assume token。这边注意 AWS RDS console 的一个 bug。console 选择新建一个 ROLE 时候,授予的 KMS KEY 权限相关的 ARN 是错误的。需要在 IAM 管理平台手动修正!!
Test:登录 EC2,测试直接连接 RDS PROXY 的地址能够正常登录
新建NLB
在 EC2 通过 nslookup 命令查询 RDS PROXY 对应的 ip 地址。
新建 NLB 时候需要注意选择内部子网,且在测试链接之前需要确认 sgRDS 安全组是否允许这两个内部子网访问 RDS 数据库。
Test:登录 EC2,测试直接连接 NLB 的地址能够正常登录
创建private link
- 创建endpoint service
选择 Network 类型,绑定上面创建的 NLB - 创建endpoint
在对应 VPC 的公网 subent 创建 endpoint,并且绑定 sgECS 的安全组。确保放开 sgECS 对于公网 subnet 对于 3306 端口的访问。
Endpoint service 记得接受建立链接 - 测试
登录EC2,测试直接连接engpoint service的地址能够正常登录
对于MetaDB Privatelink 自动化接受认证
- acceptanceRequired = false
无需认证直接接受。可以配合允许访问的 arn 限定范围配合使用 - acceptanceRequired = true
需要手动调用 aws api,通过 Endpoint ID 捞取待验证的链接,自动进行验证。