在 AWS 账户之间通过 AWS PrivateLink、网络负载均衡器和 Amazon RDS 代理访问 Amazon RDS

关键点

使用 AWS PrivateLink 和网络负载均衡器,可实现跨账户安全访问 Amazon RDS 数据库实例。Amazon RDS 代理提升了应用程序的可扩展性和容错能力。Lambda 函数自动处理跨账户的 IP 地址注册。

本文将介绍如何通过 AWS PrivateLink、网络负载均衡器NLB和 Amazon RDS 代理,在不同 AWS 账户的应用程序之间安全且高效地连接 RDS 数据库实例或 Aurora 集群。我们将讨论 Amazon RDS 代理的优势,以及如何使用它来提高应用程序的可用性和故障恢复时间。

解决方案概览

以下图示展示了解决方案的高层架构:

在本解决方案中,我们利用 PrivateLink、NLB 和 RDS 代理实现数据库账户中的 RDS 实例的跨账户访问。设置此架构的高层步骤如下:

创建一个 Aurora 集群或 RDS 数据库,并将 RDS 代理与其相应的端点关联。使用 Lambda 函数获取 RDS 代理端点的对应 IP 地址,并将其注册到 NLB 目标组中。创建一个 VPC 端点服务,通过 PrivateLink 以实现跨账户访问。

我们提供了一个 AWS CloudFormation 模板来实现这些步骤,并设置数据库账户中所需的网络基础设施。

先决条件

为了表示跨账户环境,我们使用两个 AWS 账户:

数据库账户:包含 RDS 代理、NLB 和 PrivateLink 的账户应用程序账户:测试对数据库账户进行跨账户访问的账户

您可以在下面的部分使用提供的 CloudFormation 模板来设置数据库账户的基础设施。有关注意事项,请参考 服务端点和配额。

在这篇文章中,我们将使用 Amazon Aurora PostgreSQL 兼容版。RDS 代理还支持 Amazon Aurora MySQL 兼容版、Amazon RDS for MySQL、Amazon RDS for PostgreSQL 和 Amazon RDS for MariaDB,这意味着这个解决方案适合运行在 Amazon RDS 或 Aurora 上的 MySQL 和 PostgreSQL 引擎。有关支持的版本的更多信息,请参考相应的 Aurora 版本。

使用 AWS CloudFormation 设置基础设施

您可以使用以下 CloudFormation 模板 部署基础设施。该模板在数据库账户中部署解决方案所需的以下资源:

网络资源:带有两个私有子网的 VPC 和安全组数据库资源:一个带有两个实例读实例和写实例的 Aurora 数据库集群,RDS 代理,以及与 AWS Secrets Manager 的集成来管理数据库凭证VPC 端点:一个弹性负载均衡接口端点和 Amazon 简单存储服务 (Amazon S3) 网关端点NLB:带有其目标组和侦听器的网络负载均衡器Lambda 函数:用于将 RDS 代理端点中的 IP 地址注册到 NLB 目标组的函数PrivateLink 端点:允许来自应用程序账户的跨账户访问的 PrivateLink 端点服务

模板部署完成后,访问 Amazon RDS 控制台以确认 RDS 数据库已创建成功。如果您使用了默认的模板参数,数据库引擎将是 Amazon Aurora PostgreSQL,并且将包含在本模板中创建的私有 VPC 中的两个 MultiAZ 实例读实例和写实例。

在 RDS 代理控制台中,您可以观察到它与 RDS 实例位于相同的 VPC 和子网中。

最后,您可以观察到 RDS 代理目标组已与之前的数据库关联,并且身份验证已与 Secrets Manager 集成。

将 RDS 代理端点 IP 地址注册到 NLB 目标组

为了实现这个方案,我们使用 PrivateLink 连接到网络负载均衡器启用跨账户访问。由于 NLB 目标组仅接受 IP 地址,而 RDS 代理端点具有相关联的 DNS 名称,因此我们需要获取端点的相应 IP 地址。

我们使用 Lambda 函数获取这些 IP 地址每个 RDS 代理所在的子网一个 IP。该函数的高层步骤如下:

从 RDS 代理端点获取 IP 地址。将 IP 地址注册到 NLB 目标组。

由于 RDS 代理端点名称是不可变的,因此在首次部署 CloudFormation 模板或模板发生任何更改时,将运行此函数。为此,我们使用 Lambda 支持的自定义资源,确保函数在自定义资源被创建、更新或删除时被调用。

在 Amazon EC2 控制台的 负载均衡器 中,观察 NLB 目标组是否成功创建。在所创建的 NLB 的 侦听器 标签中,确认端口和协议是否正确,确保与您选择的数据库引擎相符例如,对于 PostgreSQL,应该是 TCP 协议和 5432 端口。选择 转发到目标组 下 NLB 目标组的链接。

在 目标组 页面中,注意到 RDS 代理端点 IP 地址已作为 NLB 目标注册使用您选择的引擎相应的端口。您还可以检查这些目标的健康状态。有关更多信息,请参考 为您的网络负载均衡器创建目标组 和 目标组的健康检查。

创建 PrivateLink 端点服务

在数据库账户中执行的最后一步是创建一个 PrivateLink 端点服务,以允许应用程序账户进行访问。在配置此端点服务时,请考虑以下事项:

端点服务需要负载均衡器,以接受来自服务消费者的请求并将其路由到您的服务。在这种情况下,您可以使用前一步创建的 NLB 创建端点服务。有关更多信息,请参考 创建端点服务。您可以允许特定 AWS 主体创建 VPC 接口端点来连接到您的端点服务。在这种情况下,应用程序 AWS 账户即为主体。不过,您可以将访问权限缩小到应用程序账户中的特定角色或用户。有关更多信息,请参考 管理权限。您可以配置端点服务以自动或手动接受连接请求。在这种情况下,端点服务将自动接受连接。有关如何配置手动批准的更多信息,请参考 接受或拒绝连接请求。

