为啥我无法在对等互连后从另一个 VPC 中的 EC2 实例连接 AWS RDS 实例

Posted

技术标签:

【中文标题】为啥我无法在对等互连后从另一个 VPC 中的 EC2 实例连接 AWS RDS 实例【英文标题】:Why can't I connect AWS RDS instance from EC2 instance in another VPC after peering为什么我无法在对等互连后从另一个 VPC 中的 EC2 实例连接 AWS RDS 实例 【发布时间】:2018-02-28 23:28:03 【问题描述】:

我在 VPC A 中的 EC2 实例上运行 Tableau Server。同时,我在另一个 VPC B 中创建了一个 postgres RDS。现在我想在 Tableau Server 和 RDS 之间建立连接。 RDS VPC的CIDR为172.31.0.0/16,EC2 VPC的CIDR为10.0.0.0/16。

根据A DB Instance in a VPC Accessed by an EC2 Instance in a Different VPC,我在 VPC A 和 VPC B 之间创建了对等互连,pcx-xyz123。此外,我还为 VPC 创建了以下路由表。

RDS VPC
Destination      Target
172.31.0.0/16    local
10.0.0.0/16      pcx-xyz123

EC2 VPC
Destination      Target
10.0.0.0/16      local
172.31.0.0/16    pcx-xyz123

两个路由表都是主要的。每个都有 0 个子网(不确定这是否重要)。

但是,我仍然无法从 Tableau Server 连接 RDS。

这两个实例是由同一个帐户创建的。它们都列在美国东部(俄亥俄州)下。所以我假设他们在同一个地区。另外,它们的主机名中都有us-east-2。在我的 PC 上,我可以使用 psql 命令或 pgAdmin 连接到 RDS。

为什么我不能连接两个实例?

编辑: 我在与 Tableau Server 相同的 VPC 的同一子网中创建了另一个 EC2 Linux 实例,仅用于调试目的。我以相同的方式配置了对等互连和路由表,并将子网与路由表相关联。但是,我仍然无法连接到 EC2 Linux 实例上的 RDS。

【问题讨论】:

无论是谁发起了对等互连,只要它被接受即可。您是否更新了每个 VPC 中的路由表以指向对等连接?安全组?您能否编辑您的问题以显示配置?您可以尝试通过对等连接在两个 EC2 实例之间进行连接吗?还是 EC2 实例和 RDS?你做了什么调试? 你是否与 vpc-peering 和 route-table 绑定? 是否接受对等互连?可以贴一下VPC A的路由表吗?或者VPC B目标CIDR的EC2实例子网路由表中的规则是什么? @JohnRotenstein 原帖中添加的路由表配置 @helloV 我用路由表更新了帖子。是的,接受对等互连。不知何故,我没有任何与路由表关联的子网。我应该吗? 【参考方案1】:

VPC 对等互连的工作方式与公共子网连接到 Internet 网关的方式大致相同——路由表定义了流量如何进出子网。

为了使 VPC 对等互连工作:

邀请并接受对等连接(完成) 在每个 VPC 中创建一个路由表,指向另一个 VPC 的 IP 范围的对等连接(完成) 将您希望能够与路由表对等的每个子网关联 或者,编辑现有路由表以包含对等条目 如果您的 RDS 数据库是公共的,并且您尝试使用数据库的公共 DNS 进行连接,那么您需要编辑 your peering connection 的 DNS 设置以允许 DNS 解析。

路由工作如下:

当流量离开子网时,会参考路由表以确定将流量发送到哪里 首先评估限制最大的(例如 /24),直到限制最少的(例如 /0) 根据相应的路由表条目路由流量

这意味着您可以配置 一些 子网来对等,而不必包括所有子网。传统上,对等的是私有子网,并且可能只有特定私有子网——但这完全是您的选择。

把它想象成路线图上的方向,告诉交通它应该被引导到哪里。

【讨论】:

我只是将所有子网关联到两个 VPC 的路由表。但是仍然无法连接到 RDS。 那么你应该逐步调试。首先在每个 VPC 中创建一个 EC2 实例。登录一个,然后从那里尝试登录另一个。确保安全组允许连接。这样,您检查的是网络而不是 RDS。如果它有效,那么你的对等是好的。接下来是从 EC2 实例连接到另一个 VPC 中的 RDS。只有在那之后,您才应该从 Tableau 中尝试,因为这更难调试。 我尝试从一个 VPC 中的 EC2 访问另一个 VPC 中的 EC2,它可以双向工作。如何从 EC2 实例访问 RDS,而不是使用 psql 命令?我可以ssh吗?不过,我似乎无法找到 RDS 实例的公共 IP。 如果是 PostgreSQL 数据库,那么psql 是一个很好的测试连通性的方法。还要检查与您的 RDS 实例关联的安全组。它应该允许从两个 VPC(或至少从您要连接的位置)的私有地址范围进行访问。 您的 RDS 端点 xxxxxx-db.xxxxxxxxx.us-east-2.rds.amazonaws.com 可能需要 DNS 解析。进入您的对等连接并将 DNS 设置编辑为 true。在您的 EC2 实例中,nslookup 和 RDS 端点应更改为 172.31.0.0/16 范围内的 ip【参考方案2】:

