トラブルシューティングの極意―達人に訊く問題解決のヒント

第7回 [クラウド編]低レイヤから行う原因調査―AWS上に構築されたシステムのトラブルに遭ったときに

この記事を読むのに必要な時間:およそ 4 分

トラシュー事例(上級編)
参照系のデータベースアクセスが負荷分散されない

問題発覚と環境説明

AWSのサービスの中にはEC2のようなサービスのほかに,ロードバランサのサービスであるElastic Load Balancing(以下,ELB⁠⁠,リレーショナルデータベースのサービスであるAmazon RDS(以下,RDS)などがあります。これらのサービスはフルマネージド型のサービスとなっており,可用性が高く,アクセスが増えてくると自動的にスケールする機能(ELB)や,1台のホストに障害があった場合に自動的に切り替わるといった機能(RDS)があります。これらの機能はたいへん便利なのですが,その特性をきちんと理解していないと思わぬトラブルに遭遇する場合があります。

次のトラブルは図2のような構成のシステムで発生しました。Web/アプリケーションサーバからデータベースの参照は,HAProxyを経由して2台のRDSリードレプリカに負荷分散されています。しかしあるときを境に,このRDSへの負荷分散がある特定のRDSに対して負荷分散されないという状態になりました。参照系の負荷分散に失敗していることで参照クエリが1台のホストに集中してしまい,負荷が高まっているようでした。

図2 上級編の想定システム

図2 上級編の想定システム

監視サーバは負荷分散されていないRDSの障害は検知しておらず,現時点ではサービスにも大きな影響は出ておりませんでしたが,影響が出る前に対応をすることになりました。

原因調査と対策例

初級編のトラブルではメンテナンス拠点からサーバへの接続に関する問題でしたが,システム間の接続に問題があった場合も同じようなステップで対応します。

今回の場合はHAProxy経由でRDSにアクセスしている構成となるため,HAProxyが出力するログ図3やMySQLクライアントでHAProxyを経由してアクセスしてみた結果図4を見てみましょう。

図3 HAProxyが出力するログ

Feb 6 16:58:45 localhost haproxy[10512]: Server mysql/read1 is DOWN, reason: Layer4 connection problem, info: "Connection refused", check duration: 2ms. 1 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue.

図4 MySQLクライアントでHAProxyを経由してアクセス(失敗)

$ mysql -u root -p -h 127.0.0.1 -P 3306
Enter password:
ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 0

HAProxyのログは,バックエンドのRDSへの接続に失敗していることを示しています。HAProxyがRDSへの接続に失敗しているため,そのホストへ参照クエリを分散しないような状態となっていると推測できます。MySQLクライアントを使って,HAProxy経由でRDSに接続しようとしてもやはり失敗します。

今回の場合も監視サーバからは障害を検知していませんが,RDSに何かしらの障害がおきているのでしょうか? 初級編の場合は低いレイヤから確認して問題の切り分けをしましたが,今回の場合はその前に1つステップをはさみます。前述したとおり,アプリケーションはHAProxyを経由してRDSに接続をしていますので,できるだけ構成をシンプルな状態にするのです。今回の場合,HAProxyを経由することなく直接RDSに接続すると,監視サーバからアクセスができるのと同じようにRDSにアクセスができました。

ここまでの内容をまとめると,HAProxyを経由した場合だけRDSとの接続に失敗しているようですが,具体的な理由まではわかっていません。このような場面での切り分け例として,tcpdumpコマンドなどで通信をキャプチャすることが考えられます。

図5の例はWebサーバ内でtcpdumpコマンドを実行し,3306ポートへの通信をキャプチャした例となります。この中で,ip-10-0-1-76.ap-northeast-1.compute.internal.mysqlというのはRDSにローカル通信した場合の接続先であり,そこに通信しようとしていることがわかります。ここで表示されている接続先と,RDSのエンドポイントを名前解決した結果を比較してみましょう。

図5 tcpdumpコマンドを実行し,3306ポートへの通信をキャプチャ

$ sudo tcpdump dst port 3306
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
15:04:59.745944 IP ip-10-0-0-21.ap-northeast-1.compute.internal.34921 > ip-10-0-1-76.ap-northeast-1.compute.internal.mysql: Flags [S], seq 188805037, win 17922, options [mss 8961,sackOK,TS val 265836392 ecr 0,nop,wscale 7], length 0

エンドポイントを名前解決した結果図6が,HAProxyが接続しようとしていたものと異なる結果となりました。HAProxyが特定のリードレプリカに接続ができていない問題は,これが原因で間違いないようです。HAProxyは起動時に設定ファイルで指定された接続先を名前解決して,結果をキャッシュするようになっています。RDSは稼働するホストに障害が発生した場合にホストの自動交換機能で,ハードウェアが自動的に交換されますが,そのとき内部的にローカルIPアドレスが変更されてしまうのです。

図6 RDSの接続先をdigコマンドで名前解決

$ dig rds-slave02.a1b2c3d4f5g6.ap-northeast-1.rds.amazonaws.com any

; <<>> DiG 9.9.4-RedHat-9.9.4-14.el7_0.1 <<>> rds-slave02.a1b2c3d4f5g6.ap-northeast-1.rds.amazonaws.com.com any
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 413
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;rds-slave02.a1b2c3d4f5g6.ap-northeast-1.rds.amazonaws.com. IN ANY

;; ANSWER SECTION:
rds-slave02.a1b2c3d4f5g6.ap-northeast-1.rds.amazonaws.com. 5 IN A 10.0.1.32

;; Query time: 4 msec
;; SERVER: 10.0.0.2#53(10.0.0.2)
;; WHEN: 月 2月 09 16:12:13 JST 2015
;; MSG SIZE rcvd: 107

このようなミスマッチで通信に影響が出る場合もありますので,クラウドや使用しているアプリケーションの特徴を理解して設計する必要があります。

今回の構成ではRDS側のローカルIPアドレスが変更される可能性が考慮されておりませんでしたが,RDSのローカルIPアドレスが変更されるようなイベントが発生した場合に,HAProxyを再起動して名前解決をしなおすようなしくみが必要となります。


[クラウド編]ではクラウド環境におけるトラブル対応について,AWSを例にして解説しました。IaaS系のクラウドサービスはさまざまありますが,サービスごとにそれぞれ特徴が違ってきますので,それらを理解して使いこなす必要があります。また,クラウドではバックアップから新しいサーバをすばやく用意することもできます。こういった特徴を活かして,新しいサーバを使ってサービスの復旧を優先するという考え方も大切になります。

トラブルシューティングをする場合の基本的な方針はオンプレミスでもクラウドでもあまり大きな差はありませんので,しっかりと基礎技術を身につけることが大切になると思います。

Software Design

本誌最新号をチェック!
Software Design 2021年7月号

2021年6月17日発売
B5判/184ページ
定価1,342円
(本体1,220円+税10%)

  • 第1特集
    先駆けに学ぶゼロトラストの現実解
    リモートワークに必須のセキュリティモデル
  • 第2特集
    IT技術の総力戦
    ISUCONで学ぶパフォーマンスチューニング
  • 特別企画
    WSL 2本格入門
    何ができるか,どこまでできるか
  • 特別企画
    5分で試す,機械学習を用いたワクチン開発の世界
    自然言語処理技術との類似と相違
  • 短期連載
    GitOpsで作るKubernetesのCI/CD環境
    [1]GitOps超入門

著者プロフィール

柳瀬任章(やなせひであき)

株式会社サーバーワークス サービス開発課

オンプレミス環境のインフラエンジニアとしてキャリアをスタートさせ,クラウドの登場をきっかけにAWSの導入支援を担当するようになる。通常業務の傍らAWSに関連するイベントでの登壇や書籍への寄稿に携わり,現在はAWSの運用自動化サービスCloud Automatorの開発を担当している。「Amazon Web Services実践入門」共著者。

Twitter:@oko_chang

著書

バックナンバー

トラブルシューティングの極意―達人に訊く問題解決のヒント

バックナンバー一覧