はんドンクラブにおいて,以下の障害が発生していましたが,現在は復旧しています。ご迷惑をおかけしたことをお詫びいたします。
- 日時: 2019年11月19日 15:05:13 〜 2019年11月19日 19:02:19 (JST)
- 影響範囲: はんドンクラブの全ユーザ
- 障害内容: 特定の画像が表示されない
- 原因:Webサーバ設定が不適切であり,利用している外部サービスのIPアドレス変更に追従できなかったため
- 解決方法: 暫定的にはWebサーバの再起動で回復済。
本格対処は11月21日までに実施予定11月20日23:50頃に本格対処完了
障害の発生メカニズム
はんドンクラブでは,メディア(トゥートに添付された画像や動画,またはアイコン画像など)は,Conohaのオブジェクトストレージに保存されています。このオブジェクトストレージ内のメディアへのアクセス用URLをWebページのドメイン(handon.club)と同一ドメイン(media.handon.club)にするため,はんドンクラブサーバ内のnginxでリバースプロキシを使っています。
media.handon.club における nginx.conf
は,以下のようになっていました(一部抜粋)。
server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name media.handon.club; ~~~中略~~~ add_header Cache-Control "public, max-age=31536000, immutable"; location / { proxy_pass https://object-storage.tyo2.conoha.io/v1/xxxxxxx/xxxxxxx/; ~~~中略~~~ } }
よく知られた問題として,proxy_pass
にドメインを書いた場合,nginxの起動時にのみ名前解決が行われます。そのため,nginx起動後にDNSレコードの変更があった場合でも,OS側のTTL設定に依らず,レコード変更に追従することができません。つまり,手動でnginxを再起動するまで,永遠に古いDNSレコードが使われつづけてしまいます。
今回の障害の原因については,前述のnginxの仕様により,オブジェクトストレージのグローバルIPアドレス変更に追従できなかったためです。conoha側で何らかの理由で object-storage.tyo2.conoha.io
のIPアドレスが変更されましたが,はんドンクラブのnginxは古いIPアドレスへアクセスし続けてしまうため,結果としてユーザが画像を表示できない状態になっていました。
なお,古い画像には通常通りアクセスできていました。これは, media.handon.club が CDN によりキャッシュされているためです。前述の nginx.conf
のとおり,一度アクセスした画像は,最大で31,536,000秒間CDNサービスのCloudflareにキャッシュされます(あれ,そういえば,Cloudflareってこのヘッダをちゃんと尊重してくれるんでしたっけ??)。そのため,キャッシュされているアイコン画像や古いトゥートに添付された画像はアクセスが出来るが,1度もアクセスがなかった画像にはアクセスができなかった・・・・ということになります。
なお管理人は,この proxy_pass
の挙動について認識こそしていたものの,正しくない設定をしてしまいました。原因は,media.handon.club サーバについてはあまり深く考えずに各種設定を行っており,チェック漏れが発生したためです。要するに管理人の凡ミスです。
障害に気づくのが遅れた理由
今回の障害はユーザ申告により発覚しました。そのため,管理人が問題を把握したのは問題発生から3時間以上経過した18:30頃でした。こちらの原因について説明します。
はんドンクラブでは,media.handon.club については,1分に1回HTTPSリクエストを送ることで死活監視を行っています。そして,連続してアクセスエラーが発生すると,管理人と副管理人のLINEに通知される仕組みとなっています。そのため,サーバ障害に対しては速やかにその発生を認知出来るはずでした。
しかし,この死活監視は,常に同じエンドポイントに対して実施していました。そのため,当然CDNにキャッシュされているページに対して死活監視していたことになります。そのため,今回のように,新たにアップロードされている画像に限定して再現する障害では,アラートが上がらない状態となっていました。
今後の改善
nginx.conf
については修正を行います。- 死活監視方法の変更による早期障害検知は現実的ではないため,リスクを許容することとします。
- 新しくアップロードされた画像に対するポーリング監視は,適切なエンドポイントが分からないため現実的ではありません
- ただし,長期的には,ユーザの申告をより簡単かつ速やかに受け付けられる仕組みを検討し,リスクを軽減します
(11/20追記)以下のように設定変更しました。
server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name media.handon.club; ~~~中略~~~ add_header Cache-Control "public, max-age=31536000, immutable"; location ~ /(.*) { resolver 8.8.4.4 1.0.0.1 valid=360s; set $container "object-storage.tyo2.conoha.io/v1/xxxxxxx/xxxxxxx"; proxy_pass https://$container/$1$is_args$args; ~~~中略~~~ } }