Oracle Functions (Limited Availability)を触ってみる

こんにちは id:dhigashi です。

「Fn Projectを触ってみる」の第3弾です。ついに Oracle Cloud Infrastructure の Function as a Service (FaaS) サービスである Oracle Functions が Limited Availability として利用できるようになったので触ってみます。

Function を実行するまでの手順は以下を参考にしています。 www.oracle.com

※本記事の内容は一般提供が開始される際には内容が変更になるかもしれませんのでご注意下さい。

尚、Limited Availability Program については id:s-oomori が記事を書いてくれています。
先行して利用してみたい方はこちらをご覧ください。

cloudii.atomitech.jp

また、Oracle Functions のベースとなっている Fn Project についてはこれらの記事で取り扱っています。こちらも是非ご覧下さい。
当時と現在とではコマンドなどに破壊的変更があるので読み替える必要があります...😨

cloudii.atomitech.jp

OCI環境の準備

Oracle Functions が Limited Availability として利用できるのは Phoenix リージョンとなっていますので、us-phoenix-1 リージョンが選択されている事を確認します。

グループとユーザーの作成

今回は Oracle Functions を利用するユーザーと、ユーザーが所属するグループを新規で作成します。

また、ユーザーの Auth Token を作成しておきます。こちらは後ほど開発環境の準備を行う際に使用します。

f:id:blog-admin-atomitech:20190213103802p:plain

コンパートメントの作成

コンパートメントも同様に検証用のものを新規で作成します。

ポリシーの設定

作成したグループ及び FaaS (Oracle Functions) サービスが必要な操作が行えるようポリシーの設定を行います。

  • グループと Oracle Functions サービスが Registry (OCIR) を利用する
Allow group <GROUP_NAME> to manage repos in tenancy
Allow service FaaS to read repos in tenancy
  • グループが作成したコンパートメント内のそれぞれのリソースを利用する
Allow group <GROUP_NAME> to manage functions-family in compartment <COMPARTMENT_NAME>
Allow group <GROUP_NAME> to manage vnics in compartment <COMPARTMENT_NAME>
Allow group <GROUP_NAME> to inspect subnets in compartment <COMPARTMENT_NAME>
  • Oracle Functions サービスが作成したコンパートメント内のリソースを利用する
Allow service FaaS to use virtual-network-family in compartment <COMPARTMENT_NAME>

VCNの作成

コンパートメント内に VCN も新規で作成します。
インターネットゲートウェイを作成し、ルートテーブルをインターネットゲートウェイへのトラフィックを許可するように設定します。

VCN作成時に CREATE VIRTUAL CLOUD NETWORK PLUS RELATED RESOURCES オプションで自動で作成しても良いかもしれません。

Creating a Virtual Cloud Network

f:id:blog-admin-atomitech:20190213104830p:plain

開発環境の準備

関数の作成、デプロイを行うために開発環境の準備を行います。

ユーザーの API Key の追加

秘密鍵と公開鍵を作成しユーザーの API Key に公開鍵を登録します。

$ openssl genrsa -out <PRIVATE_KEY_PEM_FILE> -aes128 2048
$ chmod go-rwx <PRIVATE_KEY_PEM_FILE>
$ openssl rsa -pubout -in <PRIVATE_KEY_PEM_FILE> -out <PUBLIC_KEY_PEM_FILE>

鍵が登録されるとフィンガープリントが表示され、次に OCI CLI プロファイルを設定する際に使用します。

f:id:blog-admin-atomitech:20190213230113p:plain

OCI CLI プロファイルの設定

~/.oci/config ファイルにプロファイルを追加します。
OCI CLI を利用していない場合など、ファイルが存在していない場合は新たに作成します。

これまでの準備で作成したそれぞれの値を指定します。

  • tenancy: テナンシーの OCID
  • user: 作成したユーザーの OCID
  • region: リージョン名
  • key_file: 秘密鍵へのパス
  • fingerprint: フィンガープリント
  • pass_phrase: 秘密鍵を生成した際に指定したパスフレーズ
