11
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Azure Kubernetes Service(AKS)とKEDAを利用したサーバレス

Last updated at Posted at 2021-10-18

はじめに

この記事ではAzure Kubernetes Service(以下、AKS)とKEDAを利用したサーバレスなイベント駆動型アプリケーションの構築方法について解説します。

想定読者

  • Kubernetesを利用したことがある方
  • Azureが好きな方

Kubernetesにおけるスケーリング

Kubernetesにおけるアプリケーション(ポッド)のスケールの方法の1つとしてHPA(Horizontal Pod Autoscaler)があります。これはPodで利用しているリソース消費量(CPUやメモリ)を監視して、高負荷時にポッドを自動でスケールアウトするものです。

この記事で紹介するKEDAは同じく水平スケールを実現するKubernetesのコンポーネントで、イベント駆動型のアプリケーションに対応しています。KEDAではHPAに比べて以下の特徴があります。

  • イベントの急激な増加を素早く検知して、処理前にスケールアウトをする

    HPAではイベントがPodに到達した後、リソースの消費量等をもとにスケールアウトの判断することが多いです(External Metricsなど、必ずしもそうではありません)。一方でKEDAではイベントソース(キューやストリームなど)の状態を監視して、イベントがPodに到達する前にあらかじめスケールアウトの判断をすることができます。

  • イベントが発生していない時に無駄なリソースを消費しない

    HPAではスケール範囲が1~nであり、イベントが発生していない場合にもリソースの消費が発生します。一方でKEDAではスケール範囲が0~nであり、イベントが発生していない場合のリソース消費量を抑えることができます。

KEDAとは

MicrosoftとRed Hatが中心となって開発されたオープンソースプロジェクトで、Kubernetes Event-driven Autoscalingの頭文字をとってKEDAとされています。Kubernetes上で動作するサーバレスなイベント駆動型のオートスケールを実現します。KEDAを利用することで、0~nのスケーリングを実現できます。サーバレスと呼ばれるのはこの特徴があるからです。

アーキテクチャ

KEDAは大きく3つのコンポーネントにより構成されています。ControllerScalerMetrics adapterです。

Controllerは、KubernetesのDeploymentに対してアクティブ・非アクティブを制御し、0からのスケールを実現しています。

Scalerはトリガとして指定された外部リソースからメトリクス(キューの長さなど)を取得します。

Metrics adapterScalerで取得したメトリクスをHPAに提供します。従来のHPAが対応しているメトリクスに加えて、豊富な情報を利用してオートスケールを実現できます。

詳細な情報は公式サイトのこちらを参照してください。

keda-arch.png

サポートするイベントソース

KEDAで処理できるイベントソースとして、以下Azureリソースを利用したものに対応しています。ここで挙げたトリガ以外にも様々なトリガに対応しているので、KEDAのサイトをご覧ください。

  • Azure Storage Queue
  • Azure Service Bus Queue
  • Azure Event/IoT Hubs
  • Azure Log Analytics
  • Azure Monitor

Azure Functionsとの統合

さらにAKSでKEDAを利用するうえで便利なことの1つに、Azure Functionsと統合できることが挙げられます。
Azure Functionsのコードをそのままにコンテナ化することで、AKS上にホストすることができるのです。
ここからは実際にその流れを解説していきます。

AKSとKEDAを利用してサーバレスアプリケーションを構築する

Azure Storage QueueをトリガとしたAzure FunctionsをAKSにデプロイするシナリオを想定します。

事前準備(ローカルPC)

ローカルPCに以下ツールをインストールします。

  • Azure Functions Core Tools

    Azure Funtionsを開発するためのコマンドラインツールです。AKSにKEDAをインストールしたりAKSにデプロイしたりする機能が含まれています。

  • Azure CLI

    Azureリソースを操作するのに利用します。

  • kubectl

    kubernetesを制御するためのコマンドラインツールです。本記事では動作確認などに利用します。

  • Docker

    Azure Functionsのコードをコンテナ化し、レジストリにPushするために利用します。

Azureリソースの構築

Azureの以下リソースを利用します。それぞれのリンクを参考に構築します。

az aks update -n <AKS名> -g <リソースグループ名> --attach-acr <ACR名>

手順

AKSへの接続情報取得

以下コマンドを実行し、AKSへの接続情報を取得します。

