この記事は Serverless2 Advent Calendar 2018 の 2 日目の記事です。
本文
最近 Docker でパッケージングしたらどこでも動くが実現してるようなものなので、実質 Docker でパッケージング出来たら run anywhere な感じということです!
そして、Azure Functions は Docker をサポートしています。(2018/12/02 時点ではプレビュー) ということでやってみましょう。私は Windows 10 に Docker を入れて試しました。
基本的には以下のドキュメントに沿ってやります。
ではやってみましょう。
といっても難しいことは特になくて、func コマンドでプロジェクトを作るときに --docker
オプションをつけてやります。任意のフォルダで以下のコマンドをうってみましょう。
func init --docker
そうすると dotnet, node, python から選択できるので今回は node で行ってみようと思います。実行結果は以下のような感じのログになります。Dockerfile まで出来ちゃってますね!
Select a worker runtime: node Writing .gitignore Writing host.json Writing local.settings.json Writing C:\Users\kaota\.vscode\extensions.json Writing Dockerfile
早速 Visual Studio Code で開いてみましょう。
FROM mcr.microsoft.com/azure-functions/node:2.0 ENV AzureWebJobsScriptRoot=/home/site/wwwroot COPY . /home/site/wwwroot
思ったよりシンプル。確かに node の場合はビルドとかいりませんしね。因みに dotnet を選択すると以下のような Dockerfile が生成されます。
FROM microsoft/dotnet:2.1-sdk AS installer-env COPY . /src/dotnet-function-app RUN cd /src/dotnet-function-app && \ mkdir -p /home/site/wwwroot && \ dotnet publish *.csproj --output /home/site/wwwroot FROM mcr.microsoft.com/azure-functions/dotnet:2.0 ENV AzureWebJobsScriptRoot=/home/site/wwwroot COPY --from=installer-env ["/home/site/wwwroot", "/home/site/wwwroot"]
こちらも十分シンプルに見えます!公式がおぜん立てしてくれたベースイメージがあるのは強いですね。
このままだと空の関数になってしまうので func new
をうちこんで HttpTrigger の関数を 1 つ作ります。
関数名は Echo を指定しました。そして生成されたファイルをちょっと変えて以下のようにします。
function.json
{"disabled": false, "bindings": [{"authLevel": "anonymous", "type": "httpTrigger", "direction": "in", "name": "req", "methods": ["get" ]}, {"type": "http", "direction": "out", "name": "res" }]}
index.js
module.exports = async function (context, req) { context.log('JavaScript HTTP trigger function processed a request.'); context.res = { status: 200, body: `You said '${req.query.message}'` }; };
まずは、func start
でローカルで実行してみます。先ほど作成した Echo 関数がちゃんと認識されてることがわかります。
Http Functions: Echo: [GET] http://localhost:7071/api/Echo
curl コマンドで叩いてみるとこんな感じ。ばっちりですね。
> curl http://localhost:7071/api/Echo?message=Hello You said 'Hello'
そして docker build -t okazuki/serverless2018:v1
と打ち込んで docker でパッケージングします。
そして、docker run -p 8080:80 okazuki/serverless2018:v1
と打ち込んで実行しましょう。docker ps
をして動いてるのを確認!
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2ce0a0ec453c okazuki/serverless2018:v1 "/bin/sh -c /azure-f…" About an hour ago Up 9 seconds 0.0.0.0:8080->80/tcp gallant_hugle
先ほどと同じように curl コマンドで docker run で指定した 8080 ポートに対して関数のエンドポイントを叩いてみます。
>curl http://localhost:8080/api/Echo?message=Hello You said 'Hello'
ばっちりですね。docker kill で止めておきましょう。
ここまで出来たら後はお好みの環境で動かすだけですね。 まぁ Azure Functions の機能自体が Azure Storage に依存してたりするので(Durable Functions とか) そういうのを使おうとすると結局 Azure のサービスが必要でレイテンシを考えると Azure でホストするしかないのかぁ…となりそうな気もします。
でも、Azure Functions はバインディング(トリガーやアウトプットやインプット)は自作出来るようになってるので例えば AWS 系サービスのトリガーとかを作ったらいい感じに AWS 上で Azure Functions を動かすことも出来るかもしれませんね。
IoT デバイスで Azure Functions を動かすのも Docker を使ってるので、Azure Functions の Docker 対応は要注目な気がします。
まとめ
Azure Functions は Docker イメージ作れるのでどこでも動く。
Azure Functions に興味がある人は、無料で教育用の Azure 環境をクレカ不要で使いながらテキストを進めることが出来る Microsoft Learn というサイトがあるので、そこから試してみてください。因みに無料枠でも Azure Functions 出来ます。
誰か
Azure Functions on AWS とかしてくれないかな?