[<PROFILE_NAME>]
tenancy=<TENANCY_OCID>
region=<REGION_NAME>
user=<USER_OCID>
key_file=<PRIVATE_KEY_PEM_FILE>
fingerprint=<PUBLIC_KEY_FINGERPRINT>
pass_phrase=<PASSPHRASE>

Docker のインストールと Registry へのログイン

Fn Project を利用する為には Docker が必要となります。
インストールしていない場合は以下などを参考にインストールして下さい。

docs.docker.com

検証に使用した環境は以下の通りです。

$ docker version
Client:
 Version:           18.09.2
 API version:       1.39
 Go version:        go1.10.6
 Git commit:        6247962
 Built:             Sun Feb 10 04:13:27 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          18.09.2
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.6
  Git commit:       6247962
  Built:            Sun Feb 10 03:47:25 2019
  OS/Arch:          linux/amd64
  Experimental:     false

Registry (OCIR) にログインします。
ユーザ名は <TENANCY_NAME>/<USER_NAME> の形式で、パスワードにはユーザーと一緒に作成した Auth Token を入力します。

$ docker login phx.ocir.io
Username: <TENANCY_NAME>/<USER_NAME>
Password:
WARNING! Your password will be stored unencrypted in /home/opc/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

Fn CLI のインストール

関数の作成やデプロイに Fn CLI を利用します。
こちらもインストールしていない場合は以下などを参考にインストールして下さい。

github.com

検証に使用した環境は以下の通りです。

$ fn version
Client version is latest version: 0.5.51
Server version:  ?

Fn CLI コンテキストの作成

新しいコンテキストを作成し、Fn CLI で使用するように指定します。

$ fn create context faas --provider oracle
Successfully created context: faas
$ fn use context faas
Now using context: faas

コンテキストに関数をデプロイするコンパートメント OCID を指定します。

$ fn update context oracle.compartment-id <COMPARTMENT_OCID>
Current context updated oracle.compartment-id with <COMPARTMENT_OCID>

コンテキストに Fn Project API を呼ぶ際に使用する API エンドポイントを指定します。
今回は https://functions.us-phoenix-1.oraclecloud.com を指定します。

$ fn update context api-url https://functions.us-phoenix-1.oraclecloud.com
Current context updated api-url with https://functions.us-phoenix-1.oraclecloud.com

コンテキストに Docker Registry と Oracle Functions で使用するリポジトリのアドレスを指定します。
リポジトリはイメージの Push 時に作成される為、REPOSITORY_NAME で指定するリポジトリを予め用意する必要はありません。

$ fn update context registry phx.ocir.io/<TENANCY_NAME>/<REPOSITORY_NAME>
Current context updated registry with phx.ocir.io/<TENANCY_NAME>/<REPOSITORY_NAME>

コンテキストに追加した OCI CLI プロファイル名を指定します。

$ fn update context oracle.profile <PROFILE_NAME>
Current context updated oracle.profile with <PROFILE_NAME>

Oracle Functions アプリケーションの作成

Web コンソールから最初の Oracle Functions アプリケーションを作成します。
この時、作成した VCN と Subnet を指定します。

f:id:blog-admin-atomitech:20190212173547p:plain

作成が完了すると、Fn CLI からもアプリケーションが確認できます。

$ fn list apps
NAME        ID
faas-demo   ocid1.fnapp.oc1.phx.aaaaaaaaag23...

関数の作成

サンプルとして Go 言語の関数を作成してみます。

$ fn init --runtime go demo-1
Creating function at: /demo-1
Function boilerplate generated.
func.yaml created.
$ cd demo-1/
$ ls -1
Gopkg.toml
func.go
func.yaml

関数のデプロイ

fn deploy コマンドで関数をデプロイします。
Docker イメージがビルドされ Registry に Push、そのイメージを使用して関数を作成していることが分かります。

