针对可能遇到连接RDS或RedShift的类似问题的人提供额外信息:
1) 检查安全组
验证RDS实例的安全组是否允许来自源服务器所属的安全组(或其直接添加的IP)的访问。您应该查看的安全组是从RDS控制台UI中指定的RDS实例属性的安全组(命名为“安全组”)。
注意:数据库安全组与AWS EC2安全组可能不同。如果您的RDS实例在classic/public 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(postgres)上建立套接字连接来测试端口连接。首先找到RDS实例的IP,然后使用telnet或nc:
telnet x.x.x.x 3306
nc -vz x.x.x.x 3306
a) 如果您的连接尝试不成功并立即失败,则端口可能被阻止或远程主机未在该端口上运行服务。您可能需要联系AWS支持进行进一步故障排除。如果从AWS之外连接,请先尝试从AWS内的另一个实例进行连接(因为您的防火墙可能会阻止这些连接)。
b) 如果您的连接不成功并出现超时,则可能是防火墙丢弃/忽略数据包或数据包返回的网络路径不同。您可以通过运行netstat -an | grep SYN
来确认此问题(从不同的CLI窗口/会话中运行并等待telnet / nc命令超时)。处于SYN状态的连接意味着您已发送连接请求,但没有收到任何回应(SYN_ACK或拒绝/阻止)。通常,这意味着防火墙或安全组正在忽略或丢弃数据包。
请检查是否在主机和RDS实例之间使用iptables或NAT网关。如果您在VPC中,请确保允许源主机的出站流量。
c) 如果套接字连接测试成功,但您无法使用mysql客户端(CLI、工作台、应用程序等)连接,请查看netstat的输出以查看连接状态(将x.x.x.x替换为RDS实例的实际IP地址):
netstat -an | grep x.x.x.x
如果使用telnet或NC时正在建立连接,但是在使用mysql客户端时看到“SYN”状态,则可能遇到MTU问题。
当撰写本文时,RDS可能不支持用于PMTUD的ICMP数据包(https://en.wikipedia.org/wiki/Path_MTU_Discovery#Problems_with_PMTUD)。如果您尝试通过ClassicLink从经典EC2实例访问位于VPC中的RDS或RedShift,则可能会出现问题。请尝试使用以下方法降低MTU,然后再次测试:
sudo ip link show
sudo ip link set dev eth0 mtu 1400
如果较低的MTU可行,请务必跟进AWS客户支持以寻求帮助,并提及在连接到您的RDS实例时遇到了MTU问题。如果TCP数据包被封装进行隧道传输,则会导致数据包/有效负载的可用MTU降低。将源服务器上的MTU降低,允许封装的数据包仍适合限制范围内。
如果不起作用,请将MTU设置回默认值并联系AWS支持进行进一步故障排除。