EC2 アプリケーションステータスチェック — ロードバランサ無しでアプリ層を死活監視する機能を触ってみた
はじめに
こんにちは、ryoです。
先日 8 月 10 日に Amazon EC2 にアプリケーションステータスチェック機能が導入されたとアナウンスがありました。
Amazon EC2 application status checks のアナウンス
ALB/NLB を使わない単体 EC2 構成でアプリ層の死活監視をどう実現するかは以前から課題に感じていたため、早速触ってみました。
本記事では、単体 EC2 に Application status checks を設定し、CloudWatch でどのように表示されるか、アラーム連携でどう通知できるかを中心に紹介します。
検証環境
| 項目 | 値 |
|---|---|
| AWS CLI | aws-cli/2.36.20(※本機能の CLI コマンドは最新版でないと対応していません) |
| リージョン | ap-northeast-1 |
| Amazon EC2 インスタンス | t3.micro x 1 台(Amazon Linux 2023) |
| アプリ | nginx(/health → HTTP 200) |
| チェック設定 | customer-managed、HTTP :80 /health、matcher 200 |
本記事のターゲット読者
- ALB/NLB を使わない単体 Amazon EC2 で Web/API サーバーを動かしていて、「プロセスは生きているのにアプリが 500 を返し続ける」ようなアプリ層の障害をマネージドに検知したい人
- ロードバランサーのターゲットグループヘルスチェックに頼らず、Amazon EC2 単体でアプリ層の死活監視を完結させたい人
- CloudWatch アラームや SNS 通知と連携させて運用に組み込みたい人
アプリケーションステータスチェックとは
Amazon EC2 インスタンス上のアプリケーションに対して、AWS が VPC 内から HTTP/HTTPS ヘルスチェックを 60 秒間隔で送り、応答コードで健全性を判定する新しいマネージド機能です。
従来「アプリ層の死活監視」に必要だった ALB/NLB のターゲットグループや自前 AWS Lambda + カスタムヘルスチェックを、ロードバランサー無しで Amazon EC2 ネイティブに実現する点が、ありそうで無かった機能です。
なぜ嬉しいのか — 従来との差
Amazon EC2 には従来から 2 種類のステータスチェックがありました。
- System status check: AWS 基盤(ハイパーバイザー、ネットワーク、電源)側の問題
- Instance status check: OS の到達性(起動失敗、カーネルパニック、ネットワーク設定ミス等)
どちらも「アプリが実際にリクエストに応答しているか」は見ません。
プロセスがハングしてタイムアウトしても、OS が生きていれば両方エラーは検知しません。
そのため従来アプリ層まで見るには以下の方法が必要でした。
- ALB / NLB のターゲットグループヘルスチェックを使う(=ロードバランサーが必要)
- Route 53 ヘルスチェック(外形監視、public 前提になりがち)
- 自前で AWS Lambda + カスタムヘルスチェックを組む
Application status checks はロードバランサーも自前実装も無しに、Amazon EC2 単体でアプリ層の HTTP/HTTPS ヘルスチェックを行えます。
つまり ALB/NLB を入れるほどではない単体 EC2 構成でも、マネージドにアプリの死活監視ができるようになった――ここが一番の新しさです。
やってみた
単体 EC2 インスタンスに Application status checks を設定し、正常時・異常時の動作と CloudWatch での見え方を確認します。
仕組みを簡潔に
- AWS が VPC 内の観測点から、インスタンスの
:port/pathに 60 秒ごとに HTTP/HTTPS リクエストを送る - 応答コードを設定した status code matcher と照合し、連続 2 回失敗で
impaired、連続 2 回成功で復帰などの設定が可能 - 単体 EC2 の場合、
impairedを CloudWatch メトリクスとして検知し、アラーム→SNS 通知や Systems Manager Automation による自動復旧に連携できる
チェックのリクエストは HTTP/2 で送られ、public インターネットは経由せず AWS 内部ネットワークを通ります。
HTTPS チェックはサーバー証明書を検証しないので、自己署名証明書でも問題ありません。
内部で何が起きているか(ネットワーク図)
VPC 内のマネージド ENI を経由したヘルスチェックの経路

