Skip to content

PrivateLink互联VPC

  • 文档日期: 2025/12/9
  • 文档难度: 中级
  • 预计完成时间: 30-45 分钟
  • 适用环境: AWS 生产/测试环境,跨账户场景

在两个 VPC 存在 CIDR 网段重叠的情况下,通过 AWS PrivateLink 建立私有连接,使消费者账户中的 EC2 实例能够访问提供者账户中的 RDS for MySQL 数据库。


本方案适用于以下场景:

  • 网段冲突:两个 VPC 使用相同或重叠的 CIDR(如都使用 10.0.0.0/16),无法通过 VPC Peering 或 Transit Gateway 互联
  • RDS 公网访问限制:RDS 的”公开访问”选项仅在创建时可设置,创建后无法修改。若初始未启用,则无法通过公网直接访问
  • 安全合规要求:流量全程在 AWS 骨干网内传输,不经过公网

  • 两个 AWS 账户(提供者账户 + 消费者账户)
  • 提供者账户已部署 RDS for MySQL 实例(位于私有子网)
  • 消费者账户已部署 EC2 实例(用于测试连接)
  • 双方账户具有 VPC、EC2、RDS 相关 IAM 权限

[架构总览图]

%%{init: {"flowchart": {"defaultRenderer": "elk"}} }%%
flowchart LR
    subgraph Consumer["消费者账户 (10.0.0.0/16)"]
        EC2[EC2 实例]
        VPCe[Interface Endpoint<br/>私有 IP]
    end
    
    subgraph Provider["提供者账户 (10.0.0.0/16)"]
        NLB[Network Load Balancer]
        ES[Endpoint Service]
        RDS[(RDS MySQL<br/>私有子网)]
    end
    
    EC2 --> VPCe
    VPCe -.->|AWS 骨干网| ES
    ES --> NLB
    NLB --> RDS

PrivateLink 通过在消费者 VPC 创建本地 ENI 的方式,完全绕过 CIDR 路由问题。流量始终保持在 AWS 内部网络。


转到EC2控制台 -> 负载平衡 -> 目标群组

由于 RDS 不支持直接注册为目标,需使用 IP 类型目标组:

配置项设置值
目标类型IP addresses
协议TCP
端口3306
VPCRDS 所在 VPC
健康检查协议TCP

创建目标组 设置目标组RDS IP 设置目标组

获取 RDS 私有 IP 地址:

方法1:通过通VPC内的EC2命令,解析RDS的实例地址

Section titled “方法1:通过通VPC内的EC2命令,解析RDS的实例地址”

在 RDS 控制台查看集群的 Cluster endpoint(如 mydb-cluster.cluster-xxxx.region.rds.amazonaws.com),然后通过 DNS 解析获取 IP。VPC 内的任意 EC2 上执行:

nslookup mydb-cluster.cluster-xxxx.region.rds.amazonaws.com
# 或者
dig +short mydb-cluster.cluster-xxxx.region.rds.amazonaws.com

RDS

  1. 确认RDS的写实例所在的可用区为ap-east-1a
  2. 进入EC2控制台->网络与安全->网络接口;在筛选框中输入RDS的安全组名称,进行名称过滤;
    1. 筛选安全组
  3. 找到与写实例相同且接口类型为弹性网络接口(描述为RDSNetworkInterface),即可找到写实例的内网IP
    1. 查找写实例内网IP

RDS 实例位于私有子网,需通过 NLB 将其暴露给 PrivateLink。

EC2 控制台 > 负载均衡器 中操作:

配置项设置值
类型Network Load Balancer
方案Internal(内部)
可用区选择 RDS 所在的可用区(至少 2 个)
监听器端口3306(MySQL 默认端口)

NLB创建1 NLB创建2 NLB创建3 审核NLB

VPC 控制台 > PrivateLink 和 Lattice> 终端节点服务 中操作:

