こんにちは!SREとして日夜クラウドの海を泳ぎ回っている筆者です。
皆さんは、AWSのアプリケーションロードバランサー(ALB)を使ってWebアプリを公開したとき、「あれ?なんだかアクセスできないぞ…」と冷や汗をかいた経験はありませんか? 画面を開くと、決まって目にするのが「504 Gateway Timeout」や「503 Service Unavailable」といった冷酷なエラーコードです。
「ALBはちゃんと動いているのに、なぜ後ろのサーバー(EC2など)が相手をしてくれないんだ!?」
そんなトラブルシューティングの現場で、私たちSREが真っ先に確認する最も重要かつ基本的なポイント、それが「ターゲットグループのヘルスチェック」です。
今回は、インフラやネットワークの世界に一歩足を踏み入れたばかりの初学者の皆さんに向けて、ALBのヘルスチェックが裏側でどうやってサーバーの生死を見極めているのかを、身近な例えを交えながら優しく紐解いていきたいと思います。一歩ずつ、しっかりと理解していきましょう!
—
1. ヘルスチェックって、そもそも何をしているの?
難しく考える必要はありません。ヘルスチェックの本質はズバリ、「お医者さんの定期検診」です。
想像してみてください。あなたは人気のレストラン(ALB)のマネージャーです。毎日たくさんのお客様(ユーザーからのリクエスト)がやってきます。あなたは、料理を実際に作るコックさんたち(EC2インスタンスやコンテナ)に仕事を割り振らなければなりません。
もし、あるコックさんが急にお腹を壊して倒れてしまったらどうでしょう? その人に注文を回し続けたら、お客様には冷めた料理が届き、店全体の信頼がガタ落ちですよね。
だからこそ、マネージャーであるALBは、一定の間隔でコックさんのもとへ赴き、こう声をかけます。
「おい、元気にしているか? 『生きてます』って返事の合言葉を言ってくれ!」
この「元気ですか?」と問いかけ、正常な返事(合言葉)が返ってくるかを監視する仕組みこそが、ヘルスチェックなのです。もし何度呼びかけても返事がない場合、マネージャーは「このコックさんは今お休み中だな」と判断し、生きている別のコックさんだけに注文を回すようになります。これが、クラウドにおける「高可用性(止まらないシステム)」の裏側のカラクリです。
—
2. どのプロトコルを使う? HTTP・HTTPS・gRPCの選び方
ALBがターゲット(サーバー)の生死を確認するとき、いくつかの「言葉(プロトコル)」を使うことができます。代表的な3つを見ていきましょう。
HTTP / HTTPS ヘルスチェック
最も王道で、Webアプリの監視で一番使われる方法です。
ALBは、決まったURL(例: /healthz や /index.html)に対して、ブラウザがアクセスするのと同じように GET リクエストを投げます。
- HTTP: 暗号化なしでストレートに聞きに行きます。
- HTTPS: 証明書を使って安全な通信路を作り、安全に聞きに行きます。SSL/TLS証明書の期限切れなども一緒にチェックできる優れものです。
gRPC ヘルスチェック
最近のマイクロサービスアーキテクチャで大人気の gRPC を使った通信を行っている場合に選択します。
通常のHTTPとは異なり、高速で効率的な通信を行うための専用の作法(gRPC health checking protocol)に則って、バックエンドのコンテナが元気に動いているかを厳しくチェックします。
—
3. 現場で役立つ!ヘルスチェックの主要パラメータと設定のコツ
では、実際にAWSのコンソールやIaC(TerraformやCloudFormation)で設定する具体的なパラメータを見ていきましょう。ここを適当に決めてしまうと、「本当はサーバーが元気なのに、誤検知で切り離されてしまう(チリメンジワのようなトラフィックの暴れ)」といった厄介な問題が起きます。
以下は、AWS CLIを使ってターゲットグループを作成し、ヘルスチェックを設定する際のリアルなサンプルです。
# ALBのターゲットグループを作成するコマンドの例
aws elbv2 create-target-group \
--name my-web-app-tg \
--protocol HTTP \
--port 80 \
--vpc-id vpc-0123456789abcdef0 \
--target-type instance \
--health-check-protocol HTTP \
--health-check-path /healthz \
--health-check-interval-seconds 30 \
--health-check-timeout-seconds 5 \
--healthy-threshold-count 2 \
--unhealthy-threshold-count 3 \
--matcher HttpCode=200
それぞれのパラメータが何を意味しているのか、郵便配達のたとえで見てみましょう。
① --health-check-path(チェックするパス)
- 設定値:
/healthzなど - 意味: サーバーのどの部屋(URL)のドアをノックするかを指定します。
- SREの知恵袋: アプリのトップページ(
/)を指定しがちですが、おすすめしません。トップページは裏側でデータベースの重い処理や外部API呼び出しを行っていることが多く、DBが少し重くなっただけで「サーバーが死んだ」と誤解されてしまうからです。ヘルスチェック専用の軽量なエンドポイント(例:/healthzや/ping)をアプリ側に用意し、単に「メモリとプロセスが生きています」と即座に200 OKを返す設計にするのがプロの技です。
② --health-check-interval-seconds(チェックの間隔)
- 設定値:
30秒 - 意味: 何秒ごとに「元気ですか?」と聞きに行くかのインターバルです。短すぎるとサーバーのCPU負荷になり、長すぎると障害発生時の検知が遅れます。大体のシステムでは
30秒が黄金律とされています。
③ --health-check-timeout-seconds(タイムアウト時間)
- 設定値:
5秒 - 意味: 「元気ですか?」と声をかけてから、何秒以内に返事が来なかったら「無視された(タイムアウト)」とみなすかの制限時間です。通常は
5秒あれば十分すぎるほどです。
④ 閾値(Threshold): healthy-threshold-count と unhealthy-threshold-count
ここが一番重要です!
healthy-threshold-count(正常判定の回数: 例では2):
「おや、今までお休み中だったコックさんが、2回連続で元気に返事をしてくれたぞ。じゃあそろそろ仕事に復帰してもらおう!」と、ターゲットを「健全(Healthy)」とみなすまでに必要な連続成功回数です。
unhealthy-threshold-count(異常判定の回数: 例では3):
「おい、3回連続で呼んでも返事がないぞ……これは本当に倒れているな」と、ターゲットを「不健全(Unhealthy)」とみなして切り離すまでに必要な連続失敗回数です。ネットワークのちょっとした瞬間的な瞬断で一発レッドカードを出さないための「優しさのクッション」です。
⑤ --matcher HttpCode(成功とみなすHTTPステータスコード)
- 設定値:
200 - 意味: サーバーから返ってきたHTTPステータスコードが何であれば「合格」とするかです。通常は
200ですが、アプリの仕様に合わせて200-399や、特定のコード(200,302など)を指定することも可能です。よくある失敗として、アプリがリダイレクト(302 Found)を返す仕様になっているのに、マッチャーを200だけにしていて永遠に「不健全(Unhealthy)」から抜け出せないというトラップがあります。注意しましょう!
—
まとめ:ヘルスチェックはアプリケーションの「心電図」
いかがでしたでしょうか?
ALBのターゲットグループとヘルスチェックは、一見すると無機質な設定項目の羅列に見えますが、その本質は「クラウド上のサーバーたちの命の脈拍を感じ取る、大切な心電図」です。
- アプリの構造に合わせた適切なパス(
/healthzなど)を選ぶこと - ネットワークの揺らぎを考慮した適切な閾値を設定すること
- サーバーが返すHTTPステータスコードを正しく把握すること
これらを一つずつ丁寧に押さえていくことで、夜中に突然アラートが鳴り響くような恐怖から解放され、堅牢で信頼性の高いシステムを作り上げることができます。
インフラやネットワークの世界は、私たちの身の回りの現実世界の仕組みととてもよく似ています。難しく考えず、「もし自分が郵便配達員やマネージャーだったらどうするか?」という視点を持てば、どんな複雑なクラウドサービスも必ず手なずけることができますよ。
それでは、また次回のインフラ解説でお会いしましょう!SREチームの筆者でした。
コメント