EC2 Linux インスタンスでの、インスタンスメタデータの問題をトラブルシューティングする方法を教えてください。
Amazon Elastic Compute Cloud (Amazon EC2) Linux インスタンスからインスタンスメタデータを取得できません。
簡単な説明
Amazon EC2 は、IPv4 エンドポイント 169.254.169.254 または IPv6 エンドポイント [fd00:ec2::254] への HTTP リクエスト経由でインスタンス内のインスタンスメタデータにローカルでアクセスします。インスタンスメタデータにアクセスするには、インスタンスメタデータサービス (IMDS) を使用する必要があります。IMDSv1 は認証トークン必要としませんが、IMDSv2 はセキュリティを強化するためにセッショントークンを必要とします。
インスタンスメタデータを取得する際に、次の問題が発生する可能性があります。
- タイムアウトや HTTP 400、404 エラーなどの HTTP リクエストエラー
- IMDSv2 トークンリクエストでの障害
- ソフトウェア固有の処理に関する問題
- ネットワークインターフェイスまたはルートテーブルの設定ミス
- プロキシまたは NAT ゲートウェイの構成が原因でメタデータアクセスがブロックされる
- (IPv6 のみ) IMDSv6 エンドポイントが有効にならない
- AWS Identity and Access Management (IAM) インスタンスプロファイルのアタッチメントが欠けているか、古くなっている
- iptables、firewalld などのローカルファイアウォールが 169.254.169.254 へのアクセスをブロックしている
- 大量のリクエストが原因で、メタデータリクエストが制限される
解決策
注: AWS コマンドラインインターフェイス (AWS CLI) コマンドの実行中にエラーが発生した場合は、「AWS CLI で発生したエラーのトラブルシューティング」を参照してください。また、AWS CLI の最新バージョンを使用していることを確認してください。
HTTP リクエストエラーを解決する
発生した HTTP エラーコードに応じて、次のトラブルシューティング手順を実行します。
(IMDSv1 のみ) 「404 - Not Found」エラー
HTTP 404 エラーは、無効な URL を入力した場合や、インスタンスの IAM ロールを更新したもののロールを更新しなかった場合に発生します。
このエラーを解決するには、正しい URL を使用していることを確認してください。さらに、インスタンスの IAM ロールをデタッチしてから再アタッチするようにしてください。
次に、インスタンスを起動、停止して変更を適用します。
(IMDSv2 のみ) 「400 - Bad Request」エラー
HTTP 400 エラーは、PUT リクエストで無効なトークンを使用したり、ソフトウェアが誤ったヘッダーを送信したりした場合に発生します。たとえば、FortiGate または Matillion エージェントの中には、IMDSv2 トークンをキャッシュしたり再利用したりしないものがあります。
このエラーを解決するには、次のコマンドを実行して PUT リクエスト用の新しいトークンを生成します。
$ TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl
さらに、システムログまたはアプリケーションログを調査し、長時間実行しており、トークンの更新を要するプロセスがないかを確認します。
(IMDSv2 のみ) 「401 - Unauthorized」エラー
HTTP 401 エラーは、GET リクエストで無効なトークンを使用した場合に発生します。
このエラーを解決するには、次のコマンドを実行して GET リクエスト用の新しいトークンを生成します。
$ curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/
さらに、システムログまたはアプリケーションログを調査し、長時間実行しており、トークンの更新を要するプロセスがないかを確認します。
「403 Forbidden」エラー
HTTP 403 エラーは、インスタンスレベルで IMDS を無効にした場合や、セキュリティグループ、ファイアウォール、またはルートテーブルによりインスタンスアクセスがブロックされた場合に発生します。このエラーは、IMDSv2 を使用する必要があるものの、クライアントが IMDSv1 を使用した場合にも発生する可能性があります。
この問題を解決するには、次の AWS CLI コマンド describe-instances を実行して IMDS の設定を確認してください。
aws ec2 describe-instances --instance-ids your_instance_id --query 'Reservations[].Instances[].MetadataOptions'
注: your_instance_id を実際のインスタンス ID に置き換えます。
HttpEndpoint が disabled に設定されている場合は、次の modify-instance-metadata-options コマンドを実行して IMDS を有効にします。
aws ec2 modify-instance-metadata-options --instance-id your_instance_id --http-endpoint enabled
注: your_instance_id を実際のインスタンス ID に置き換えます。
設定がインスタンスから 169.254.169.254 (IPv4) または [fd00:ec2::254] (IPv6) へのアウトバウンド HTTP アクセスを許可していることを確認してください。
インスタンスがプロキシ、NAT 構成、ロードバランサー、または複数の内部ネットワークホップを使用する場合、HttpPutResponseHopLimit を 2 以上に設定することをおすすめします。トークンの応答がネットワーク層を通過できるように、十分に高いホップ値を設定します。デフォルトでは、HttpPutResponseHopLimit は 1 ホップのみを許可します。この値を増やすには、次の modify-instance-metadata-options コマンドを実行します。
aws ec2 modify-instance-metadata-options --instance-id your_instance_id --http-put-response-hop-limit 2
注: your_instance_id を実際のインスタンス ID に置き換えます。
プロキシ設定に問題がないか確認する
インスタンスがプロキシを使用してインターネットにアクセスする場合、プロキシのトラフィックから IMDS の IPアドレスを除外する必要があります。そうしないと、HTTP 403 や 404 エラー、または接続タイムアウトが発生する可能性があります。
プロキシから IMDS の IPアドレスを除外するには、次のコマンドを実行して no_proxy 環境変数を設定します。
export no_proxy='169.254.169.254,[fd00:ec2::254]'
注: Matillion、Fortigate、カスタムサービスなどの一部のアプリケーションでは、システムレベルの no_proxy 設定を使用しない場合があります。この場合は、アプリケーションで no_proxy を設定します。デュアルスタック構成では、IPv4 と IPv6 の両方のメタデータエンドポイントを除外します。
IPv6 サポートが有効であることを確認する
IPv6 のみのサブネットを使用する場合は、次の modify-instance-metadata-options コマンドを実行し、IMDS で IPv6 サポートを明示的に有効化します。
aws ec2 modify-instance-metadata-options \ --instance-id your_instance_id \ --http-protocol-ipv6 enabled
注: your_instance_id を実際のインスタンス ID に置き換えます。
厳密なセキュリティグループのルールが設定された仮想プライベートクラウド (VPC) エンドポイントを使用する場合は、メタデータの IP アドレスへのアクセスがポート 80 (HTTP) で許可されていることを確認してください。
Fortigate または Matillion アプリケーションでは、ソフトウェアが IMDSv2 セッショントークンをサポートしていることを確認してください。
ネットワーク構成や、IAM ロールの関連付けが古くなっていたり、内部ソフトウェアに問題があったりする場合のトラブルシューティング
インスタンスを再起動します。
ローカルファイアウォールのルールを確認する
ローカルのファイアウォールブロックが iptables を使用しており、IMDS エンドポイントへのアクセスをブロックしているかどうかを確認するには、次のコマンドを実行します。
sudo iptables -L
ブロックされたエンドポイントの出力例:
Chain OUTPUT (policy ACCEPT) target prot opt source destination REJECT tcp -- anywhere 169.254.169.254 owner UID match 1000-10000 reject-with icmp-port-unreachable
169.254.169.254 へのトラフィックをブロックするルールがないか確認するには、次のコマンドを実行します。
curl http://169.254.169.254/latest/meta-data/
ルールがトラフィックがブロックしている場合、次の例のような出力が表示されます。
curl: (7) Failed to connect to 169.254.169.254 port 80 after 0 ms: Connection refused
ブロックを行うルールを削除するには、次のコマンドを実行します。
sudo iptables -D OUTPUT -p tcp -d 169.254.169.254 -m owner --uid-owner 1000-10000 -j REJECT
インスタンスがデュアルスタックの場合は、IPv6 ファイアウォールルールが [fd00:ec2::254] の IPv4 アドレスをブロックしていないことを確認してください。iptables が空でもトラフィックがブロックされる場合は、firewalld、ufw など、オペレーティングシステム (OS) のファイアウォールデーモンを確認してください。ウイルス対策ソフトウェアやファイアウォールソフトウェアなどのセキュリティエージェントも確認してください。これらのソフトウェアは、隠しルールを適用する可能性があります。
Amazon EC2 によりリクエストがスロットリングされたかどうかを確認する
Amazon EC2 は、1 秒あたりのパケット数 (PPS) に基づいて IMDS へのトラフィックを制限します。インスタンスにアタッチされた各 Elastic ネットワークインターフェイスでは、メタデータに関連するトラフィックの最大クォータは 1024 PPS に設定されています。PPS レートがこのクォータを超えると、「HTTP 5xx」エラーが発生したり、メタデータを取得できなかったり、アプリケーションがタイムアウトしたりします。
スロットリングの問題を軽減するには、次の手順を実行します。
- アプリケーションに、IMDS へのアクセス時に行われるエクスポネンシャルバックオフと再試行ロジックを実装します。
- ベンダーに問い合わせるか、ソフトウェアを最新バージョンに更新したうえで、IMDSv2 がサポートされていることを確認してください。
- IMDSv2 を使用する際、トークンを一度生成し、有効期間 (TTL) 中に複数のメタデータクエリに再利用してください。
- 最新の IMDSv2 バージョンにアップグレードし、構成でトークンの再利用とエクスポネンシャルバックオフが正しく実装されていることを確認してください。
- インスタンスメタデータを頻繁にポーリングしないでください。
- 可能な限り、アプリケーションではインスタンスキャッシュを使用してください。
ソフトウェアがメタデータ要求を遅延なしで大量に行う場合、スロットリングやメタデータの不具合が発生する可能性があります。tcpdump、strace、またはアプリのデバッグログを参照し、169.254.169.254 への呼び出しが頻繁に行われていないかどうかを確認します。スロットリングイベントを監視するには、次のコマンドを実行し、ネットワークインターフェイスドライバーで linklocal_allowance_exceeded メトリクスを確認します。
ethtool -S eth0
注: eth0 を実際のネットワークインターフェイス名に置き換えます出力で linklocal_allowance_exceeded の値が 0 になっていないか確認し、スロットリングを識別します。
出力例:
linklocal_allowance_exceeded: 245
上記の出力例は、PPS クォータを超えたことが原因で、Amazon EC2 により IMDS への 245 パケットがスロットリングされたことを示しています。
