BFT名古屋 TECH BLOG

日々の業務で得た知識を所属するエンジニアたちがアウトプットしていきます。

【AWS】Lambda/Batchへのコンテナ利用 -02_Lambda用コンテナ-

コンニチハ、BFT名古屋支店のヤタテです。
最近世の中コンテナ、コンテナと流行ってますよね。

f:id:bftnagoya:20210326092443p:plain
コンテナ
この記事を書いた時点では、スエズ運河で日本のコンテナ船が座礁して世界の物流に影響を与えている
とかニュースが流れています。

IT業界でもアプリケーション実行環境にコンテナを使うのは当たり前になってきて、AWSを代表する
サーバレスアーキテクチャのLambdaやAWS Batchでもコンテナ技術が利用できます。

さて、今回はLambdaでAWSBatch用のコンテナイメージが利用できるかどうか確認します。

Lambda/Batchへのコンテナ利用 -02_Lambda用コンテナ-

背景

AWS Lambda/Batchにて、コンテナイメージによる実装を開始。

検証内容

  1. Lambdaへのコンテナイメージによる関数実装
  2. Batchへのコンテナイメージ流用が可能であるか確認
     → Lambda専用の作りにする必要がありそう

現状

  • コンテナ使用経験なし
     → 前回の記事で、触ってレベルに昇格
  • Lambdaにて、Python(スクリプト言語)での使用経験あり
  • Batchの使用経験なし
  • AWS使用経験あり (EC2やVPC周りのみ)

AWSについてはある程度イメージがつく。
  コンテナは、使用や作成イメージがほとんどついていない。

AWSベースイメージ

AWS公式より、Lambdaで使用するDockerイメージのベースが公開されている。
Pythonやnode.jsなど、各言語ごとで用意されている。
ベースイメージに内包されているDockerfileを使用することで、
比較的容易にLambda用のコンテナをデプロイすることが可能。

Lambdaコンテナーイメージのランタイムサポート
コンテナイメージを使用した Java Lambda 関数のデプロイ

デプロイしたコンテナの検証

デプロイしたコンテナをLambdaへ導入する場合、正常に動作しなくても課金が発生する。
ローカル環境でテストするためのツールがあるため、検証時に使用する。

ランタイムインターフェースエミュレータ (aws-lambda-rie)
Lambdaコンテナーイメージのランタイムサポート
※本ページ下部よりDL可能

Javaのコンテナデプロイ

以下を参照し、実行。
参考サイト AWS LambdaのコンテナサポートをJavaで試してみた。

JARのデプロイは、以下の記事にて実施。

bftnagoya.hateblo.jp

bftnagoya.hateblo.jp

使用Dockerイメージ

amazon/aws-lambda-java:latest
 (public.ecr.aws/lambda/java:11)

Dockerfileの中身

※参考サイトのDockerfileを参照し、自環境に合わせてjarファイル等を変更

FROM public.ecr.aws/lambda/java:11

# Copy function code
COPY target/Sqldo.jar ${LAMBDA_TASK_ROOT}
COPY target/lib/postgresql-42.2.18.jar ${LAMBDA_TASK_ROOT}/lib/
RUN ls -al
RUN jar -xvf Sqldo.jar

CMD [ "yatate001.Sqldo::handleRequest" ]

ディレクトリ構成

/Dockerfile
/target (dir)
/target/SqlDo.jar
/target/lib (dir)
/terget/lib/postgresql-42/2/18.jar

タイムゾーンについて

Lambdaでは、タイムゾーンの指定を、環境変数「TZ」を変更することで、実施できる。
しかし、環境変数「TZ」は、"AWSによって予約されている環境変数"であり、原則変更してはならない値となる。
そのため、コード側で対応する必要がある。

■今回の対応
SQLにてレコード追加時に、タイムゾーンを指定するコードへ変更

//INSERT文の実行
stmtIst = conn.createStatement();
String sqlIst = "insert into tschm.tstbl3 " +
                "(prefecture, city, specialty, timestamp) " +
                "select " +
                    "prefecture, " +
                    "tstbl1.city, " +
                    "specialty, " +
                    "timezone('JST',current_timestamp) " +   //この箇所
                "from tschm.tstbl1 inner join tschm.tstbl2 " +
                "on tschm.tstbl1.city = tschm.tstbl2.city "
                ;
stmtIst.executeUpdate(sqlIst);
conn.commit();

Lambdaをコンテナ実装する場合

筆者に開発経験がないため憶測になるが、
本方式の場合は、格納するライブラリ指定をDockerfileで行え、容量も10GBへ増加するため、
実装したコードをJARで格納し、ハンドラメソッドで呼び出す方式の方が、
コンテナとしてはシンプルな構成になると想定される。
この辺については、別途検証予定。

※コンテナをビルドするまでが、一般的なコンテナと異なり結構厄介だったので、
 Dockerfileがよりシンプルになる構成にしたいという意図。
 コンテナに関する理解が深まることで、印象は変わるかもしれない。