Azure Functions をAzure 以外のクラウドプロバイダーで動かしてみる。

2021年7月31日

はじめに

これはServerless Advent Calendar 2020に12月6日分になります。

内容手にはServerless MeetupやJAZUGで登壇した内容を記事化したものになります。

どうやって動かすか

現状、Azure FunctionsをAzure以外で動作させる方法としてはKnativeがありますが、今回はKEDAで動作させる方法になります。

実際にAWS上でAzure Functionsを動作させることも可能で動作報告もあります。

余談:KnativeでKnative Lambda Runtime(AWS Lambda互換) をGKEで動作している報告もあります。

オープンソースで公開されているがGoogleが主体で開発を進めています。
CNCF(Cloud Native Computing Foundation)へは加わらない方針だそうです。

KEDA

今回はKEDA(Kubernetes Event-driven Autoscaling)を利用しています。

イベント駆動型オートスケーラーです。
MicrosoftとRedHatで共同開発、CNCFに採用されました。
オンプレミス、Azure Kubernetes Service、RedHat OpenShiftなどの環境で利用可能です。
現在、Version 2.0 (2020/11/17)でリリーススピードが2~3か月です。
構成がシンプルで導入が楽です。

  • Helm charts
  • Operator Hub
  • YAML declarations

仕組み

主に2つの仕組みがあります。

Agent
Kubernetes Deploymentsのアクティブ化、非アクティブ化を行います。イベントが無い場合にはゼロスケールします。
0->1 or 1->0

Metrics
メトリクスサーバーとして機能し、Horizo​​ntalPod Autoscalerと連携します。様々なメトリクスに対応します。
1->n or n->1