$ fn deploy --app faas-demo
Deploying demo-1 to app: faas-demo
Bumped to version 0.0.2
Building image phx.ocir.io/<TENANCY_NAME>/<REPOSITORY_NAME>/demo-1:0.0.2 ................................................................
Parts:  [phx.ocir.io <TENANCY_NAME> <REPOSITORY_NAME> demo-1:0.0.2]
Pushing phx.ocir.io/<TENANCY_NAME>/<REPOSITORY_NAME>/demo-1:0.0.2 to docker registry...The push refers to repository [phx.ocir.io/<TENANCY_NAME>/<REPOSITORY_NAME>/demo-1]
e09e7954f29d: Pushed
a8170438a0a9: Pushed
db794edf2401: Pushed
0b32a561a108: Pushed
0.0.2: digest: sha256:a13bf5ddf09de057eb24fec5b784ec50c5802a60af950ab08f01fd46d7684c69 size: 1156
Updating function demo-1 using image phx.ocir.io/<TENANCY_NAME>/<REPOSITORY_NAME>/demo-1:0.0.2...
Successfully created function: demo-1 with phx.ocir.io/<TENANCY_NAME>/<REPOSITORY_NAME>/demo-1:0.0.2

Fn CLI でデプロイした関数を確認してみます。

$ fn list functions faas-demo
NAME    IMAGE                       ID
demo-1 phx.ocir.io/<TENANCY_NAME>/<REPOSITORY_NAME>/demo-1:0.0.2  ocid1.fnfunc.oc1.phx.aaaaaaaaackq...

関数の実行

fn invoke コマンドで関数を実行してみます。

$ fn invoke faas-demo demo-1
{"message":"Hello World"}

実行できました。

エンドポイントからの実行

次に HTTP リクエストで実行するために、まずはトリガーを作成します。

$ fn create trigger faas-demo demo-1 trigger-1 --type http --source /demo-1
Successfully created trigger: trigger-1
Trigger Endpoint: https://rg2fmgyldia.us-phoenix-1.functions.oci.oraclecloud.com/t/demo-1

トリガーが作成できたら fn inspect コマンドで invokeEndpoint を調べます。

$ fn inspect function faas-demo demo-1
{
        "annotations": {
                "fnproject.io/fn/invokeEndpoint": "https://rg2fmgyldia.us-phoenix-1.functions.oci.oraclecloud.com/invoke/ocid1.fnfunc.oc1.phx.aaaaaaaaackq...",
                "oracle.com/oci/compartmentId": "ocid1.compartment.oc1..aaaaaaaalfs3..."
        },
        "app_id": "ocid1.fnapp.oc1.phx.aaaaaaaaag23...",
        "created_at": "2019-02-12T08:41:56.996Z",
        "id": "ocid1.fnfunc.oc1.phx.aaaaaaaaackq...",
        "idle_timeout": 30,
        "image": "phx.ocir.io/atomitech/faas-test/demo-1:0.0.2",
        "memory": 128,
        "name": "demo-1",
        "timeout": 30,
        "updated_at": "2019-02-12T08:41:56.996Z"
}

invokeEndpoint の URL に対してリクエストを行うと関数を実行することができますが、署名付きのリクエストでなければならない為、その辺りをよしなにしてくれる oci-curl を利用します。

oci-curl については以下を参考に導入して下さい。

docs.cloud.oracle.com

oci-curl スクリプト内の tenancyId, authUserId, keyFingerprint, privateKeyPath は、OCI CLI プロファイルと同様に準備で作成した値をそれぞれ指定します。

oci-curloci-curl <host> <method> [file-to-send-as-body] <request-target> の形でリクエストを行います。
リクエストボディは指定しないので file-to-send-as-body には空のファイルを指定します。

$ oci-curl "rg2fmgyldia.us-phoenix-1.functions.oci.oraclecloud.com" POST empty.json "/invoke/ocid1.fnfunc.oc1.phx.aaaaaaaaackq..."
Enter pass phrase for <PRIVATE_KEY_PEM_FILE>:
{"message":"Hello World"}

こちらも実行できました。

まとめ

Oracle Functions を使い、関数を作成・デプロイ・実行までを行いました。
今回は簡単な関数でしたが、次は他の OCI リソースなどと組み合わせた検証も行ってみたいと思います。

Oracle Functions のベースとなる Fn Project はオープンソースの FaaS 基盤でローカル環境でも、どのパブリッククラウドでも利用することが出来ました。Oracle Functions がリリースされる事でロックインは避けつつ、インフラの運用は任せることができますね。

参考文献