背景
あるとき Fargate 1.4 で動くバッチタスクがエラーをはくようになった。
内容は Error retrieving credentials from the instance profile metadata service.
で、タスクのメタデータエンドポイントから認証情報を取得できないというもの。
エラーの原因
タスクは PHP SDK を利用しており、 CloudWatchClient を生成するときに発生したもののようだった。
Client 生成時に渡すクレデンシャルとして通常 Access Key/Secret Key を指定するが、必ずしもセキュアな方法とはいえないため、代わりにタスクの IAM ロールを利用する方法を採用していた。
このとき、SDK はタスクのメタデータエンドポイントに問い合わせを行い、レスポンスから一時的な認証情報を取得する。
https://docs.aws.amazon.com/ja_jp/sdk-for-php/v3/developer-guide/guide_credentials_assume_role.html
エラーの原因は、エンドポイントへのアクセスがしきい値を超えることでスロットリングが生じたことによるものだった。
Client を大量に生成している実装などがあればわかるのだが、当該タスクは起動~終了のライフサイクル内で 1 度しか生成を行わない。
スロットリングのしきい値
ECS on EC2 であれば環境変数 ECS_TASK_METADATA_RPS_LIMIT
から確認・変更が可能。
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/ecs-agent-config.html
一方で Fargate タイプの場合は公開されていない、かつ変更が不可能。
複数の Fargate タスクがひとつの EC2 上で動くことへの意識
本問題の対策としては「Access Key/Secret Key を使う方法」「Credential をキャッシュする方法」などをサポートに教えてもらった。だが結局、本問題は数日経ったら解消した。
これは想像にしかすぎないが、タスクメタデータエンドポイントは他テナントのユーザーと共有されていることから、どこぞの誰かのタスクが「やらかし」てエンドポイントへのアクセスが一時的に増大し、巻き添えをくらってしまったのではないか?
また、この件に限らず、Fargate はタスクが起動できないなど不安定になることが稀にある。
Fargate に関する障害の原因調査をするときに「必ずしもタスク自身に問題があるわけではない」という観点が抜けていると、調査が難航してしまいそうな印象を受けた。若干厄介な性質だがそれ以上のメリットも享受しているので、うまく付き合いながら活用していければと思う。
参考
https://aws.amazon.com/jp/blogs/news/under-the-hood-fargate-data-plane/
https://dev.classmethod.jp/articles/reinvent2019-aws-fargate-under-the-hood-con423/