LambdaでPythonライブラリを使うには
PythonのプログラムをLambdaに移行する機会があったのですが、その際に色々と手こずったので、誰かの助けに慣れればと思い記事を書きます。
Lambdaは、AWSが提供するサーバーレスコンピューティングサービスですが、通常のPythonプログラムのようにpip install ライブラリ名
でNumpyやPandasなどのライブラリを入れることができません。
Lambdaではレイヤーという機能で標準ライブライ以外のライブラリを使用することができます。
レイヤーの特徴
- ライブラリと関数を分離することができ、他の関数にも使用できる
- 関数のデプロイパッケージのサイズを小さくできる
- S3のファイル、zipファイル、ARNから作成することができる
- zipファイルのサイズは50MBを超えてはいけない
- 最大5つのレイヤーをLambda関数につけることができる
- その合計は展開後のサイズで250MB以下にしないといけない
- バージョン管理できるので、問題があればすぐに戻すことができる
便利な機能ではありますが、少しクセがあります。
Lambdaでライブラリを使う方法3選
他にもライブラリを入れる方法はあるかと思いますが、3つの方法をご紹介します。
- ローカルでインストールしてからzipファイルに圧縮する
- Klayersのレイヤーを利用する
- DockerイメージをECRにプッシュしてアタッチ
他にAWSが用意してくれているレイヤーを使うことも可能です。(Pandasもあるので、これだけで事足りることもありそうです)しかし、試していないので今回は除きます。
気になる方はこちらが参考になると思います。
https://dev.classmethod.jp/articles/check-lambda-python-runtime-packages/
それでは順番にご紹介していきます。
ローカルでインストール
一番基本的な方法になるかと思います。
しかし、Windowsでやる場合、うまくいかないことが多いため簡単な説明とさせていただきます。(Numpyなどはこの方法では無理でした)
手順
- Lambdaのランタイムと同じPythonをインストールし、pythonというフォルダに各ライブラリをインストールします。
- pythonフォルダをzipファイルに加工します。
- Lambdaのレイヤーの追加にてzipファイルをアップロードします。
- Lambda関数でそのレイヤーをアタッチしてください。
Lambdaの仕様上、解凍後のフォルダは「python」となるようにする必要があります。
このレイヤーはLambda関数とは分離されているため、他の関数にアタッチすることも可能です。
Windows環境でのレイヤーの問題点
まずは容量の問題があります。
zipファイルの容量は最大50MBとなっており、容量の大きいPandasなどを使用する場合、かなり厳しいです。削ろうにも多くの場合、Pythonのライブラリはさまざまなライブラリと依存関係にあります。そのため、削減することは困難です。
もう一つはLambdaはLinux環境であり、Windows環境下でインストールしたライブラリではうまく動かない場合があります。
そのため、Windows環境でインストールしたものでも問題なく軽いライブラリを使用するときのみzipファイルでのレイヤーが使えるということになります。
Klayersというレイヤーを使う
そんな状況を助けてくれるサービスがKlayersです。
Keith's Layers (Klayers)は全てのライブラリがあるわけではありませんが一般的によく使うであろうPythonライブラリのレイヤーを公開しているGitHubリポジトリです。
Klayersを利用する場合、50MBの制限を気にする必要はありません。多くのライブラリが利用できるため困ることはないと思います。
手順
- Klayersのリポジトリページにアクセスします。
- List of ARNsにあるランタイムと同じPythonのリンクをクリック。
- Lambdaがあるリージョンを探して、htmlをクリックます。
- ライブラリのリストが表示されるのでARNをコピーします。
- Lambda関数に移動してレイヤーを追加をクリック。
- ARNを指定を選択して、コピーしたARNを貼り付けます。
Klayersを使っておきた問題
Klayersが問題があるというよりも、レイヤーをつかうときに気を付けなければいけないことがあります。
大きな問題がレイヤーにはあります。
それは一つのLambda関数で使用できるレイヤーは展開後のサイズが250MB以内ということ。これはKlayersのARNを使用しても適用されるようです。
Pythonのライブラリを扱ったことがあるかたはお分かりかと思いますが、複雑な計算をするライブラリは結構容量が大きいです。
3,4つと組み合わせるLambda関数を実行する場合その制限に引っ掛かってしまうんですよね。。
Lambda関数をわけることもできますが、それはそれで面倒。。。
DockerイメージでLambda関数をつくる
そこで色々と調べていると、DockerイメージをECRにアップしてそれを使ってLambda関数を作るとほぼ容量制限なく使えることがわかりました。
この方法はレイヤーを利用するのではなく、Dockerfileを作り、通常のPythonファイルのようにライブラリをインストールします。
そのため、AWS CLIやDocker Desktopをインストールしていない場合はインストールしてください。
手順
- ECR(Elastic Container Registry)にリポジトリを作成する
- Dockerfileを作る
- Dockerfileを元にビルドする
- ECRにログインする
- Dockerイメージをタグ付けする
- Dockerイメージをプッシュする
- Lambda関数をつくる際にそのDockerイメージをアタッチする
まず、Dockerfileですが、こんな感じで必要なライブラリを記述し作成してください。Lambdaで使用できるPythonは下記のリンクから探してみてください。
FROM public.ecr.aws/lambda/python:3.12
RUN pip install --upgrade pip
RUN pip install numpy
RUN pip install pillow
RUN pip install pandas
COPY lambda_function.py ${LAMBDA_TASK_ROOT}}
CMD ["lambda_function.lambda_handler"]
ライブラリのインストールコマンドがわからんって方は下記リンクからどうぞ!
Dockerfileができたら、ECR(Elastic Container Registry)にアクセスしてDockerイメージをプッシュするためのリポジトリを作成してください。(ちなみになぜかECRと検索しても出てきません。)
ビルドするときの注意ポイント
リポジトリを作ったらあとはビルドしてプッシュしていきます。
便利なことにECRのリポジトリページにプッシュするまでのコマンドが丁寧に書かれています。
基本的にそれに従っていけばいいのですが、一つ気をつけたいポイントがあります。
Dockerfileからイメージをビルドするのですが、その際のコマンドは
PS C:\Users\Administrator\qiita> docker build --platform linux/amd64 --provenance=false -t ECRリポジトリ名 .
としてください。
LambdaはLinux環境のためWindows環境でビルドするとうまくいきませんので、--platform
オプションをつけます。
--provenance=false
オプションをつけないとイメージ以外のインデックスファイルが作成されてしまうため必ずつけてビルドしましょう。(インデックスファイルが作成されると非常にわかりづらくなります。)
Dockerイメージをプッシュしたら、あとはLambda関数を作成する際にそのDockerイメージを使うだけです。これでレイヤーの容量を気にせずLambdaを利用することができます。
終わりに
Lambdaの経験がほぼなかったので、色々とつまづきました。
1つのLambda関数自体に複数の処理をさせるのは、良くないのかとは思いますが画像を加工したりと情報の受け渡しをするには一つのLambda関数でやりたいところ。。。
他にSAMを使ってLambda関数を作成する方法もありますが、管理はしやすくなり、いいなとは思いますが結構複雑でなかなか手が出ませんでした。
コンテナ、ECRを利用してのLambda関数の作成は慣れてしまえば簡単です。
誰かのお役に立てたら嬉しいです。
ありがとうございました。
参考記事