(我之后发布这个问题是因为找到根本原因和解决方案所花费的时间。其他人也很有可能遇到同样的问题)
我有一个RDS实例(在VPC中),我试图从经典EC2实例上运行的应用程序连接,通过ClassicLink连接。安全组和DNS不是问题。
我能够建立到RDS实例的套接字连接,但是无法连接CLI工具(psql,mysql等)或者像toad或mysql workbench这样的数据库GUI工具。
使用telnet或nc的直接套接字连接会导致" ESTABLISHED"中的TCP连接。 state(来自netstat的输出)。
来自DB CLI,GUI工具或应用程序的连接会导致超时和TCP连接卡在" SYN"状态。
更新:在我的情况下,根本原因是MTU大小和EC2 ClassicLink存在问题。我已在下面的答案中发布了一些常规故障排除信息,以防其他人遇到类似的RDS连接问题。
答案 0 :(得分:1)
尝试连接到RDS或RedShift时可能遇到类似问题的人员的其他信息:
1)检查安全组
验证RDS实例的安全组是否允许从源服务器所属的安全组进行访问(或者如果在AWS外部,则直接添加其IP)。您应该查看的安全组是RDS控制台UI中的RDS实例属性中指定的安全组(名为"安全组")。
注意:数据库安全组可能与AWS EC2安全组不同。如果您的RDS实例在经典/公共EC2中,您应该检查"数据库安全组" RDS UI的一部分。对于VPC用户,安全组将是普通的VPC安全组(名称sg-xxx将列在RDS实例的属性中)。
2)确认DNS不是问题。
亚马逊使用拆分DNS,因此AWS外部的DNS查找将返回公共IP,而AWS内部的查找将返回私有IP。如果您怀疑它是DNS问题,您是否确认从不同的可用区域返回了不同的IP?如果不同的AZ获得不同的IP,您需要联系AWS支持。
3)通过建立套接字连接来确认网络连接。
tracepath和traceroute等工具可能无法提供帮助,因为RDS目前会降低ICMP流量。
尝试在端口3306(mysql或5432 for postgres)上建立与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)如果您的套接字连接测试成功,但您无法连接mysql客户端(CLI,工作台,应用程序等),请查看输出netstat以查看连接所处的状态(将xxxx替换为RDS实例的实际IP地址):
netstat -an | grep x.x.x.x
如果您在使用telnet或NC时建立了连接,但是您看到了' SYN'在使用mysql客户端时,您可能遇到了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支持人员联系以进行进一步的故障排除。