az aks get-credentials --resource-group <リソースグループ名> --name <AKSクラスタ名>

kubectl config get-contextsを実行したときに作成したAKSクラスターが選択されていればOKです。

KEDAのインストール

Azure Functions Core Toolsを利用してKEDAをAKSにインストールします。
以下コマンドを実行してKEDAをインストールします。

kubectl create namespace keda
func kubernetes install --namespace keda

コンソールにKEDA v2 is installed in namespace kedaと表示されればインストール完了です。
試しにkubectl get pods --namespace kedaを実行すると、kedaのPodが確認できます。

NAME                                      READY   STATUS             RESTARTS   AGE
keda-metrics-apiserver-8458c8f96d-mcblr   1/1     Running            0          1m
keda-operator-69c986985-sdp46             1/1     Running            0          1m

ACRへのログイン

ACRへコンテナをpushするため、Azure CLIを利用してACRにログインします。

az acr login -n <ACR名>

コンソールにLogin Succeedと表示されればログイン完了です。

Azure Functionsのプロジェクトと関数の作成

Azure Functionsのプロジェクトを作成します。AKSではコンテナを利用するため、--docker-onlyオプションをつけてプロジェクトを作成します。また言語はJavaScriptを利用します。

func init --docker-only --javascript

続けて関数を作成します。

func new --javascript --template "Azure Queue Storage trigger" --name queuefunc

作成されたファイルのうち、以下をそれぞれ書き換えます。

  • index.js:メイン処理

    スケーリングを確認するため待機処理を追加

function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

module.exports = async function (context, myQueueItem) {
    sleep(10000); // ←この行を追加
    context.log('JavaScript queue trigger function processed work item', myQueueItem);
};
  • local.setting.json:環境変数の定義

    AzureWebJobsStorageに作成したストレージアカウントの接続文字列を追加

{
  "IsEncrypted": false,
  "Values": {
    "FUNCTIONS_WORKER_RUNTIME": "node",
    "AzureWebJobsStorage": "DefaultEndpointsProtocol=https;AccountName=...."
  }
}
  • function.json:関数の定義

    トリガとなるQueueの名前、ストレージアカウントの接続文字列が書かれている環境変数名を追加

{
  "bindings": [
    {
      "name": "myQueueItem",
      "type": "queueTrigger",
      "direction": "in",
      "queueName": "Storage Queueの名前",
      "connection": "AzureWebJobsStorage"
    }
  ]
}

AKSへのデプロイ

準備が整ったのでAKSへのデプロイを実施します。
Azure Functionsのプロジェクトのディレクトリで、以下コマンドを実行します。

func kubernetes deploy --name <関数の名前> --registry <ACR名.azurecr.io> --namespace keda

このコマンドを実行すると、内部的に以下の処理が行われています。

  1. Dockerイメージのビルド
  2. DockerイメージのレジストリへのPush
  3. AKSへのマニフェストのデプロイ

実際にACRを確認すると指定した関数名のリポジトリが作成され、イメージがPushされていることが確認できます。(タグはlatest)

acr.png

またAKSにデプロイされるオブジェクトは、先ほどのコマンドに--dry-runのオプションをつけることでマニフェストを確認できます。

func kubernetes deploy --name <関数の名前> --registry <ACR名.azurecr.io> --namespace keda --dry-run

3つのKubernetesオブジェクトがデプロイされていることを確認できます。

  • Deployment

    アプリケーション本体

  • Secret

    local.setting.json内で定義した環境変数

  • ScaledObject

    KEDAのカスタムリソースで、トリガやスケール対象のDeploymentを指定する

動作確認

指定したAzure Queue Storageに対して(数100件ほど)メッセージを追加したときのPodの状態になります。作成したqueuefuncがスケールアウトしていることを確認できます。

またメッセージをすべて処理した後の状態でアイドル状態が続けば、対象のPodは1つも存在しない状態になることも確認できます。冒頭で解説した0~nのスケールを確認することができました。

auto-scaling.gif

おわりに

この記事ではKEDAを利用してAzure FunctionsをAKSで実行する流れについて解説しました。

本文中で解説しきれませんでしたが、プロダクション環境での利用する場合は、環境変数の扱いやコンテナのタグの運用方法など様々な検討事項が残ります。KEDAのサイトやAzure Functionsのリファレンスにヒントがありますのでぜひ参照してみてください。

参考

11
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?