到達のために AWS が VPC 内にマネージド ENI を作ります。
ENI は「source subnet x security group の組合せごとに 1 本」です。
この ENI はインスタンスの ENI 上限には数えられませんが、リージョン あたりの ENI 上限には数えられるので、上限が枯渇しているとチェックが動かない点に注意してください。
使ってみる(AWS CLI)
1. チェックを作る
以下のコマンドでチェックを作成します。
--health-check-paths を付けなければ AWS managed モード(source/destination を AWS が自動選定)、付ければ customer-managed モードになります。
aws ec2 create-application-status-check \ --protocol http --port 80 --path /health --status-code-matcher 200
customer-managed モードでは、ヘルスチェックの送信元 subnet/SG を明示的に指定できます。
セキュリティグループルールで送信元を把握・制御したい場合はこちらを選んでください。
--status-code-matcher は単一コードだけでなく 200,202,300-399 のような列挙・範囲指定が可能です(最大 64 文字)。
2. インスタンスに関連付ける
作成したチェックを単体インスタンスに関連付けます。
aws ec2 associate-application-status-check \ --application-status-check-id asc-xxxxxxx \ --instance-ids i-xxxxxxxx
※
asc-xxxxxxxは作成時に返されたチェック ID、i-xxxxxxxxは対象インスタンス ID に置き換えてください。
タグベースでの一括指定にも対応しているため、同じ用途のインスタンスが複数ある場合はタグで管理すると楽です。
aws ec2 associate-application-status-check \ --application-status-check-id asc-xxxxxxx \ --target-tag-associations Key=Environment,Value=production
3. 結果を見る
describe-application-status コマンドでチェック結果を確認できます。
正常時は Status: passed、失敗時は Reason にアプリが返した HTTP コードが入るので、原因切り分けがそのままできます。
aws ec2 describe-application-status --instance-ids i-xxxxxxxx
※
i-xxxxxxxxは対象インスタンス ID に置き換えてください。
CloudWatch での表示
Application status checks の結果は自動的に CloudWatch メトリクスとして送信されます。
ここが単体 EC2 構成にとって嬉しい点で、追加設定なしに監視基盤に乗ります。
メトリクスの確認
CloudWatch コンソール > メトリクス >クラシックメトリクス > EC2 > インスタンス別メトリクス で、以下のメトリクスが確認できます。
| メトリクス名 | 意味 |
|---|---|
StatusCheckFailed_Application |
アプリケーションステータスチェックの失敗有無 |
CloudWatch アラームとの連携
単体 EC2 で Application status checks を活用するなら、CloudWatch アラーム + SNS 通知の組み合わせが基本パターンです。
SNS トピックの作成とサブスクリプション設定
アラームの通知先となる SNS トピックを事前に作成し、通知先(メール等)を登録しておきます。
# SNS トピック作成 aws sns create-topic --name my-alert-topic # メール通知のサブスクリプション追加 aws sns subscribe \ --topic-arn arn:aws:sns:ap-northeast-1:123456789012:my-alert-topic \ --protocol email \ --notification-endpoint your-email@example.com
※
123456789012は自身の AWS アカウント ID、your-email@example.comは通知先メールアドレスに置き換えてください。
subscribe 実行後に確認メールが届くので、メール内のリンクをクリックして承認してください。
承認が完了するまで通知は配信されません。
アラームの作成例
SNS トピックの準備ができたら、CloudWatch アラームを作成して通知と紐付けます。
aws cloudwatch put-metric-alarm \ --alarm-name app-status-check-failed-i-xxxxxxxx \ --namespace AWS/EC2 \ --metric-name StatusCheckFailed_Application \ --dimensions Name=InstanceId,Value=i-xxxxxxxx \ --statistic Maximum \ --period 60 \ --evaluation-periods 1 \ --threshold 1 \ --comparison-operator GreaterThanOrEqualToThreshold \ --treat-missing-data breaching \ --alarm-actions arn:aws:sns:ap-northeast-1:123456789012:my-alert-topic
※
i-xxxxxxxxは対象インスタンス ID、123456789012は自身の AWS アカウント ID に置き換えてください。
--treat-missing-data breaching を指定することで、メトリクスのデータが届かない場合(データ不足)もアラーム状態として扱います。これを設定しないと、メトリクス名の誤りやデータ欠損時にアラームが発火せず通知が届かない原因になります。
EC2 アクションによる自動復旧
さらに、アラームアクションとして EC2 のリカバリーアクションを設定すれば、
インスタンスの自動再起動も可能です。
aws cloudwatch put-metric-alarm \ --alarm-name app-status-check-auto-recover-i-xxxxxxxx \ --namespace AWS/EC2 \ --metric-name StatusCheckFailed_Application \ --dimensions Name=InstanceId,Value=i-xxxxxxxx \ --statistic Maximum \ --period 60 \ --evaluation-periods 3 \ --threshold 1 \ --comparison-operator GreaterThanOrEqualToThreshold \ --alarm-actions arn:aws:automate:ap-northeast-1:ec2:reboot
※
i-xxxxxxxxは対象インスタンス ID に置き換えてください。
上記の例では連続 3 分間チェック失敗が続いた場合にインスタンスを reboot します。
ec2:recover(ハードウェア障害時のリカバリー)ではなく ec2:reboot を使っているのは、アプリ層の問題は OS 再起動で解決するケースが多いためです。
なお、reboot による自動復旧を機能させるには、アプリ(nginx 等)が OS 起動時に自動起動する設定になっていることが前提です。
自動起動が無効だと、reboot 後もアプリが停止したまま → ヘルスチェック失敗 → 再度 impaired という無限ループに陥ります。
導入する際の考慮事項
セキュリティグループの設定
ヘルスチェックのリクエストはマネージド ENI から届くため、インスタンスのセキュリティグループでチェック対象ポート(今回は 80)のインバウンドが許可されている必要があります。
customer-managed モードで送信元 SG を指定すれば、その SG からのアクセスだけ許可するルールで済みます。
Suppress(抑止)の活用 — メンテナンス中の誤検知防止
デプロイやパッチ適用中はアプリが一時停止するため、何も対策しないと impaired 判定 → アラーム発報になってしまいます。
Suppress 機能を使えば、指定時間だけチェックを抑止できます。
# デプロイ開始前(1 時間ぶん抑止) aws ec2 enable-application-status-check-suppression \ --instance-ids i-xxxxxxxx --duration-seconds 3600
--duration-seconds を指定すると、指定時間経過後に自動で抑止が解除されます。
デプロイ完了後は disable-application-status-check-suppression で明示的に解除もできます。
本番に新しいチェックを足すときの安全手順
いきなり有効化すると、設定ミスで不要なアラームが鳴り続ける…という事故になりかねません。
段階的に導入するのが安全です。
- チェックを作成し、インスタンスに関連付ける
- 2 インターバル(約 2 分)待つ
describe-application-statusで期待どおりの status / HTTP コードを確認- 問題なければ CloudWatch アラームを設定して本番運用開始
料金とクォータ
料金はマネージド ENI 1 本あたり $0.01 / ENI-Hour + メトリクスは標準 CloudWatch 料金です。
Price List API でも us-east-1 / 東京とも AppStatusCheck-ENI-Hours = $0.01/h を検証環境で確認しました。
課金は監視インスタンス台数ではなく ENI 本数(= source subnet x SG の組合せ数 x AZ)で効くのがポイントです。
同じ subnet+SG に 100 台いても ENI は 1 本 = $0.01/h で済みます。
主なクォータ(既定)は以下のとおりです。
- アカウントあたりチェック数: 50
- チェックあたり関連付け: 50
- アカウントあたり関連付け: 200
- アカウントあたり target: 5,000(要申請)
まとめ
単体 EC2 でアプリを動かしていて「アプリ層の死活監視が手薄だった」という方には、まさに待望の機能だと感じました。
CloudWatch アラームとの連携もシンプルなので、まずは開発・ステージング環境で試して感触を掴んでみてはいかがでしょうか。
最後まで読んでいただきありがとうございます!
参考資料
営業・インフラエンジニアを経てクラウドへ転向。VMware関連の知識も強みのひとつです。セキュリティ・IaCにも高い関心を持っています。休日はサウナかご飯食べてます。
Recommends
こちらもおすすめ
-
Docker Composeで3層ウェブアーキテクチャを構成する
2019.3.15
-
AWS無料セミナー開催レポート | 大人気のAWS入門セミナー
2018.11.17
Special Topics
注目記事はこちら
データ分析入門
これから始めるBigQuery基礎知識
2024.02.28

AWSの料金が 10 %割引になる!
『AWSの請求代行リセールサービス』
2024.07.16
