EC2インスタンスi-78a8df00から、RDSインスタンスmysql.****.us-east-1.rds.amazonaws.comに接続しようとしている。どちらもU.S.Eastリージョンにあります。EC2インスタンスのセキュリティグループ(sg-****)をRDSのセキュリティグループに追加してみましたが、解決に至りませんでした。このコマンドを実行するとタイムアウトしてしまうので、ファイアウォール/DNSの問題のようです。
ubuntu@ip-10-195-189-237:~$ mysql -h mysql.************.us-east-1.rds.amazonaws.com
ERROR 2003 (HY000).Can't接続できません。'mysql.****.us-east-1.rds.amazonaws.com' (110) のMySQLサーバーに接続することができない。
私のローカルマシンからは、上記と同じ行を使用してRDSインスタンスに問題なく接続できます。様々なフォーラムでの解決策を試しましたが、これらは役に立ちません。
RDSやRedShiftに接続しようとして同様の問題に遭遇する可能性がある人への追加情報です。
1)セキュリティグループを確認する。
RDSインスタンスのセキュリティグループが、接続元のサーバーが所属するセキュリティグループ(AWSの外部の場合は直接追加したIP)からのアクセスを許可していることを確認します。確認するセキュリティグループは、RDSコンソールUIからRDSインスタンスの属性に指定されているもの("security group"という名前)です。
注:データベースのセキュリティグループは、AWS EC2のセキュリティグループと異なる場合があります。RDSインスタンスがクラシック/パブリックEC2の場合、RDS UIの"データベースセキュリティグループ"のセクションを確認する必要があります。VPCユーザーの場合、セキュリティグループは通常のVPCセキュリティグループとなります(RDSインスタンスの属性にsg-xxxという名前が記載されます)。
**2)DNSが問題ないことを確認します。
AmazonはスプリットDNSを採用しており、AWSの外部でDNSを検索するとパブリックIPが、内部で検索するとプライベートIPが返されます。DNSの問題だと思われる場合、異なるIPが異なるアベイラビリティゾーンから返されることを確認しましたか?異なるAZで異なるIPが返ってくる場合は、AWSのサポートにお問い合わせいただく必要があります。
**3)ソケット接続を行い、ネットワーク接続を確認します。
RDSは現在ICMPトラフィックをドロップするため、tracepathやtracerouteのようなツールはおそらく役に立ちません。
ポート3306(mysql、またはpostgresの5432)でRDSインスタンスへのソケット接続を確立しようとすることで、ポート接続をテストしてください。RDS インスタンスの IP を見つけて、telnet または nc のいずれかを使用して開始します。
telnet x.x.x.x 3306
nc -vz x.x.x.x 3306
a) 接続が成功せず、すぐに失敗する場合、ポートがブロックされているか、リモートホストがそのポートでサービスを実行していない可能性が高いです。AWS の外部から接続する場合、まず AWS 内の別のインスタンスから接続してみてください(ファイアウォールがこれらの接続をブロックしている可能性があるため)。
b) 接続が成功せず、タイムアウトが発生する場合、パケットはおそらくファイアウォールによってドロップ/無視されているか、パケットが異なるネットワークパスで返されています。netstat -an | grep SYN`を実行することで確認できます(telnet/ncコマンドを実行しタイムアウトを待っている間に別のCLIウィンドウ/セッションから)。SYN状態の接続は、接続要求を送ったが、何も返ってきていない(SYN_ACKまたはreject/block)ことを意味します。通常、これはファイアウォールやセキュリティグループがパケットを無視したり、ドロップしていることを意味します。
ホストとRDSインスタンスの間でiptablesまたはNATゲートウェイを使用していないことを確認してください。VPC 内にいる場合は、送信元ホストからの egress/outbound トラフィックを許可していることも確認してください。
**ソケット接続テストは成功したが、mysql クライアント(CLI、ワークベンチ、アプリなど)で接続できない場合、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パケットをサポートしていない可能性があります。これは、クラシックリンク経由でクラシック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をデフォルトに戻し、AWSのサポートにトラブルシューティングを依頼してください。
どうやらmulti-AZはすべてを台無しにするようです。デフォルトのmulti-AZ設定は、私のデータベースをus-east-1d地域に配置し、私のEC2インスタンスはus-east-1a地域にあったので、DNSは正しくルーティングされていなかった。RDSインスタンスを非マルチAZとして再作成し、us-east-1aで動作するようにしたら、すべてがハッピーになりました。
もし、RDS、ELB、multi-AZ機能を持つAWS上のDNSルーティングに関して、超天才がいるならば、Amazon Web Serviceのドキュメントのどこにも書かれていないので、これを行う方法を知ることはとても素晴らしいことだと思うのですが、いかがでしょうか?