はじめに
arm64でLambda関数をデプロイせざるを得ないケースで、Layerを追加したい場合向け。 imageデプロイを使えばどうとでもなるのだが、それは根本解決にはならない。前に一度やったのだが、やり方を失念してしまったため、備忘として記録する。
Cloud9やEC2を使ってLayerを作成する方法もあるが、AWSが提供するdocker imageを使えばローカル環境であらゆるLayerを作成できるし、インタラクティブにやりたいので、本記事ではその方法について記述する。
環境
- 言語: python3.12
- OS: macOS Sonoma14.5
- RAM: 64GB
- Docker: 25.0.3
手順
このDocsで推奨されている通り、Amazon Linuxベースコンテナイメージに基づくDocker環境に依存関係をインストールしてパッケージ化する。以下の手順の参考もとはこちら。
Step.0
前提として、以下の点が満たされているか確認。
-
ecr-public:GetAuthorizationToken
とsts:GetServiceBearerToken
のアクションがIAMロールにアタッチ済み -
aws configure
の確認 (--profile
オプションで指定も可) - MacのDockerが起動している
Step.1
まずは、DockerクライアントをAmazon Linuxパブリックレジストリに対して認証する。
aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws
Login Succeeded
とコンソールに出ればOK。
--profile
オプションをつける際は--region
の後にでも書けば良い。ちなみに我らがap-northeast-1
は24年5月時点でサポートされていないのか、エラーとなる。
Step.2
こちらから欲しい環境のDocker imageを見つけてdocker pull
コマンドでコンテナイメージを取得する。今回はpython3.12が含まれるarm64アーキテクチャAWS SAMビルドイメージを用いる。
public.ecr.aws/sam/build-python3.12:1-arm64
をpullする。
docker pull public.ecr.aws/sam/build-python3.12:1-arm64
以下のような結果が出ればpullできている。
Digest: sha256:629e2aeb90287ed1e16cc4b41740108d7a4b850c8aa36e047002e98964e73d87
Status: Downloaded newer image for public.ecr.aws/sam/build-python3.12:1-arm64
public.ecr.aws/sam/build-python3.12:1-arm64
What's Next?
View a summary of image vulnerabilities and recommendations → docker scout quickview public.ecr.aws/sam/build-python3.12:1-arm64
Step.3
コンテナをローカルで実行
docker run -it --security-opt seccomp=unconfined public.ecr.aws/sam/build-python3.12:1-arm64 /bin/bash
一応、pythonのバージョンを確認
bash-5.2# python --version
Python 3.12.3
Step.4
Layerに入れたい必要なライブラリをインストールし、パッケージングする。まずはディレクトリの作成から。
mkdir -p layer/python/lib/python3.12/site-packages
このランタイムのレイヤーパスは決められているので、それに従う。
次に、上で作成したレイヤーパスをターゲットに指定して、pipで必要なライブラリをインストールする。今回は例としてpandasを入れる。
pip install pandas --target layer/python/lib/python3.12/site-packages
成功したら、layer/python
を圧縮してpython.zip
というファイルを作る。
bash-5.2# cd layer/
bash-5.2# zip -r ../python .
これでカレントディレクトリにpython.zip
というファイルが作成された。
Step.5
作成したpython.zip
をローカルへコピーする。まずはターミナルでウィンドウを一つ増やして、今実行中のdockerコンテナのIDを取得する。
inakason@buz ~ % docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0197d6a50aca public.ecr.aws/sam/build-python3.12:1-arm64 "/bin/bash" 16 minutes ago Up 16 minutes gallant_raman
IDが確認できたらdocker cp
コマンドでコンテナからローカルへファイルをコピー
inakason@buz ~ % docker cp 0197d6a50aca:/var/task/python.zip Desktop/python.zip
Successfully copied 45.5MB to /Users/inakason/Desktop/python.zip
コンテナ内のルートディレクトリ(?)が var/task/
だったので、先頭に追加することに注意する。dockerコンテナはここで用済みなので、docker stop {ID}
で停止しておく。
Step.6
後はマネジメントコンソールないしAWS CLIからLambda Layerを追加すれば良い。
これで、import pandas as pd
が走るようになる。
おわりに
一つのLambda関数に追加できるLambda Layerの数と容量(確か、5つとデプロイサイズ含め250MB)の制約があるので、これを超えてしまう場合はimageや他AWSリソースの利用を検討しなければならない。