VPC 对等是关于细节的。以下是我们必须运行的项目才能使其工作。

对等 VPC 1 到 VPC 2(很明显,但包括那些没有执行此步骤的人)。从 VPC 1 建立到 VPC 2 的对等互连。接受请求。如果不同地域,切换到VPC 2地域并接受peer请求。

例子:

VPC 1 CIDR = 10.0.0.0/16 VPC 2 CIDR = 172.16.0.0/16

VPC 1(带 RDS 实例的 VPC) 1. RDS 实例的路由表服务子网 - 将路由目标添加到 VPC 2 CIDR 块 (172.16.0.0/16) 和目标 VPC 2 对等连接(从列表中选择 - pcx-#####)。 2. RDS 安全组 - 为源 IP 为 VPC 2 CIDR 块 (172.16.0.0/16) 的 DB 端口添加入站规则。因此,您将有两个用于 DB 端口的入站规则。一个用于 VPC 1 (10.0.0.0/16) CIDR 块,一个用于 VPC 2 (172.16.0.0/16)。 3. 私有路由表的网络访问控制列表 - 如果您只允许某些端口,请为 DB 端口添加规则,源 = VPC 2 CIDR 块 (172.16.0.0/16) 和允许。VPC 2 1. EC2 实例的路由表服务子网 - 将路由目标添加到 VPC 1 CIDR 块 (10.0.0.0/16) 和目标 VPC 1 对等连接(从列表中选择 - pcx-#####)。 2. 实例安全组 - 为源 IP 为 VPC 1 CIDR 块 (10.0.0.0/16) 的数据库端口添加入站规则。 3. Route Table 的网络访问控制列表 - 如果您只允许某些端口,请为 DB Port 添加一条规则,source = VPC 1 CIDR block (10.0.0.0/16) 并允许。

我想就是这样 - 但如果我找到其他设置,我会更新此消息。

只是一些历史记录,我们这样做是为了进行灾难恢复。我们的生产实例和 RDS MS SQL DB 在 us-east-1 (VPC 1) 中,我们的灾难恢复暖备用实例在 us-west-2 (VPC 2) 中。我们主要从美国获得流量,但我们可能会考虑将备用站点设为真正的生产副本(扩展组),然后将 Route 5 记录更改为基于延迟的路由。

【讨论】:

【参考方案3】:

以下是通过 VPC 对等访问私有 RDS 的步骤:

假设您有 2 个 VPC:

生产 VPC:10.0.1.0/24 RDS VPC:10.0.2.0/24

第 1 步:在两个 VPC 之间创建 VPC 对等连接。 然后接受建立连接的请求。您将获得一个连接 ID,例如:pcx-e8e8e8e8

第 2 步:在 每个 VPC 中配置路由表

生产 VPC:将此路由添加到 RDS VPC: 10.0.2.0/24 —> pcx-e8e8e8e8 RDS VPC:将此路由添加到生产 VPC: 10.0.1.0/24 —> pcx-e8e8e8e8

第 3 步:通过添加此入站规则,配置 RDS 的安全组以接受生产 VPC 的 IP 范围

端口(MS SQL:1433,mysql:3306 等)- 允许源:10.0.1.0/24

现在应该可以连接了。

注意:连接到 RDS 时,您应该使用提供的 DNS 名称以获得更好的弹性。 AWS VPC DNS 将负责将此名称解析为 RDS 实例的本地 IP 地址。

【讨论】:

这应该是 -> RDS VPC:将此路由添加到生产 VPC:10.0.1.0/24 —> pcx-e8e8e8e8 如果您忘记了第 3 步,您将获得超时,不要忘记!感谢您指出每一步。 我知道,我们不应该在 SO 评论中说谢谢,但谢谢你这些清晰的解释。【参考方案4】:

我遇到了类似的问题,这就是我所做的:

    已创建 VPC 对等互连,如上述线程中所述。

    在 RDS 实例的安全组中,您可以添加允许端口 5432(Postgres 端口)Securitygroupid/hostIP/VPC_CIDR 的规则。

    登录EC2实例安装psql(sudo yum install postgresql-server postgresql-contrib),执行如下命令:

    # this will ask for the password and connect.
    psql --host=xxxxxx.us-west-2.rds.amazonaws.com --port=5432 --username=xxxxx --password --dbname=xxxxx
    

【讨论】:

【参考方案5】:

按照上述所有操作后,我仍然无法连接到我的 RDS 实例。这是我第一次在 Reddit 上找到答案,而不是 SO(这里:https://www.reddit.com/r/aws/comments/8hx28w/rds_access_from_a_different_vpc/dyn616i/)。

Tl;博士 如果您已经对等 VPC、修改了路由表并打开了数据库安全组以允许来自源 VPC CIDR 的连接(基本上,@John Rotenstein 的建议 https://***.com/a/46331624/1830623),那么请确保您的 RDS 实例未标记为 Public .

【讨论】:

P.S.如果以前没有,那么该链接现在会提到跨 VPC 的 DNS 解析。将 RDS 标记为私有通过消除解析中的公共 IP 地址来解决“蛮力”问题。无论如何,这可能是一种很好的安全做法,但“优雅”的解决方案是让 RDS 服务器的 DNS 解析为私有 IP 地址,而不删除公共 IP 地址。【参考方案6】:

问题已经得到解答,但我想补充一下,如果您要连接到 RDS 的公共 DNS(例如 prod.upd9999upd.us-east-1.rds.amazonaws.com),那么您必须启用对私有 IP 的 DNS 解析。这是通过AllowDnsResolutionFromRemoteVpc 完成的。

示例:将 Vpc EC2_PROD(172.0.0.0/16) 连接到 Vpc RDS_PROD(30.0.0.0/16)。

1) 创建从 EC2 VPC(请求者)到 RDS VPC(接受者)的Peering connection。 通过右键单击已创建的对等连接和“编辑 DNS 设置”,确保使用 UI 启用AllowDnsResolutionFromRemoteVpc。或following command

aws ec2 modify-vpc-peering-connection-options --vpc-peering-connection-id "pcx-04a511409bb08ef16" --requester-peering-connection-options '"AllowDnsResolutionFromRemoteVpc":true' --accepter-peering-connection-options '"AllowDnsResolutionFromRemoteVpc":true' --region us-east-1

您的最终对等连接将如下所示:

aws ec2 describe-vpc-peering-connections --profile aws-work --region us-east-1

    "VpcPeeringConnections": [
        
            "Status": 
                "Message": "Active", 
                "Code": "active"
            , 
            "Tags": [
                
                    "Value": "ec2-to-rds-peering-connection", 
                    "Key": "Name"
                
            ], 
            "AccepterVpcInfo": 
                "PeeringOptions": 
                    "AllowEgressFromLocalVpcToRemoteClassicLink": false, 
                    "AllowDnsResolutionFromRemoteVpc": true, 
                    "AllowEgressFromLocalClassicLinkToRemoteVpc": false
                , 
                "VpcId": "vpc-RDS", 
                "Region": "us-east-1", 
                "OwnerId": "?", 
                "CidrBlockSet": [
                    
                        "CidrBlock": "30.0.0.0/16"
                    
                ], 
                "CidrBlock": "30.0.0.0/16"
            , 
            "VpcPeeringConnectionId": "pcx-04a511409bb08ef16", 
            "RequesterVpcInfo": 
                "PeeringOptions": 
                    "AllowEgressFromLocalVpcToRemoteClassicLink": false, 
                    "AllowDnsResolutionFromRemoteVpc": true, 
                    "AllowEgressFromLocalClassicLinkToRemoteVpc": false
                , 
                "VpcId": "vpc-ec2", 
                "Region": "us-east-1", 
                "OwnerId": "?", 
                "CidrBlockSet": [
                    
                        "CidrBlock": "172.0.0.0/16"
                    
                ], 
                "CidrBlock": "172.0.0.0/16"
            
        
    ]

2) 您的Requester VPC (Ec2 VPC) 路由表必须添加Accepter IP cider(例如30.0.0.0/16)。 (参见下面的Routes 标签)

aws ec2 describe-route-tables --filters Name=tag:Name,Values=EC2_PROD --profile aws-work --region us-east-1

    "RouteTables": [
        
            "Associations": [
                
                    "RouteTableAssociationId": "rtbassoc-?", 
                    "Main": true, 
                    "RouteTableId": "rtb-?"
                
            ], 
            "RouteTableId": "rtb-?", 
            "VpcId": "vpc-EC2_PROD", 
            "PropagatingVgws": [], 
            "Tags": [
                
                    "Value": "EC2_PROD", 
                    "Key": "Name"
                
            ], 
            "Routes": [
                
                    "GatewayId": "local", 
                    "DestinationCidrBlock": "172.0.0.0/16", 
                    "State": "active", 
                    "Origin": "CreateRouteTable"
                , 
                
                    "Origin": "CreateRoute", 
                    "DestinationCidrBlock": "30.0.0.0/16",    // Accepter IP cider block
                    "State": "active", 
                    "VpcPeeringConnectionId": "pcx-04a511409bb08ef16"
                , 
                
                    "GatewayId": "igw-???", 
                    "DestinationCidrBlock": "0.0.0.0/0", 
                    "State": "active", 
                    "Origin": "CreateRoute"
                
            ]
        
    ]

3) 同样Acceptor VPC (RDS VPC) 路由表必须添加Requester IP cider(例如172.0.0.0/16)。 (参见下面的Routes 标签)

