🐳

AWS ECR + Lambdaを使ってみる

2021/07/29に公開

やりたいこと

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にまとめました。
https://github.com/yoshiko-tsuka/ecr-tutorial

下記ではコードの解説を行いますが、不要な方はスキップしてOKです〜!

  • Dockerfile
    • Lambda用pythonイメージをもとに、nltkをインストール。
    • /var/task/にapp.pyをコピー(これ大事!!)
    • /tmpにinit.pyをコピー&実行
    • CMDをapp.handlerに指定(これでapp.py内のhandler関数がデフォルトで実行されるようになる)
Dockerfile
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で待ち受け
docker-compose.yml
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上で読み込まれない可能性あり)
init.py
import nltk
nltk.download('punkt', download_dir = "/var/task")
  • app.py
    • Lambdaで実行するhandler関数を記載
    • 今回は、入力されたsentenceをnltkで単語ごとに分解し、jsonで返す能性あり)
app.py
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です〜!

  1. 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
  1. Docker イメージを構築(今回は既にecr-tutorialイメージをビルドしているので、スキップ)
docker build -t ecr-tutorial .
  1. イメージにタグづけ
docker tag ecr-tutorial:latest XXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/ecr-tutorial:latest
  1. リポジトリにイメージをプッシュ(数分かかることがあります)
docker push XXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/ecr-tutorial:latest
  1. プッシュが成功すると、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でも投稿するので、よかったらフォローしてください^^
https://twitter.com/S2hydrangeS2

Discussion