【问题标题】:unable to connect to AWS VPC RDS instance (mysql or postgres)无法连接到 AWS VPC RDS 实例(mysql 或 postgres)
【发布时间】:2015-07-28 13:49:55
【问题描述】:

(我在事后发布这个问题是因为找到根本原因和解决方案需要时间。其他人也很有可能遇到同样的问题)

我有一个 RDS 实例(在 VPC 中),我试图从运行在经典 EC2 实例上的应用程序连接到该实例,通过 ClassicLink 连接。安全组和 DNS 不是问题。

我能够建立到 RDS 实例的套接字连接,但无法使用 CLI 工具(psql、mysql 等)或数据库 GUI 工具(如 toad 或 mysql workbench)进行连接。

使用 telnet 或 nc 的直接套接字连接导致 TCP 连接处于“ESTABLISHED”状态(来自 netstat 的输出)。

来自 DB CLI、GUI 工具或应用程序的连接会导致超时和 TCP 连接卡在“SYN”状态。

更新:就我而言,根本原因是 MTU 大小和 EC2 ClassicLink 存在问题。我在下面的答案中发布了一些一般故障排除信息,以防其他人遇到类似的 RDS 连接问题。

【问题讨论】:

    标签: mysql postgresql amazon-web-services amazon-rds mtu


    【解决方案1】:

    针对在尝试连接 RDS 或 RedShift 时可能遇到类似问题的人的其他信息:

    1) 检查安全组

    验证 RDS 实例的安全组是否允许从您的源服务器所属的安全组(或者如果在 AWS 外部,则直接添加其 IP)进行访问。您应该查看的安全组是在 RDS 控制台 UI 的 RDS 实例属性中指定的安全组(名为“安全组”)。

    注意:数据库安全组可能与 AWS EC2 安全组不同。如果您的 RDS 实例在经典/公共 EC2 中,您应该检查 RDS UI 的“数据库安全组”部分。对于 VPC 用户,安全组为普通 VPC 安全组(名称 sg-xxx 将列在 RDS 实例的属性中)。

    2) 确认 DNS 没有问题。

    Amazon 使用拆分 DNS,因此 AWS 外部的 DNS 查找将返回公共 IP,而 AWS 内部的查找将返回私有 IP。如果您怀疑是 DNS 问题,您是否确认从不同的可用区返回不同的 IP?如果不同的 AZ 获得不同的 IP,则需要联系 AWS 支持。

    3) 通过建立套接字连接来确认网络连接。

    tracepath 和 traceroute 等工具可能无济于事,因为 RDS 目前会丢弃 ICMP 流量。

    通过尝试在端口 3306(mysql 或 postgres 的 5432)上建立与 RDS 实例的套接字连接来测试端口连接。首先找到 RDS 实例的 IP 并使用 telnet 或 nc(如果从 AWS 内部连接,请务必使用内部/私有 IP):

    telnet x.x.x.x 3306
    nc -vz x.x.x.x 3306
    

    a) 如果您的连接尝试不成功并立即失败,则该端口可能被阻塞或远程主机未在该端口上运行服务。您可能需要与 AWS 支持联系以进一步排除故障。如果从 AWS 外部连接,请先尝试从 AWS 内部的另一个实例连接(因为您的防火墙可能会阻止这些连接)。

    b) 如果您的连接不成功并且出现超时,则可能是数据包被防火墙丢弃/忽略了,或者数据包正在不同的网络路径上返回。您可以通过运行 netstat -an | grep SYN 来确认这一点(在等待 telnet/nc 命令超时时从不同的 ssh 会话)。

    处于 SYN 状态的连接意味着您已发送连接请求,但尚未收到任何回复(SYN_ACK 或拒绝/阻止)。通常这意味着防火墙或安全组正在忽略或丢弃数据包。

    这也可能是 NAT 路由或来自多个接口的多个路径的问题。检查以确保您没有在主机和 RDS 实例之间使用 iptables 或 NAT 网关。如果您在 VPC 中,还请确保您允许来自源主机的出站/出站流量。

    c) 如果你的socket连接测试成功了,但是你无法连接mysql客户端(CLI、workbench、app等),看看netstat的输出查看连接处于什么状态(将 x.x.x.x 替换为 RDS 实例的实际 IP 地址):

    netstat -an | grep x.x.x.x

    如果您在使用 telnet 或 NC 时建立了连接,但在使用 mysql 客户端时看到“SYN”状态,则您可能遇到了 MTU 问题。

    在编写本文时,RDS 可能不支持用于 PMTUD (https://en.wikipedia.org/wiki/Path_MTU_Discovery#Problems_with_PMTUD) 的 ICMP 数据包。如果您尝试通过 ClassicLink 从经典 ec2 实例访问 VPC 中的 RDS 或 RedShift,这可能会出现问题。尝试使用以下方法降低 MTU,然后再次测试:

    sudo ip link show
    # take note of the current MTU (likely 1500 or 9001)
    sudo ip link set dev eth0 mtu 1400
    

    如果较低的 MTU 有效,请务必向 AWS 客户支持寻求帮助,并提及您在尝试连接到 RDS 实例时遇到了 MTU 问题。如果 TCP 数据包使用隧道封装封装,则会发生这种情况,从而导致数据包数据/有效负载的可用 MTU 较低。降低源服务器上的 MTU 允许打包的数据包在通过隧道网关时仍然符合 MTU 限制。

    如果它不起作用,请将您的 MTU 设置回默认值并联系 AWS 支持以进行进一步的故障排除。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-02
      • 2015-04-30
      • 2018-05-11
      • 2019-01-02
      • 2015-06-24
      • 1970-01-01
      • 2013-05-05
      • 2019-07-05
      相关资源
      最近更新 更多