AWS ECR + Lambdaを使ってみる
やりたいこと
ECR(Elastic Container Registry)を使ってLambda関数を作成する!!
LambdaちゃんとECRちゃんの絵を描きました〜
今回の記事を読んだ方は、二人と少し仲良くなれるはず、、です、、!
ECR概要
ECRって何?
- Docker Imageを保存&バージョン管理できるサービス
ECRって何がいいの?
- pip installで外部ライブラリを使用できる(Lambdaの「1から作成」(以下ランタイムと呼ぶ)では外部ライブラリをzip形式でアップロードする必要あり)
- ECRにpushしたDocker ImageをLambda以外のサービスでも使いまわせる(AWS Fargateなど)
- ランタイムでサポートされていないNode.jsやPythonのバージョンを使用した関数も作成できる
ランタイムでサポートされている言語の例
目次
1. Docker Image作成(ローカル)
2. ECRレポジトリ作成
3. Docker ImageをECRにpush
4. Lambdaで関数作成
1. Docker Image作成(ローカル)
概要
今回はチュートリアルとして、「英文を単語ごとに分解する」関数を作成します。
nltkという自然言語処理用の外部パッケージを使用し、英文を単語ごとに分解してみようと思います〜。
え?英語ってスペースで区切れば、単語に分解できるじゃん?
例えば
I'm Taro Yamada.
という文章の場合はどうでしょう?
nltkは、この文章を
I + 'm + Taro + Yamada + .(ピリオド)
と認識してくれるのです!(賢い〜〜〜)
nltkは他にも単語の品詞を特定してくれたりなど、様々な機能があります。
が、今回の記事の内容からは逸れるため割愛します〜〜
コード準備
今回のコードは下記githubにまとめました。
下記ではコードの解説を行いますが、不要な方はスキップしてOKです〜!
- Dockerfile
- Lambda用pythonイメージをもとに、nltkをインストール。
- /var/task/にapp.pyをコピー(これ大事!!)
- /tmpにinit.pyをコピー&実行
- CMDをapp.handlerに指定(これでapp.py内のhandler関数がデフォルトで実行されるようになる)
FROM public.ecr.aws/lambda/python:3.8
RUN pip3 install --upgrade pip
RUN pip3 install nltk
COPY app.py /var/task/
COPY init.py /tmp
RUN python3 /tmp/init.py
CMD [ "app.handler" ]
- docker-compose.yml
- 同ディレクトリに配置したDockerfileをビルド
- tty: trueで、docker-compose downをするまでコンテナをupした状態にする
- imageをecr-tutorialという名前にする
- localhost:9000で待ち受け
version: "2"
services:
ecr-tutorial:
build: .
tty: true
image: ecr-tutorial
ports:
- '127.0.0.1:9000:8080'
- init.py
- コンテナを立ち上げた際にpythonで実行したい処理を記載
- 今回は、nltkのpunktライブラリ(単語ごとに分解するのに必要)をダウンロードしておく(毎回app.handler実行の度にダウンロードするより高速化できる)
- ダウンロード先は/var/taskに指定(これ大事!!他のディレクトリだとLambda上で読み込まれない可能性あり)
import nltk
nltk.download('punkt', download_dir = "/var/task")
- app.py
- Lambdaで実行するhandler関数を記載
- 今回は、入力されたsentenceをnltkで単語ごとに分解し、jsonで返す能性あり)
import nltk
import json
nltk.data.path.append("/var/task")
def handler(event, context):
tokens = nltk.word_tokenize(event["sentence"])
return {
"statusCode": 200,
"body": json.dumps({"tokens": tokens})
}
imageビルド & コンテナup
docker-compose up -d --build
ローカルテスト
- 9000ポートに対して{"sentence":"I'm Taro Yamada."}を渡す
curl -d "{\"sentence\":\"I'm Taro Yamada.\"}" -H "Content-Type: application/json" http://localhost:9000/2015-03-31/functions/function/invocations
- 返り値
{"statusCode": 200, "body": "{\"tokens\": [\"I\", \"'m\", \"Taro\", \"Yamada\", \".\"]}"}
コンテナdown
docker-compose down
2. ECRレポジトリ作成
- Amazon Container ServicesでAmazon ECRのRepositoriesを選択
- 「レポジトリを作成」を押す
- リポジトリ名「ecr-tutorial」、KMS 暗号化有効にし、「レポジトリを作成」を押す
3. Docker ImageをECRにpush
- 下記のように作成が成功したら、「プッシュコマンドの表示」を押す
- macやwindowsでのプッシュコマンドが表示される
下記ではmac用のプッシュコマンドの解説を行いますが、不要な方はスキップしてOKです〜!
- AWS CLIを使用してDocker クライアントを認証
- XXXXXX.dkr.ecr.region.amazonaws.comの部分が一人一人違うので変更必要
- AWS CLIで複数プロファイルを使用している場合は、--regionパラメータの後に、--profile profile-name のように、--profileパラメータを追加
aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin XXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com
- Docker イメージを構築(今回は既にecr-tutorialイメージをビルドしているので、スキップ)
docker build -t ecr-tutorial .
- イメージにタグづけ
docker tag ecr-tutorial:latest XXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/ecr-tutorial:latest
- リポジトリにイメージをプッシュ(数分かかることがあります)
docker push XXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/ecr-tutorial:latest
- プッシュが成功すると、latestというタグのイメージが追加される
4. Lambdaで関数作成
- Lambda関数作成ページで、「コンテナイメージ」を選択、関数名は「ecr-tutorial」とする
- 「イメージを参照」で、先ほどECRにpushしたイメージを選択
- 権限はデフォルト(S3など他のサービスと連携する場合は、roleを作成する必要あり)で「関数の作成」を押す
- 「テスト」タブでテストイベントを作成し「テスト」を押す
{ "sentence": "I'm Taro Yamada"}
- 単語ごとに分解されていることを確認
5. 【おまけ】お片付け
ECRはイメージを置いているだけで課金が発生するので、下記の順番で削除
- ECR:イメージ削除
- ECR:ecr-tutorialレポジトリ削除
- Lambda:ecr-tutorial関数削除
- IAM:ecr-tutorial関数用のロール削除(ecr-tutorial-role-XXXXのようなロール名になっている)
イメージをプッシュすると、下記二つのイメージがローカルに存在しているので、削除
- ecr-tutorial:latest
- XXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/ecr-tutorial:latest
最後まで読んでいただき、ありがとうございました〜!
今回の記事で、もし100 Likes達成したら
LambdaちゃんとECRちゃんの記念イラストを描こうと思います〜〜
Twitterでも投稿するので、よかったらフォローしてください^^
Discussion