在 Amazon VPC 控制台的 端点服务 页面上,确认端点服务的负载均衡器是正确的。如果您按照云形成模板的 VPC 和子网配置,端点服务将关联到两个位于不同可用区的负载均衡器。

在验证端点服务的配置后,您可以开始测试对数据库账户的跨账户访问。在进入应用程序账户之前,请记下端点服务名称和位于 Secrets Manager 的数据库凭证。

创建 VPC 端点

在应用程序账户中,在测试从实例连接数据库之前,我们需要创建一个 VPC 端点。

在 Amazon VPC 控制台中,在导航窗格中选择 端点。选择 创建端点。在 端点设置 中,输入一个名称例如 CrossAccountRDSEndpoint。在 服务类别 中,选择 其他端点服务。在 服务设置 中,复制从数据库账户创建的 VPC 端点服务名称并验证该服务。在 VPC 中,选择您在应用程序账户的前一个实例中使用的 VPC。确保至少选择两个子网。在 安全组 中,选择先前为实例选择的两个安全组。验证您的设置并选择 创建端点。

等待端点状态从 待处理 更改为 可用。

如果在数据库账户中创建端点服务时选择了手动批准流程,您需要接受来自数据库账户的端点连接请求。VPC 端点状态变为 可用 可能需要几秒钟。

请注意 VPC 端点的 DNS 名称,这是用于从 PostgreSQL 客户端建立连接的主机名。

创建应用程序实例

测试跨账户连接需要在应用程序账户中配置客户端。为了实现这一目标,您可以在与数据库账户中部署的资源相同的 AWS 区域中,在 AWS Cloud9 中 创建环境。或者,也可以从 EC2 实例测试连接。

您必须使用与 VPC 端点和实例相同的 VPC。此外,将 Cloud9 EC2 实例的安全组配置修改为包含所选 VPC 的默认安全组。为此,在 Amazon EC2 控制台中,打开相应的 Cloud9 EC2 实例详细信息页面并根据下面的截图修改安全组配置。

使用 AWS PrivateLink、网络负载均衡器和 Amazon RDS Proxy 在 AWS

安装 PostgreSQL 客户端

现在您可以按照本节所述的过程配置 PostgreSQL 客户端。

在本文中,我们将描述如何在 Cloud9 环境中快速创建和配置 PostgreSQL 客户端,以演示跨账户连接到数据库的能力。您也可以选择在客户端 EC2 实例或您的应用程序中测试连接。

有关详细信息,请参阅 创建和连接 PostgreSQL 数据库实例。

连接 Cloud9 环境 并更新所有安装包到配置的 yum 存储库中可用的最新版本:

bash sudo yum update

请等待 yum 完成系统更新,这可能需要显式确认和一些时间才能完成。

将 PostgreSQL 14 存储库添加到 yum 配置中:

bash sudo tee /etc/yumreposd/pgdgrepoltltEOF[pgdg14]name=PostgreSQL 14 for RHEL/CentOS 7 x8664baseurl=https//downloadpostgresqlorg/pub/repos/yum/14/redhat/rhel7x8664enabled=1gpgcheck=0EOF

添加 PostgreSQL 14 存储库后再次运行 yum update 命令:

bash sudo yum update

安装 PostgreSQL 14 客户端:

bash sudo yum install postgresql14

检查 psql 客户端是否按预期工作:

bash psql Vpsql (PostgreSQL) 149

从应用程序实例测试连接

完成 PostgreSQL 客户端安装后,在测试连接之前,请确保您拥有以下信息:

数据库密码 您可以在数据库账户的 Secrets Manager 控制台中检索其值。秘密名称前缀是 AuroraSecret。

数据库用户 如果您没有修改原始的 CloudFormation 模板,则用户将是 sampleuser。应用程序账户的 VPC 端点 DNS 名称 您在上节中创建了该名称。

现在,您可以从配置在应用程序账户的客户端连接到 Aurora 数据库:

bash psql p 5432 d postgres U sampleuser h vpcexxxxxxxxxxxxxxxxxxyyyyyyyyvpcesvczzzzzzzzzzzzzzzzzzzeuwest1vpceamazonawscomPassword for user sampleuser psql (149 server 146)SSL connection (protocol TLSv12 cipher ECDHERSAAES256GCMSHA384 bits 256 compression off)Type help for help

postgres=gt select version()version

PostgreSQL 146 on aarch64unknownlinuxgnu compiled by aarch64unknownlinuxgnugcc (GCC) 750 64bit(1 row)

安易免费加速器

postgres=gt select auroraversion()auroraversion

1464(1 row)

数据库账户中的 Aurora 集群配置了一个写实例和一个读实例。我们测试了对写实例的连接,并能够创建一个新表并插入一些数据:

sqlpostgres=gt create table blogtable (col1 int col2 varchar)CREATE TABLE

postgres=gt insert into blogtable values (1 Some text)INSERT 0 1

postgres=gt select from blogtable col1 col2 1 Some text(1 row)

请保持 psql 客户端与数据库连接,检查在故障转移后,您的连接是否仍然处于活动状态,因为 RDS Proxy 可隐藏 Aurora 集群的故障并保持客户端连接。

测试故障转移事件

现在我们在数据库账户中打开 RDS 控制台并选择 数据库。当前,写实例在 euwest1b 可用区。让我们触发手动故障转移,然后再次检查跨账户的连接性。为此,在 Amazon RDS 控制台中选择写实例,并在 操作 菜单中选择 故障转移。

![故障转移数据库](https//