RDSやAuroraに接続しようとしてプロンプトが返らず、数十秒後にタイムアウトする。この症状に当たったとき、調べる範囲はネットワーク周辺にほぼ絞れます。
この記事は要約版です。省略した詳しい解説や手順は、ブログの完全版にまとめています: RDS 接続できない・タイムアウトの原因と切り分け手順
判断の起点になるのは、タイムアウトするのか、エラーが即座に返るのかという違いです。タイムアウトはTCPのSYNに応答がない状態で、パケットがどこかで破棄されている(あるいは戻ってこない)ことを表します。パスワードやデータベース名が間違っている場合はTCP接続自体が成立するため、エラーはすぐ返ってきます。この一点を確認するだけで、確認対象が大きく変わります。
原因の大半はセキュリティグループと経路
接続タイムアウトの原因を頻度順に並べると、DBインスタンスにアタッチしたセキュリティグループのインバウンドで接続元が許可されていないケースと、接続元とDBが別VPCや別サブネットにあってルーティングやピアリングが通っていないケースで大半を説明できます。残りはパブリックアクセス設定とルートテーブルの不整合、カスタムのネットワークACLによる戻り通信の遮断、エンドポイントやポートの誤り、available以外のステータスです。
セキュリティグループはステートフルなので、インバウンドでDBポートを許可すれば戻りの通信は自動で通ります。ネットワークACLはステートレスで、インバウンドとアウトバウンドの両方にルールが必要になります。デフォルトのACLは全許可のため、カスタムACLを作っている環境だけ疑ってください。
インターネットから直接到達できるのは、「パブリックアクセス: あり」「パブリックサブネット配置」「セキュリティグループ許可」の三つが揃ったときだけです。一つでも欠ければタイムアウトします。
最初に確認する三つ
ステータス、エンドポイント、ポートを文字列レベルで確定させる
どこからどこへどのポートでつなごうとしているのかが曖昧なままセキュリティグループを眺めても、時間を無駄にします。
# DB インスタンスの基本情報をまとめて確認
aws rds describe-db-instances \
--db-instance-identifier my-db \
--query 'DBInstances[0].{Status:DBInstanceStatus,Endpoint:Endpoint.Address,Port:Endpoint.Port,Public:PubliclyAccessible,VpcSG:VpcSecurityGroups,SubnetGroup:DBSubnetGroup.DBSubnetGroupName,AZ:AvailabilityZone}' \
--output json
DBInstanceStatusがstoppedなら接続できません。ポートも既定値とは限らず、PostgreSQLで5432を開けているのに実体は5433だったという例があります。
インバウンドルールを見る
取得したVPCセキュリティグループIDで、インバウンドルールを確認します。
aws ec2 describe-security-groups \
--group-ids sg-0123456789abcdef0 \
--query 'SecurityGroups[0].IpPermissions' \
--output json
見る点は三つあります。DBポートに対するルールがあるか、ソースに接続元が含まれているか、ソースがSG参照ならその接続元EC2やLambdaに当該SGを実際にアタッチしているか。CIDR指定の誤りも多く、10.0.1.0/24と書いてあるのに接続元が10.0.2.xにいる、/32が古いIPのまま、といった例が目立ちます。
素のTCPで到達性を測る
DBクライアントのエラーメッセージは原因を曖昧にしがちです。まずTCPが届くかどうかだけを確かめます。
# nc(netcat)で TCP 到達性のみ確認。タイムアウトを 5 秒に制限
nc -zv -w 5 my-db.xxxxxxxx.ap-northeast-1.rds.amazonaws.com 5432
succeededが返るのにDBクライアントで失敗するなら、ネットワークは通っています。認証、SSL、データベース名を疑ってください。5秒待って無反応ならパケットが破棄されており、セキュリティグループ、ACL、ルーティングの確認に進みます。Connection refusedが即返る場合は到達しているがそのポートで待ち受けていない状態で、ポート番号の誤りか別ホストに当たっています。
詳しくは
元記事では、サブネットとルートテーブルの判断基準を接続経路のパターンごとに整理し、Reachability AnalyzerやVPCフローログで遮断箇所を特定する手順まで扱っています。FATAL: no pg_hba.conf entryやremaining connection slots are reservedなどエラーメッセージ別の読み分け、フェイルオーバー時のDNSキャッシュやNATゲートウェイのポート枯渇による間欠タイムアウトの調査、Lambdaからの接続確認順も載せました。再発防止のための監視項目とプール設計まで含めて確認したい方はRDS 接続できない・タイムアウトの原因と切り分け手順を参照してください。