KTX-SoftwareをLambdaで実行してみた
背景
KTX-Softwareを用いて画像をKTX2に圧縮する必要があがりました。
要件を聞くと
- 圧縮対象の画像は非常に小さい(512x512以下)
- 圧縮にかかる時間は長くなってもよい
ということだったので、既にシステムで使用しているLambdaで賄えないか、ということで表題の件を実施するに至りました。
方針
KTX-Software(詳細にはKTX Tools)はLinuxアプリケーションとしては配布されていますが、PythonやNodeから呼び出せるライブラリとしては配布されていません。
というわけで、今回はKTX ToolsをインストールしたDockerイメージ上でLambdaを起動して、PythonからsubprocessでKTX Toolsを実行する方針にしました。
参考
コンテナイメージを使用した Lambda 関数の作成
コンテナイメージの作成
ベースイメージの選択
ベースイメージは以下の3パターンがあります。
- Lambda の AWS ベースイメージを使用する
- AWS の OS 専用ベースイメージを使用する
- 非 AWS ベースイメージを使用する
今回インストールするKTX ToolsにはGnuパッケージが必要です。AWSが用意するベースイメージにはこのGnuパッケージが含まれなかったため非 AWS ベースイメージを使用することにしました。
Pythonファイルの作成
Lambdaで実行するPythonファイルを作成します。
今回はローカルで動作確認するため、Docker上の/tmp/sample.jpgをKTX Toolsで変換します。
ファイル名はapp.pyとします。
$ touch app.py
import subprocess
def handler(event, context):
command = [
"ktx", "create",
"--format", "R8G8B8A8_UNORM",
"/tmp/sample.jpg",
"/tmp/sample.ktx2"
]
result = subprocess.run(command)
return f'ktx execute. returncode = {result.returncode}'
Dockerfileの作成
Dockerfileを作成します
$ touch Dockerfile
ローカルで動作確認を行うため、ローカル上のsample.jpgをDocker上へコピーしています。
FROM ubuntu:22.04
# install python
RUN apt-get update
RUN apt-get install -y python3-pip
# install python libraries
RUN pip install --upgrade pip
RUN pip install --upgrade setuptools
# install awslambdaric
RUN mkdir /function && \
pip install --target /function awslambdaric
COPY ./app.py /function/
# 変換対象のファイルをコピー
COPY ./sample.jpg /tmp/
# install KTX-Software
RUN apt-get install -y curl
RUN mkdir /install && \
curl -L -o /install/KTX-Software-4.3.2-Linux-x86_64.deb https://github.com/KhronosGroup/KTX-Software/releases/download/v4.3.2/KTX-Software-4.3.2-Linux-x86_64.deb
RUN apt install /install/KTX-Software-4.3.2-Linux-x86_64.deb
WORKDIR /function
ENTRYPOINT [ "/usr/bin/python3", "-m", "awslambdaric" ]
CMD [ "app.handler" ]
動作確認
イメージをローカルでテストする方法は下記で解説されています。
Docker ビルド
$ docker build -t docker-image:test .
エミュレーターをインストール
$ 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 イメージを起動
$ docker run -d -v ~/.aws-lambda-rie:/aws-lambda -p 9000:8080 \
--entrypoint /aws-lambda/aws-lambda-rie \
docker-image:test \
/usr/bin/python3 -m awslambdaric app.handler
Dockerにログインし、/tmpフォルダの内容を確認します
$ docker exec -it <コンテナID> /bin/bash
$ ls /tmp
sample.jpg
$ exit
エミュレータのLambdaイベントを起動
$ curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
"ktx execute. returncode = 0"と表示されれば正常です。
再びDockerにログインし、/tmpフォルダの内容を確認します。
$ docker exec -it <コンテナID> /bin/bash
$ ls /tmp
sample.jpg sample.ktx2
$ exit
sample.ktx2が生成されていることが確認できました。
起動したDokerを停止
$ docker kill <コンテナID>
Lambda関数の作成
作成したDockerイメージを使用してLambda関数を作成する方法は、下記を参考にしました。
Discussion