配置项设置值
负载均衡器选择上一步创建的 NLB
接受所需是(推荐,需手动接受连接请求)

创建完成后,记录服务名称(格式:com.amazonaws.vpce.region.vpce-svc-xxx)。

终端节点服务设置1 终端节点服务设置2 记录服务名称

在终端节点服务的允许的委托人选项卡中,添加消费者(账户B)账户:

添加委托人

添加委托人ID

arn:aws:iam::账号B的ID:root

VPC 控制台 > PrivateLink 和 Lattice > 终端节点 中创建:

配置项设置值
类型选择 Endpoint services that use NLBs and GWLBs
服务名称输入提供者(账号A)的服务名称,并验证
VPC选择 EC2 实例所在 VPC
子网选择 EC2 可访问的子网(建议多 AZ)
安全组允许出站 TCP 3306

终端节点配置1 终端节点配置2 等待接受

提供者(账户A)需在终端节点服务的终端节点连接选项卡中接受连接请求。

接受终端节点连接请求

确认接受


从消费者账户的 EC2 实例,通过 Endpoint DNS 连接 RDS MySQL:

%%{init: {"flowchart": {"defaultRenderer": "elk"}} }%%
flowchart LR
    A[EC2 实例] -->|mysql -h endpoint-dns -P 3306| B[vpce-xxx.vpce-svc-xxx.region.vpce.amazonaws.com]
    B -->|解析为本地 ENI IP| C[10.0.x.x]
    C -->|PrivateLink| D[(RDS MySQL)]

测试步骤

终端节点DNS

  1. SSH 登录消费者(账户B)的 EC2 实例
  2. 使用当前账户的 ` 的 DNS 名称连接 MySQL:
    mysql -h vpce-xxx.vpce-svc-xxx.region.vpce.amazonaws.com -P 3306 -u admin -p
  3. 连接成功即表示配置完成

连接成功

验证要点

  • Endpoint 状态显示为 available
  • EC2 安全组允许出站 TCP 3306
  • NLB 安全组允许来自 Endpoint ENI 的入站流量
  • RDS 安全组允许来自 NLB 的入站流量
  • NLB 目标组健康检查通过

  1. 账号B创建复制实例
    1. 创建复制实例
  2. 创建源端点。服务器名称为账号B的VPC终端节点的DNS名称
    1. 创建源端点
  3. 测试连接
    1. 测试源端点连接

根据 AWS PrivateLink 定价

计费项费率(以 us-east-1 为例)
Endpoint 小时费$0.01/AZ/小时
数据处理费$0.01/GB(首 1PB)
Endpoint Service 小时费$0.01/AZ/小时

最佳实践:仅在必要的可用区创建 Endpoint,避免不必要的多 AZ 部署。


Q: 连接 MySQL 报错 “Host is blocked because of many connection errors”?

A: 这是 MySQL 安全机制,NLB 的 IP 因多次连接失败被临时封禁。在提供者账户连接 RDS 执行:

FLUSH HOSTS;

或 MySQL 8.0+ 执行:

TRUNCATE TABLE performance_schema.host_cache;

Q: Endpoint 状态一直是 pendingAcceptance?
A: 提供者账户需要手动接受连接请求,或将接受设置改为自动。

Q: 连接建立后无法访问 RDS?
A: 依次检查:EC2 安全组出站规则 → NLB 安全组入站规则 → 目标组健康状态 → RDS 安全组入站规则。

Q: RDS 故障转移后连接中断?
A: RDS 故障转移可能导致 IP 变化。建议使用 Lambda 函数定期检测并更新 NLB 目标组中的 IP 地址。

Q: 是否支持双向通信?
A: 不支持。PrivateLink 仅支持消费者发起的单向连接。

Q: 为什么不直接开启 RDS 公网访问?
A: RDS 的”公开访问”选项仅在实例创建时可设置,创建后无法修改。若初始未启用,PrivateLink 是实现跨账户/跨区域访问的有效方案。