aws ec2 describe-route-tables --filters Name=tag:Name,Values=RDS_PROD --profile aws-work --region us-east-1

    "RouteTables": [
        
            "Associations": [
                
                    "SubnetId": "subnet-?", 
                    "RouteTableAssociationId": "rtbassoc-?", 
                    "Main": false, 
                    "RouteTableId": "rtb-?"
                
            ], 
            "RouteTableId": "rtb-?", 
            "VpcId": "vpc-RDS", 
            "PropagatingVgws": [], 
            "Tags": [
                
                    "Value": "RDS_PROD", 
                    "Key": "Name"
                
            ], 
            "Routes": [
                
                    "Origin": "CreateRoute", 
                    "DestinationCidrBlock": "172.0.0.0/16",    // Requester IP cider block
                    "State": "active", 
                    "VpcPeeringConnectionId": "pcx-04a511409bb08ef16"
                , 
                
                    "GatewayId": "local", 
                    "DestinationCidrBlock": "30.0.0.0/16", 
                    "State": "active", 
                    "Origin": "CreateRouteTable"
                , 
                
                    "GatewayId": "igw-???", 
                    "DestinationCidrBlock": "0.0.0.0/0", 
                    "State": "active", 
                    "Origin": "CreateRoute"
                
            ]
        
    ]