対応するスケーラー

  • ActiveMQ Artemis
  • Apache Kafka
  • AWS CloudWatch
  • AWS Kinesis Stream
  • AWS SQS Queue
  • Azure Blob Storage
  • Azure Event Hubs
  • Azure Log Analytics
  • Azure Monitor
  • Azure Service Bus
  • Azure Storage Queue
  • CPU
  • Cron
  • External
  • External Push
  • Google Cloud Platform‎ Pub/Sub
  • Huawei Cloudeye
  • IBM MQ
  • Liiklus Topic
  • Memory
  • Metrics API
  • MySQL
  • NATS Streaming
  • PostgreSQL
  • Prometheus
  • RabbitMQ Queue
  • Redis Lists
  • Redis Streams
  • *HTTP Trigger(Prometheusを利用して1->nスケールに対応)
    たぶんAzure Functionsでやろうと思えばできるかも・・・

    様々なリソースが利用可能です。

    ここからはAzure Functionsをどうやって動かすかを説明します。

    Azure Functions Core Tools

    ローカル環境で動作するAzure Functionsを利用します。
    Docker でも動作します。

    Azure Functions on Kubernetes with KEDA

    デモ環境

    EKSからAzure Queue Storageからキューを取り込むだけの環境です。

    必要なもの

  • Azure CLI(ポータル使わないならいる)
  • Git
  • Kubectl
  • Docker
  • npm
  • AWS CLI
  • eksctl
  • 今回の検証ではVisual Studio Codespaces を利用しています。
    CodespaceにはAzure CLI、Docker、Git、npmはすでにインストール済みでした。

    Azure Functions Core Toolsのインストール

    npm install -g azure-functions-core-tools@3
    mkdir keda
    cd keda
    func init . --docker
    
    Select a number for worker runtime:
    1. dotnet
    2. node
    3. python
    4. powershell
    5. custom
    Choose option: 2
    node
    Select a number for language:
    1. javascript
    2. typescript
    Choose option: 1
    javascript
    Writing package.json
    Writing .gitignore
    Writing host.json
    Writing local.settings.json
    Writing /home/codespace/workspace/keda/.vscode/extensions.json
    Writing Dockerfile
    Writing .dockerignore
    
    func new
    
    Select a number for template:
    1. Azure Blob Storage trigger
    2. Azure Cosmos DB trigger
    3. Durable Functions activity
    4. Durable Functions HTTP starter
    5. Durable Functions orchestrator
    6. Azure Event Grid trigger
    7. Azure Event Hub trigger
    8. HTTP trigger
    9. IoT Hub (Event Hub)
    10. Azure Queue Storage trigger
    11. SendGrid
    12. Azure Service Bus Queue trigger
    13. Azure Service Bus Topic trigger
    14. SignalR negotiate HTTP trigger
    15. Timer trigger
    Choose option: 10
    Azure Queue Storage trigger
    Function name: [QueueTrigger] 
    Writing /home/codespace/workspace/keda/QueueTrigger/index.js
    Writing /home/codespace/workspace/keda/QueueTrigger/readme.md
    Writing /home/codespace/workspace/keda/QueueTrigger/function.json
    The function "QueueTrigger" was created successfully from the "Azure Queue Storage trigger" template.
    

    Azure Queue Storageの作成

    事前にjs-queue-items という名前でQueueを作成します。

    設定

    local.settings.json

    {
      "IsEncrypted": false,
      "Values": {
        "FUNCTIONS_WORKER_RUNTIME": "node",
        “AzureWebJobsStorage”:“接続文字列" }
    }
    

    接続文字列はStorageのアクセスキーを確認します。

    QueueTrigger/index.js

    module.exports = async function (context, myQueueItem) {
        context.log('JavaScript queue trigger function processed work item', myQue
    };
    
    

    EKS クラスター起動

    aws configure
    eksctl create cluster --name keda-aws --region=us-east-1 --node-type t3.medium --nodes 1
    

    .kube/config も勝手に設定してくれます。

    EKSにKEDAをインストール

    kubectl create namespace keda
    func kubernetes install --namespace keda
    
    
    kubectl get deploy --namespace keda
    NAME                              READY   UP-TO-DATE   AVAILABLE   AGE
    keda                              1/1     1            1           6d23h
    
    kubectl get pod --namespace keda
    NAME                                               READY   STATUS    RESTARTS   AGE
    keda-6d99f77c57-rvdw6                              2/2     Running   0          6d23h
    

    KEDA

    kubectl get pod keda-6d99f77c57-djqbk -n keda -o yaml | grep image:
        image: docker.io/kedacore/keda:1.1.0
        image: docker.io/kedacore/keda-metrics-adapter:1.1.0
        image: kedacore/keda:1.1.0
        image: kedacore/keda-metrics-adapter:1.1.0
    

    Azure Function アプリをデプロイ

    docker login
    func kubernetes deploy --name kedaqueue --registry “Docker hub アカウント名”
    
    kubectl get deploy
    NAME        READY   UP-TO-DATE   AVAILABLE   AGE
    kedaqueue   0/0     0            0           6d23h
    
    kubectl get pod
    No resources found in default namespace.
    

    動作確認

    1、Azure Queue Storageにキューを追加する。
    2、Podsを確認する。

    5分でターミネートされます。

    kubectl get pod –w
    NAME                         READY   STATUS    RESTARTS   AGE
    kedaqueue-65dd865b95-l6p7p   0/1     Pending   0          0s
    kedaqueue-65dd865b95-l6p7p   0/1     Pending   0          0s
    kedaqueue-65dd865b95-l6p7p   0/1     ContainerCreating   0          0s
    kedaqueue-65dd865b95-l6p7p   1/1     Running             0          3s
    kedaqueue-65dd865b95-l6p7p   1/1     Terminating         0          5m
    kedaqueue-65dd865b95-l6p7p   0/1     Terminating         0          5m2s
    kedaqueue-65dd865b95-l6p7p   0/1     Terminating         0          5m3s
    kedaqueue-65dd865b95-l6p7p   0/1     Terminating         0          5m3s
    

    GKEでも確認済みです。
    Alibaba Cloudでも確認済みです。
    (中国リージョンはDockerHub を利用できないのでContainer Registryを利用しました。

    まとめ

    Azure FunctionsはAWSで動作します。
    クラウドプロバイダーでも動作します。
    GCP、Alibaba Cloudでも。
    Azure Functionsを別にしてもKEDAはニッチな所で登場するかもしれません。