Azure で とっても簡単に python のサーバレス環境を作ってみる


同僚から、Azure のサーバーレスに対して一つのリクエストをもらった。彼は、python で書きたいらしい。サーバーレスのもっとも良いところは、サーバーをある意味気にしなくていいところだが、使ったぶんだけ課金というパートを除けば、常にクラスタをデプロイしたままでのサーバーレス環境も生産性という意味では悪くないかもしれない。

自分がサーバーレスの世界に求めるのは、何と言っても簡単さだ。だから、セットアップもできるだけしたくない。今回は、たまたまハッカソンで触った OpenFaaS という Swarm / k8s にデプロイしたら動くシンプルなものを作って、彼のデマンドに答えてみたい。OpenFaaS は、ストレージや、キューのトリガーすらない、httpだけの非常にシンプルなものだ。

基礎的なアイデア

基礎的なアイデアはとしてもシンプルだ。彼からのお題は、ブロブにアップロードした画像解析をpython でサクッとしたいとのことだ。ライブラリが充実しているから python がいいらしい。ところが、Azure Functions は今の所、Windows ベースなので、Python や Ruby が使えたところで、ネィティブエクステンション系のライブラリは相当辛いだろう。

だから、こんな感じはどうだろう?

Blob -> Logic Apps -> OpenFaaS -> Blob

単純にいうと、ブロブに何かアップロードされたら、Logic Apps が拾って、httpのリクエストを、Open FaaS に投げる。Open FaaS は同期もしくは、非同期でそのリクエストを受け取って、リスクエストに格納されたファイル名にアクセスして、取得して分析するという感じ。このクソシンプルな作戦だと、OpenFaaSじゃなくても他のでも使える。ちなみに、Azure Container Instance を使わなかったのは、今の所オースケストレーターがないから。また、高負荷にも多分耐えられないから(スケールしないので)今後楽しみね。

OpenFaaS でファンクションを作る

まずは、OpenFaaS 側でファンクションを作ろう。必要なものは、2つだけ。シンプルなエコーもどきを、実装しよう。JSON の方がいいだろうから、JSON でエコーするようにする。OpenFaaS のセットアップは、私のブログポストを参考にしてほしい。

必要なものは、2つだけ。 handler.py と、storage.yaml 。ファンクションの名前をつけたディレクトリを作って、そこに、handler.py を置くだけ。

├── storage
│   └── handler.py
├── storage.yaml

handler.py

import json

def handle(req):   
    print('{ "recieve" : ' + req + "}")

storage.yaml (名前はなんでも良い)

provider:
  name: faas
  gateway: http://13.93.212.187:8080

functions:
  storage-trigger:
    lang: python
    handler: ./storage/
    image: tsuyoshiushio/storage-trigger

どちらも一回書いてしまえばクソ簡単。デプロイしよう。

faas-cli -action build -f ./storage.yaml
faas-cli -action push -f ./storage.yaml
faas-cli -action deploy -f ./storage.yaml

準備おっけー。ちなみに、OpenFaaS は内部で Docker を使っているので、ネイティブエクステンション問題は問題ない。Windows Container にも対応しているらしい。(それだったら、Azure Function使うけどw)

Logic Apps を設定する

Logic Apps は、Azure のサーバーレスのオファーの一つで、コーディングレスで、いろんなサービスをつなぐことができる。Azure に限らない。いろんなイベントを拾うことができる。Blob にアップされたらとか、VM ができたら、Event Grid という仕組みもできたので、ほぼ全てのイベントを拾うことができる。
イベントきっかけで、いろんなサービスを連携させることができる。今回は、ブロブのイベントを拾って、OpenFaaS で作ったファンクションに連携させる。ちなみに、事前に、Storage Account は作成しておいた。

ちなみに Logic Apps の Web action でハマったところは、最初、このアプリがBad Request で帰ってきたこと。正しい Json ではないとのこと。原因は、Logic Apps 側の設定ではなく、Function が返してきたレスポンスが、正しい Json ではないから。手元を散々見直してハマったが、実は、向こう側の問題だったということ。

これを、保存して実行させておいて、ブロブに何かの画像をアップさせる

そしたら、自動的に、Logic Apps がイベントを拾って、ファイル名を、ファンクションにポストする

あとは、自分で、Azure SDK を使ってキューを取りに行かないと行けないけど、かなり楽チンじゃないかなぁー。

終わりに

次回は、ここから発展させてみて、色々繋げてみる。また、Function を作ったら、できれば、Logic Apps を書くのを自動化できないかなとかふと思ってみたり。

リソース