4) 最后还更新 Accepter VPC(RDS) 上的防火墙/安全组,以允许从 Ec2 VPC 的 3306 端口(如果它的 mysql)连接。

aws ec2 describe-security-groups --filters Name=tag:Name,Values=RDS_FIREWALL --profile aws-work --region us-east-1

    "SecurityGroups": [
        
            "IpPermissionsEgress": [
                
                    "IpProtocol": "-1", 
                    "PrefixListIds": [], 
                    "IpRanges": [
                        
                            "CidrIp": "0.0.0.0/0"
                        
                    ], 
                    "UserIdGroupPairs": [], 
                    "Ipv6Ranges": []
                
            ], 
            "Description": "Dev", 
            "Tags": [
                
                    "Value": "RDS_FIREWALL", 
                    "Key": "Name"
                
            ], 
            "IpPermissions": [
                
                    "PrefixListIds": [], 
                    "FromPort": 3306, 
                    "IpRanges": [
                        
                            "Description": "EC2_VPC_IP_CIDER", 
                            "CidrIp": "172.0.0.0/16"
                        
                    ], 
                    "ToPort": 3306, 
                    "IpProtocol": "tcp", 
                    "UserIdGroupPairs": [], 
                    "Ipv6Ranges": []
                
            ], 
            "GroupName": "RDS_FIREWALL", 
            "VpcId": "vpc-???", 
            "OwnerId": "???", 
            "GroupId": "sg-???"
        
    ]

【讨论】:

如果您的 EC2 实例的 VPC 有多个子网,请务必修改 EC2 实例上引用的路由表【参考方案7】:

如果您的 CIDR 相同,则对等互连将不起作用。如果您将实例从一个区域克隆到另一个区域,则会出现相同的 CIDR。在路由中,您将无法定义相同的 CIDR。

【讨论】:

以上是关于为啥我无法在对等互连后从另一个 VPC 中的 EC2 实例连接 AWS RDS 实例的主要内容,如果未能解决你的问题,请参考以下文章

无法通过私有 IP 从另一个实例访问 AWS EC2 实例

AWS Lambda 无法访问同一 VPC 中的 EC2 端口

ssh 隧道/端口转发无法通过 EC2 实例工作到 VPC 中的 Elasticsearch 集群

将一个 VPC 中的 EBS 卷数据传输到另一个 VPC 中的 EFS

Terraform - 在 VPC 对等连接之间授权安全组

如何从 AWS 胶水访问 VPC 中的 aws 资源?