コンテナイメージを使用して Go Lambda 関数をデプロイする
Lambda 関数コードをコンテナイメージとしてデプロイできます。Go 関数のコンテナイメージの構築を支援するため、AWS は次のリソースを提供します。
-
Lambda の AWS ベースイメージ
これらのベースイメージには、Lambda でイメージを実行するために必要な言語ランタイムおよびその他のコンポーネントがプリロードされています。AWS は、コンテナイメージの構築に役立つ各ベースイメージの Dockerfile を提供します。
-
オープンソースのランタイムインターフェイスクライアント
コミュニティまたはプライベートエンタープライズのベースイメージを使用する場合、ランタイムインターフェイスクライアントをベースイメージに追加し、Lambda と互換性を持たせる必要があります。
-
オープンソースのランタイムインターフェイスエミュレータ
Lambda は、関数をローカルでテストするためのランタイムインターフェイスエミュレータ(RIE)を提供します。Lambda のベースイメージおよびカスタムランタイムのベースイメージには RIE が含まれます。その他のベースイメージでは、イメージをローカルでテストするための RIE をダウンロードできます。
コンテナイメージとして定義された関数のワークフローには、次のステップが含まれます。
-
このトピックにリストされているリソースを使ってコンテナイメージを構築します。
-
Amazon Elastic Container Registry (Amazon ECR) のコンテナレジストリ にイメージをアップロードします。
トピック
AWSGo 用の ベースイメージ
AWS では、次のような Go に使用できるベースイメージを提供しています。
タグ | ランタイム | オペレーティングシステム | Dockerfile | 廃止 |
---|---|---|---|---|
1 |
Go 1.x | Amazon Linux | GitHub 上の Go 1.x 用の Dockerfile |
Amazon ECR リポジトリ: gallery.ecr.aws/lambda/go
Go 用ランタイムインターフェイスクライアント
AWS では、Go 用として、個別のランタイムインターフェイスクライアントは提供していません。aws-lambda-go/lambda
パッケージには、ランタイムインターフェイスの実装が含まれています。
Go:1.x ベースイメージの使用
このセクションの手順を完了するには、以下が必要です。
-
プロジェクト用のディレクトリを作成し、そのディレクトリに切り替えます。
mkdir hello cd hello
-
新しい Go モジュールを初期化します。
go mod init
example.com/hello-world
-
Lambda ライブラリを新しいモジュールの依存関係として追加します。
go get github.com/aws/aws-lambda-go/lambda
-
「
hello.go
」という名前のファイルを作成し、テキストエディタで開きます。これは Lambda 関数のコードです。次のサンプルコードをテストに使用することも、独自のサンプルコードで置き換えることもできます。package main import ( "context" "fmt" "github.com/aws/aws-lambda-go/lambda" ) type MyEvent struct { Name string `json:"name"` } func HandleRequest(ctx context.Context, name MyEvent) (string, error) { return fmt.Sprintf("Hello %s!", name.Name), nil } func main() { lambda.Start(HandleRequest) }
-
Go プロジェクトを構築します。このコマンドは、「
main
」という実行可能ファイルを作成します。GOOS=linux GOARCH=amd64 go build -o main
hello.go
GOOS
をlinux
に設定し、GOARCH
をamd64
に設定すると、非 Linux 環境でコンパイルする場合でも、コンパイルされた実行可能ファイルに Go ベースイメージのアーキテクチャと互換性を持たせられます。 -
新しい Dockerfile を作成します。Dockerfile の例は次の設定を使用します。
-
FROM
: 使用する「ベースイメージの URI」。 -
COPY
: 関数コードをイメージの「/var/task
」ディレクトリにコピーします。 -
CMD
: Lambda 関数ハンドラーまたは実行可能ファイル。
FROM
public.ecr.aws/lambda/go:1
# Copy function code COPYmain
${LAMBDA_TASK_ROOT} # Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile) CMD [ "main
" ] -
-
Docker イメージを「Docker の構築
」コマンドで構築します。次の例では、イメージを docker-image
と名付けてtest
タグを付けます。 docker build -t
docker-image
:test
.
(オプション) イメージをローカルでテストする
-
docker run コマンドを使用して Docker イメージを起動します。この例では、
docker-image
はイメージ名、test
はタグです。docker run -p 9000:8080
docker-image
:test
このコマンドはイメージをコンテナとして実行し、
localhost:9000/2015-03-31/functions/function/invocations
でローカルエンドポイントを作成します。 -
RIE を使用して、アプリケーションをローカルでテストします。新しいターミナルウィンドウから curl コマンドを使用して、次のエンドポイントにイベントをポストします。
curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"Name": "World"}'
このコマンドは、コンテナイメージで実行されている 関数を呼び出し、応答を返します。
-
コンテナ ID を取得します。
docker ps
-
「docker kill
」コマンドを使用してコンテナを停止します。このコマンドでは、 3766c4ab331c
を前のステップのコンテナ ID で置き換えます。docker kill
3766c4ab331c
Amazon ECR にイメージをアップロードして Lambda 関数を作成するには
-
「get-login-password
」コマンドを実行して Amazon ECR レジストリに Docker CLI を認証します。 -
--region
値を Amazon ECR リポジトリを作成する AWS リージョン に設定します。 -
111122223333
を AWS アカウント ID に置き換えます。
aws ecr get-login-password --region
us-east-1
| docker login --username AWS --password-stdin111122223333
.dkr.ecr.us-east-1
.amazonaws.com -
-
「create-repository
」コマンドを使用して Amazon ECR にリポジトリを作成します。 aws ecr create-repository --repository-name
hello-world
--image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE成功すると、次のようなレスポンスが表示されます。
{ "repository": { "repositoryArn": "arn:aws:ecr:us-east-1:111122223333:repository/hello-world", "registryId": "111122223333", "repositoryName": "hello-world", "repositoryUri": "111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world", "createdAt": "2023-03-09T10:39:01+00:00", "imageTagMutability": "MUTABLE", "imageScanningConfiguration": { "scanOnPush": true }, "encryptionConfiguration": { "encryptionType": "AES256" } } }
-
前のステップの出力から
repositoryUri
をコピーします。 -
「docker tag
」コマンドを実行して、最新バージョンとしてローカルイメージを Amazon ECR リポジトリにタグ付けします。このコマンドで: -
docker-image:test
をお使いの Docker イメージの名前およびタグで置き換えます。 -
Amazon ECR リポジトリ URI をコピーした
repositoryUri
で置き換えます。URI の末尾には必ず:latest
を含めてください。
docker tag
docker-image
:test
111122223333
.dkr.ecr.us-east-1
.amazonaws.com/hello-world
:latest -
-
「docker push
」コマンドを実行して Amazon ECR リポジトリにローカルイメージをデプロイします リポジトリ URI の末尾には必ず :latest
を含めてください。docker push
111122223333
.dkr.ecr.us-east-1
.amazonaws.com/hello-world
:latest -
まだ作成済みでない場合、関数に「実行ロールの作成」を実行してください。次のステップではロールの Amazon リソースネーム (ARN) が必要です。
-
Lambda 関数を作成する
ImageUri
には、先ほど使用したリポジトリ URI を指定します。URI の末尾には必ず:latest
を含めてください。aws lambda create-function \ --function-name
hello-world
\ --package-type Image \ --code ImageUri=111122223333
.dkr.ecr.us-east-1
.amazonaws.com/hello-world
:latest \ --rolearn:aws:iam::111122223333:role/lambda-ex
-
関数を呼び出します。
aws lambda invoke --function-name
hello-world
response.json次のような結果が表示されます。
{ "ExecutedVersion": "$LATEST", "StatusCode": 200 }
-
関数の出力を確認するには、
response.json
ファイルを確認してください。
関数コードを更新するには、新しいバージョンのイメージを作成し、そのイメージを Amazon ECR リポジトリに保存する必要があります。詳細については、「関数コードの更新」を参照してください。
provided.al2
ベースイメージから Go イメージを作成する
Amazon Linux 2 で実行される Go のコンテナイメージを作成するには、provided.al2
ベースイメージを使用します。このベースイメージの詳細については、Amazon ECR Public Gallery の「provided
aws-lambda-go/lambda
パッケージを Go ハンドラーにインクルードします。このパッケージにより、ランタイムインターフェイスクライアントを含む、Go のプログラミングモデルが実装されます。provided.al2
ベースイメージには RIE も含まれます。
provided.al2
ベースイメージを使用しながら、Go 関数をビルドしデプロイします。
-
プロジェクト用のディレクトリを作成し、そのディレクトリに切り替えます。
mkdir hello cd hello
-
新しい Go モジュールを初期化します。
go mod init
example.com/hello-world
-
Lambda ライブラリを新しいモジュールの依存関係として追加します。
go get github.com/aws/aws-lambda-go/lambda
-
「
hello.go
」という名前のファイルを作成し、テキストエディタで開きます。これは Lambda 関数のコードです。次のサンプルコードをテストに使用することも、独自のサンプルコードで置き換えることもできます。package main import ( "context" "fmt" "github.com/aws/aws-lambda-go/lambda" ) type MyEvent struct { Name string `json:"name"` } func HandleRequest(_ context.Context, name MyEvent) (string, error) { return fmt.Sprintf("Hello %s!", name.Name), nil } func main() { lambda.Start(HandleRequest) }
-
テキストエディタを使用して、プロジェクトディレクトリに Dockerfile を作成します。次の Dockerfile の例では、「マルチステージビルド
」が使用されます。これにより、各ステップで異なるベースイメージを使用できます。「Go ベースイメージ 」など、1 つのイメージを使用し、コードをコンパイルして実行可能なバイナリを構築できます。その後、最後の FROM
ステートメントでprovided.al2
など別のイメージを使用し、Lambda にデプロイするイメージを定義できます。ビルドプロセスは最終デプロイイメージとは分離されているため、最終イメージにはアプリケーションの実行に必要なファイルのみが含まれます。例 — マルチステージビルド Dockerfile
注記
Dockerfile で指定する Go のバージョン (たとえば、
golang:1.20
) が、アプリケーションの作成に使用した Go のバージョンと同じであることを確認してください。FROM golang:1.20 as build WORKDIR /helloworld # Copy dependencies list COPY go.mod go.sum ./ # build COPY hello.go . RUN go build -o main hello.go # copy artifacts to a clean image FROM public.ecr.aws/lambda/provided:al2 COPY --from=build /helloworld/main /main ENTRYPOINT [ "/main" ]
-
docker build
コマンドを使用して Docker イメージをビルドします。次の例では、イメージにdocker-image
という名前を付けています。docker build -t
docker-image
:test
.
代替ベースイメージから Go イメージを作成する
代替のベースイメージからも、Go 用のコンテナイメージを構築できます。次の Dockerfile の例では、ベースイメージとして alpine
例 アルパインベースイメージを含む Dockerfile
注記
Dockerfile で指定する Go のバージョン (たとえば、golang:1.20.2
) が、アプリケーションの作成に使用した Go のバージョンと同じであることを確認してください。
FROM golang:1.20.2-alpine3.16 as build WORKDIR /helloworld # Copy dependencies list COPY go.mod go.sum ./ # Build COPY hello.go . RUN go build -o main hello.go # Copy artifacts to a clean image FROM alpine:3.16 COPY --from=build /helloworld/main /main ENTRYPOINT [ "/main" ]
手順は provided.al2 ベースイメージの手順 と同じですが、もう 1 つの考慮事項があります。イメージに RIE を追加する場合、docker build
コマンドを実行する前に、これらの追加手順に従う必要があります。RIE を使用してイメージをローカルにテストする方法の詳細については、「Lambda コンテナイメージをローカルでテストする」を参照してください。
イメージに RIE を追加するには、
-
Dockerfile で、ENTRYPOINT 命令を次の内容に置き換えます。
# (Optional) Add Lambda Runtime Interface Emulator and use a script in the ENTRYPOINT for simpler local runs ADD https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie /usr/bin/aws-lambda-rie RUN chmod 755 /usr/bin/aws-lambda-rie COPY entry.sh / RUN chmod 755 /entry.sh ENTRYPOINT [ "/entry.sh" ]
-
テキストエディタを使用して、プロジェクトディレクトリに
entry.sh
という名前で、次の内容のファイルを作成します。#!/bin/sh if [ -z "${AWS_LAMBDA_RUNTIME_API}" ]; then exec /usr/bin/aws-lambda-rie "$@" else exec "$@" fi
イメージに RIE を追加する必要がない場合は、RIE なしでもローカルでテストできます。
イメージに RIE を追加せずにローカルでテストするには、
-
プロジェクトディレクトリから次のコマンドを実行して、GitHub から RIE をダウンロードし、ローカルマシンにインストールします。
mkdir -p ~/.aws-lambda-rie && curl -Lo ~/.aws-lambda-rie/aws-lambda-rie \ https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie \ && chmod +x ~/.aws-lambda-rie/aws-lambda-rie
-
docker run
コマンドを使用して、Lambda イメージの関数を実行します。次の例では、/main
が関数のエントリポイントへのパスとなっています。docker run -d -v ~/.aws-lambda-rie:/aws-lambda --entrypoint /aws-lambda/aws-lambda-rie -p 9000:8080 myfunction:latest /main
このコマンドはイメージをコンテナとして実行し、ローカルの
localhost:9000/2015-03-31/functions/function/invocations
でエンドポイントを起動します。 -
curl
コマンドを使用して、次のエンドポイントにイベントをポストします。curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"Name": "World"}'
このコマンドは、コンテナイメージで実行されている 関数を呼び出し、応答を返します。