この記事は、Microsoft Azure Tech Advent Calendar 2020 の 17 日目の記事です。
KEDA を使って、Azure Functions を動かしてみました。
KEDA
KEDA (Kubernetes Event-Driven Autoscaling) は、Kubernetes をベースに、処理すべきイベント量に応じて自動でスケーリングしてくれる仕組みです (ほぼ名前を直訳) 。
名前の通り、Kubernetes が必要なようです。
Kubernetes によるコンテナー オーケストレーションを、イベント ベースにやってくれる、というのが雑な理解。
Kubernetes 自体、名前くらいしか知らないんですが。
Azure Functions
ご存じ、Azure が提供する FaaS (Functions as a Service)です。
作成した関数を、HTTP や Azure の各サービスからの通知をトリガーから実行でき、出力結果についてもほかのサービスと連携が可能なので、使い勝手の良いサービスです。
Azure Functions は、関数を実行するランタイム部分と、スケーリングを制御する部分で構成される Azure 上のサービスで、このうち後者のスケーリング制御は KEDA/Kubernetes に置き換えることができます。
KEDA/Kubernetes 上で動作させることができるので、オンプレミス環境のような Azure プラットフォームの外で Azure(?) Functions が利用できます。
ちなみにランタイム部分はオープンソースとして GitHub で公開 されており、issue や Pull Request を通して開発者と直接コンタクトを取ることが可能ですので、興味がある方はどうぞ。
やってみる
実際に動かしてみます。
前準備
以下 3 つのコマンド ツールをローカル環境にインストールしておきます。
- Azure Functions Core Tools
Azure Functions を開発/デプロイするためのコマンドfunc
がインストールされます。
https://github.com/Azure/azure-functions-core-tools#installing
今から入れる人は v3 を入れるといいでしょう。 - kubectl
Kubernetes を操作するコマンド ツール (だという理解)
https://kubernetes.io/ja/docs/tasks/tools/install-kubectl/ - Docker
KEDA へのデプロイ時に Docker コンテナー イメージのビルドと発行をするので必要です。
構築本番
Kubernetes が動くオンプレ環境が準備できなかったので、今回は Azure の Kubernetes サービス、AKS を使って試してみます。
# 結局 Azure 上なのであまり KEDA を使うメリットはわからないですが、あくまで「試し」です。
1. AKS リソースをデプロイ
ポータルからポチポチしたらデプロイできるので、難しいことはないです。
2. kubectl の設定
AKS 上の Kubernetes の認証情報をローカルの kubectl の設定ファイル ($HOME/.kube/config
) に保存します。
az aks get-credentials --resource-group $RG_NAME --name $AKS_NAME
このコマンドを実行すると、kubectl から AKS 上の Kubernetes の操作が可能になります。
※以降の手順では、一切 kubectl
を実行していませんが、func
が内部的に使用しています。
Azure ポータルからもコマンドの確認が可能です。
3. KEDA コンポーネントのインストール
AKS 上の Kubernetes に名前空間を作成しつつ、KEDA コンポーネントをインストールします。
func kubernetes install --namespace $CLUSTER_NAMESPACE
4. デプロイする関数の準備
ローカルの開発環境に Function App 用のプロジェクトを作り、次に Queue トリガー関数を作ります。 関数の実装言語はお好みのものを。
func init --docker --javascript func new --javascript --template "Azure Queue Storage trigger" --name queuetrigger1
最終的に Docker コンテナーとしてデプロイするので、Dockerfile を生成する --docker
をつけています。
既に実装中のプロジェクトがある場合は、下記コマンドで Dockerfile を生成するといいでしょう。
func init --docker-only
AKS 上で起動が確認できればいいだけなので、作成した関数はほぼテンプレのまま、メッセージを受信してから 5 秒スリープするだけです。
const sleep = (time) => { return new Promise((res) => { setTimeout(() => { res(); }, time); }) } module.exports = async function (context, myQueueItem) { await sleep(5000); context.log('JavaScript queue trigger function processed work item', myQueueItem); };
その他、function.json や Dockerfile はこちら。
{ "bindings": [ { "name": "myQueueItem", "type": "queueTrigger", "direction": "in", "queueName": "<QUEUE_NAME>", "connection": "<APPSETTING_NAME_FOR_QUEUE_STORAGE>" } ] }
# To enable ssh & remote debugging on app service change the base image to the one below # FROM mcr.microsoft.com/azure-functions/node:3.0-appservice FROM mcr.microsoft.com/azure-functions/node:3.0 ENV AzureWebJobsScriptRoot=/home/site/wwwroot \ AzureFunctionsJobHost__Logging__Console__IsEnabled=true COPY . /home/site/wwwroot RUN cd /home/site/wwwroot && \ npm install
5. 関数のデプロイ
AKS の KEDA 上に関数をデプロイします。
その前に、local.settings.json で定義している値をデプロイ環境用のものに変更しておきます。
デプロイの時点で Function App のアプリケーション設定に相当する情報は、local.settings.json からインポートされ、KEDA の Secret として保存されますので、例えば、ローカルでの開発に Storage Emulator を使って UseDevelopmentStorage=true
などを設定している場合は、デプロイ前に正しいストレージ アカウントへの接続文字列へ変更しておきます。
デプロイ自体のコマンドはこれだけです。
func kubernetes deploy --name $NAME_IMAGE --registry $USERNAME_REGISTRY --namespace $CLUSTER_NAMESPACE
このコマンドを実行すると、
-
docker build
でコンテナー イメージを作成 -
docker push
で Registry に登録 -
$HOME/.kube/config
の認証情報に基づいて、Kubernetes に反映
が一気に実行され、デプロイ完了です。
動作確認
実際に関数を動かした時に、KEDA でスケールするのか、確認してみました。
KEDA に乗せた関数は Queue トリガーで実行されるので、キューにメッセージを追加する HTTP トリガー関数をローカルで、0.1 毎に実行してみました。
その様子がこちらです。
最初のポッドが起動するまでややかかりますが、その後はたまったキュー メッセージを処理するためにどんどんポッドが追加され、スケール アウトしていく様子がわかります。
ほおっておけば、 0 までスケール インします。
まとめ
Azure Functions 用の関数を (AKS 上であったものの) KEAD 上で動作させ、メッセージ量に応じてポッドがスケーリングがされることが確認できました。
今回、Queue トリガーを使いましたが、KEDA では以下のトリガーもサポートされています。
- Azure Service Bus キュー
- Azure Event/IoT Hubs
- Apache Kafka
- RabbitMQ キュー
HTTP でのスケーリングはサポートされていないようで、別途 Prometheus とかいうのが必要です。 dev.to
最後に公式ドキュメントをご紹介。 docs.microsoft.com