二度手間に思えた手順について調べてみたら
AWS Lambdaのコンテナイメージ制限が判明した話
AWS Lambdaのコンテナイメージ制限が判明した話
こんにちは。
クラウド活用推進担当、新人の榊原です。はじめてのブログ投稿になります。よろしくお願いします。
Sysdig Secureはワークロードの脅威をリアルタイムで検出するツールです。
そんなSysdig Secureのサーバレスエージェントを、公式ドキュメントの手順に従ってデプロイする際、
気になることがあったので調べてみたら、AWS Lambdaが持つコンテナイメージ制限に行き当たりました。
今回はその調査内容についてまとめたいと思います。
ECSonFargateへのSysdig Secureサーバレスエージェントのデプロイのため、公式提供のinstrumentationサービス用テンプレートを使用してCloudFormationスタックを作成していました。
参考: CloudFormationによるインストール - Sysdig Documentation
instrumentationサービスをデプロイする流れは概ね以下のようになります。
serverless-patcher
イメージを外部レジストリ(Quay.io)からpullSysdig Serverless Patcher Image
の値にプライベートECRのイメージURIを指定この手順の4番目。実施中ひとつ疑問が生まれました。直接指定してはいけないのでしょうか。
・ECRにpushしたイメージは自作したものではなく、Sysdig公式提供のものです
・pullした後、一切の変更を加えずそのままpushしています
なれば、二度手間ではないかと。
わざわざプライベートECRを経由せず、
スタック作成時にQuay.ioのイメージURIを直接指定することはできないのでしょうか。
CloudFormationテンプレートのSysdig Serverless Patcher Image
のデフォルト値は quay.io/sysdig/serverless-patcher:5.3.4
となっています。なんだか直接指定もできそうです。
にもかかわらず、プライベートECRの利用が必須とされる理由はなんなのでしょうか。
というわけで直接指定を試してみました。
CloudFormationスタック作成時に、Sysdig Serverless Patcher Image
の値としてQuay.ioのイメージURIを直接指定する。
怒られました。
以下、エラーの内容です。
結果として以下が確認できました。
失敗の原因としてぱっと思いつくのは
などなど
しかし公式がプライベートECR必須としていることなどから、Lambda自体の制限が原因となっている可能性が高いと考え、調査してみました。
AWS Lambdaのドキュメントを確認し、どのようなレジストリからイメージを取得できるのか調査しました。
AWS Lambda Developer Guideには以下のような記載を確認できます。
またAWS CLIからhelpを確認すると、以下のように記載されています。
これらを見るにLambdaからのイメージ取得には、AWS ECRへのイメージpushが必須だと思われます。
しかしこの記載だけではプライベート/パブリックの制約があるのかわかりません。
本当に外部レジストリからのイメージ取得はできないのか。ECRはプライベートもパブリックも使えるのか。
検証してみましょう。
AWS Lambdaがどのレジストリからイメージを取得できるのか検証する
レジストリ | 予想結果 | 予想理由 |
---|---|---|
Amazon ECR(private) | ✅ 成功 | Sysdig公式推奨のため |
Amazon ECR(public) | ✅ 成功 | AWSドキュメントでは制約が無さそう |
Quay.io | ❌ 失敗 | 外部レジストリ |
Docker Hub | ❌ 失敗 | 外部レジストリ |
・それぞれ異なるレジストリのイメージを取得するようにLambda関数を作成
・取得対象のイメージは無作為に決定。ECRにはあらかじめ取得可能なイメージを用意
レジストリ | イメージURI | 結果 |
---|---|---|
Amazon ECR (private) | [ACCOUNT_ID].dkr.ecr.ap-northeast-1.amazonaws.com/sysdig-serverless-patcher:5.3.4 |
✅ 成功 |
Amazon ECR (public) | public.ecr.aws/lambda/python:3.9 |
❌ 失敗 |
Quay.io | quay.io/sysdig/serverless-patcher:5.3.4 |
❌ 失敗 |
Docker Hub | nginx:latest |
❌ 失敗 |
検証の結果、予想通り外部レジストリからのイメージ取得はすべて失敗しました。 また予想に反して、パブリックECRからのイメージ取得も失敗しています。これによりLambdaで扱えるのはプライベートECRだけであることが判明しました。
失敗時のエラー内容はすべて同様で、以下のようになっています。
以上の結果から、次のことが分かりました。
当初の疑問
Q: なぜserverless-patcherイメージをECRにpushする必要があるの?
A: AWS Lambdaの仕様制限により、イメージを取得できるのはプライベートECRからのみであるため
AWS Lambdaに外部レジストリ使用の制限があり、プライベートECRからしかpullできないことは分かりました。しかしそうなると新たな疑問が生えてきます。
というのも
quay.io/sysdig/workload-agent:6.0.0
このイメージもまたserverless-patcherと同様、外部レジストリたるQuay.ioから取得されるはずです。
にもかかわらず、こちらはエラーになりません。
直上のserverless-patcherイメージはまっかっかになるのに。
なぜ片方だけエラーになるのでしょうか。
2つのイメージがCloudFormationテンプレート内でどのように指定されているか確認してみます。
1. serverless-patcher
の場合
2. workload-agent
の場合
以上の内容から、serverless-patcher
はLambda関数のイメージURIとして直接指定されているのに対し、workload-agent
は環境変数として単なる文字列が設定されていることがわかります。
つまり、workload-agent
のイメージはCloudFormationスタック作成時にはpullされないため、
エラーにならないということのようです。
スタック作成時のworkload-agent
の値が環境変数であることは確認できました。
が、となると気になることが出てきます。
・環境変数ということは、どんな文字列でもスタック作成に影響がないのか
・イメージ取得がスタック作成時でないなら、どのタイミングでpullされるのか
というわけで、追加検証いってみましょう。
workload-agent
のイメージpullがいつ実行されるかを確認する
workload-agent
に存在しないイメージURIを設定しinstrumentation
スタック作成
・存在しないイメージURIでもスタック作成は成功する
・監視対象のECSタスク起動時にイメージpullが失敗する
1. instrumentation
スタック作成: 成功
存在しないイメージURIを設定しても、スタック作成に成功しました。
Lambda関数でも設定値を確認できます。
2. 監視対象ECSタスク起動: 失敗
イメージが取得できないことを示すエラーが出力され、ECSタスク起動に失敗しました。
以上の結果から、スタック作成時のworkload-agent
は文字列として保存されるだけで、
実際のpullはECS起動時に行われることが確認できました。
ECSonFargateへSysdig Secureサーバレスエージェントをデプロイする際に気になったことを調べてみました。
二度手間に見えた手順は、AWS Lambdaの仕様上避けられない必要な手順でした。
やはり公式サマサマ。手順には従うべきということなのでしょう。
同じ疑問を持つ方の参考になれば幸いです。 ここまで読んでいただきありがとうございました。
Sysdig公式ドキュメント
・ECS on Fargate serverless agent
AWS公式ドキュメント