Oracle Functions をやってみたかったので、Oracle Cloud Free Tier を登録して、やってみました。
Oracleのサイトをなぞっただけの記事で、ほぼ自分のメモです。
Oracle Cloud Free Tier
下記です。
https://docs.cloud.oracle.com/ja-jp/iaas/Content/FreeTier/freetier.htm#AlwaysFreeResources
Always Free で、仮想マシンやデータベースが、永遠に無料で使えるっていう とてもいいサービスです。
Oracle Functions
Fn Projectがベースの Oracle Cloud上で動作するFaaSプラットフォームが、Oracle Functionsです。 なんと、200万リクエストまで無料です。
また、Dockerを用いたプラットフォームであるため、既存のDockerイメージを使用することも可能とのことです。今度、やってみようと思ってます。これかなぁ↓
https://docs.cloud.oracle.com/ja-jp/iaas/Content/Functions/Tasks/functionscreatingfunctions.htm
事前準備
チュートリアルですと、都度都度な感じで記載してあったんですが、先にメモっておいたほうが良かったものを列挙します。
結果的に、先に調べて、テキストエディタにコピペしておくと便利なものです。
コンパートメントOCID
「アイデンティティ」→「コンパートメント」で、使用するコンパートメントを選択し、詳細画面で、OCIDをコピーして取得します。個人でやってる分には、別のコンパートメントを作ってないと思うので、ルートのものでいいと思います。
ユーザー名、ユーザーOCID
コンソール画面のアカウント(右上の人形マーク)を押すと、「プロファイル」って出ますが、その下にある文字列がユーザ名ですのでコピペしておきます。「oracleidentitycloudservice/ほげほげ」となってるやつです。さらに、そこをクリックすると詳細画面になるので、OCIDもコピーしておきます。
テナンシOCID、テナンシネームスペース
コンソール画面のアカウント(右上の人形マーク)を押して、テナンシをクリックします。テナンシの詳細画面から、OCIDとネームスペースをコピーしておきます。
ポリシーの設定
次に、ポリシーを設定します。
「アイデンティティ」→「ポリシー」で、「ポリシーの作成」を押します。
名前とかは適当(例えば、oracle-functions-poricy)に入れて、「ステートメント」のところで、下記の2つをセットします。
1つめ↓
Allow service FaaS to use virtual-network-family in compartment id [コンパートメントID]
2つめ↓
Allow service FaaS to read repos in tenancy
VCN(仮想ネットワーク)の作成
「ネットワーキング」→「仮想クラウド・ネットワーク」で、「VCNウィザードの起動」で作ります。
「インターネット接続性を持つVCN」を選びます。
名前は適当(例:vcn1)に入れ、あとは初期値で作りました。
・VCN CIDRブロック:10.0.0.0/16
・パブリック・サブネットCIDRブロック:10.0.0.0/24
・プライベート・サブネットCIDRブロック:10.0.1.0/24
開発環境用インスタンス(Compute)の作成
ここは、別のマシンでDockerが動いているのがあれば、それでもいいんだと思いますが、いろんな開発環境が最初から入っているイメージが準備してあるのと、せっかく無料なので、OCI上に作りました。
「コンピュート」→「インスタンス」で、「インスタンスの作成」です。
名前は適当(例:always-free-01)に入れ、イメージを選ぶところで、「Oracle Cloud Developer Image」を選びます。
always free は、下記のスペックです。
https://docs.cloud.oracle.com/ja-jp/iaas/Content/FreeTier/resourceref.htm
VCNは、上記で作成したVCSを選びます。
SSHでログインするための、キーも作っておきます。(自分はMacを使っているので、これで、ターミナルからログインしてます。)
ログインするために、パブリックIPアドレスを控えておきます。
インスタンスへのログイン
自分はMacなので、上記でダウンロードしたキーを、「.ssh」ディレクトリ配下にコピーしました。
パーミッションを変えておきます。
$ chmod 400 .ssh/ほげほげ.key
そして、ホームディレクトリから、下記コマンドでログインします。
ユーザー名はopcです。
$ ssh -i .ssh/ほげほげ.key opc@パブリックIPアドレス
開発環境の構築
Oracle Functionsの環境構築のために、以下が必要とのことです。
・Docker
・OCI CLI
・Fn Server
・Fn CLI
今回は、Oracle Cloud Developer Imageを使ってインスタンスを作ったので、DockerとOCI CLIはインストール済みです。
そこで、fnプロジェクト関連のみインストールします。
fnプロジェクトのインストール
opcユーザにDockerの操作を許可します。実行したら exitでログアウトして、再ログインします。
$ sudo usermod -aG docker opc
$ exit
再ログインしたら、下記コマンドでインストールします。
$ curl -LSs https://raw.githubusercontent.com/fnproject/cli/master/install | sh
下記コマンドで、動作確認します。
$ fn start
動作したら、CTRL + C
でサーバを停止します。
OCI CLIのセットアップ
OCI CLI はインストールされているので、セットアップだけします。
$ oci setup config
Enter a location for your config [/root/.oci/config]: [Enter]
Enter a user OCID: ←ユーザOCIDを入力
Enter a tenancy OCID: ←テナンシOCIDを入力
Enter a region : ap-tokyo-1 ←東京リージョンは、ap-tokyo-1
Do you want to generate a new RSA key pair? (If you decline you will be asked to supply the path to an existing key.) [Y/n]: Y
Enter a directory for your keys to be created [/home/opc/.oci]: [Enter]
Enter a name for your key [oci_api_key]: [Enter]
Public key written to: /root/.oci/oci_api_key_public.pem
Enter a passphrase for your private key (empty for no passphrase): [Enter]
Private key written to: /home/opc/.oci/oci_api_key.pem
CLIからOCIに対してアクセスを行う際には、このときに作成されたAPIキーを使います。
これを、OCI側に登録するため、公開鍵をcatして、その内容をコピペしておきます。
$ cat .oci/oci_api_key_public.pem
-----BEGIN PUBLIC KEY-----
ほげほげ
ほげほげ
-----END PUBLIC KEY-----
APIキーの登録
Oracle CloudのコンソールでAPIキーを登録します。 コンソール画面のアカウント(人型のアイコン)でユーザ名を押すと、ユーザの詳細画面になるので、リソース欄のAPIキーを押し、「公開キーの追加」をクリックし、上記でコピペしておいた公開鍵を貼り付けます。
認証トークンの作成と、oracle funtcions開発環境(Docker)の作成
認証トークン
ユーザーの詳細画面の左側のメニューで、"認証トークン"をクリックし、さらに"トークンの生成"をクリックします。
「説明」に、適当なテキスト(例:for functions-dev)入力し、"トークンの生成"をクリックします。
画面が表示されるので、"コピー"をクリックし、これを手元のテキストエディタなどにペーストしておきます。
oracle funtcions開発環境の作成
FN CLIを利用してOracle Functions開発環境の作成を行います。
まずは、 fn createコマンドを使用してcontext(開発環境)を作成します。
$ fn create context [my-context] --provider oracle
[my-context]には、context名を任意に指定します。
"--provider oracle"をオプションに指定することで、Oracle Function用の環境を作成できます。
今回は、"functions-dev"という名前で作成しました。 以下のコマンドを実行します。
以降、サンプルは、function-devになっています(^^)
$ fn create context "functions-dev" --provider oracle
次に、fn useコマンドを使用して、作成した環境に切り替えます。
$ fn use context "functions-dev"
次に、開発環境にコンパートメントID、APIエンドポイント、OCIR(Oracleが提供するプライベートDockerレジストリであり、Oracle Functionsの管理を行うサービス)の設定を行います。
開発環境の設定は、fn updateコマンドを使用して行います。
以下のコマンドを実行し、コンパートメントIDを設定します。
$ fn update context oracle.compartment-id [メモっておいたコンパートメントOCID]
以下のコマンドを実行し、Oracle Functionsを呼び出す際のAPIエンドポイントを設定します。
今回は、リージョンを東京にしたので、リージョン名:ap-tokyo-1
、リージョンコード:nrt
になります。
テナンシネームスペースは、以前に控えていたものです。
$ fn update context api-url https://functions.ap-tokyo-1.oraclecloud.com
$ fn update context registry nrt.ocir.io/テナンシネームスペース/function-dev
次に、以下のコマンドを実行し、Oracle Functionsで使用するprofile名を設定します。
profile名は、今回"DEFAULT"(OCI CLIセットアップ時に設定されるデフォルトのprofile名)を入力します。
$ fn update context oracle.profile "DEFAULT"
以下のコマンドを実行し、OCIRにログインできることを確認します。
$ docker login nrt.ocir.io
ログインの際にユーザー名とパスワードを聞かれます。
Usernameは、以前に控えたテキストを連結して使います。
[テナンシネームスペース]/[ユーザ名]
Passwordは、前記でコピペしておいた認証トークンです。
ログインに成功すると以下のように表示されます。
Login Succeeded
以上で、Oracle Functions開発環境の作成できました。
Oracle Functionsのアプリケーション作成
いよいよ、アプリケーションの作成です(^^)V
「開発者サービス」→「ファンクション」で、「アプリケーションの作成」を押します。
今回はサンプルのまま、
・名前:「helloworld-app」
・VCN:「(最初に作ったVCNの名前、例:vcn1」
・サブネット:「(VCNに紐づくパブリックサブネット)」
を選び、「作成」を押します。
これで、OKです。
アプリケーション(ファンクション)の作成・デプロイ
ファンクションプロジェクトの作成
先ず、ファンクションを作るプロジェクトを作ります。
いくつかの言語のひな形があり、それからプロジェクトを作れるようです。
最終的には、Dockerで作ったものを割り当てたいところですが、最初なんで、今回は、Javaでアプリケーションを作成してみます。
まずは、fn initコマンドを使用してファンクションのひな形を作成します。
・fn initコマンド
--runtime:使用する言語を指定します。今回はjavaを指定します。
--trigger:HTTPのエンドポイントを追加するためのオプション
とのことなので、以下のコマンドを実行し、ファンクションプロジェクトを作成します。
$ fn init --runtime java helloworld-func
「helloworld-func」っていうディレクトリができました。
すっごく深いんですが、ここ↓にソースがあります。
$ ls helloworld-func/src/main/java/com/example/fn/
HelloFunction.java
中身はこんなんでした。
$ cat helloworld-func/src/main/java/com/example/fn/HelloFunction.java
package com.example.fn;
public class HelloFunction {
public String handleRequest(String input) {
String name = (input == null || input.isEmpty()) ? "world" : input;
System.out.println("Inside Java Hello World function");
return "Hello, " + name + "!";
}
}
引数を入れると、「Hello (引数)!」となり、引数なしだと、「Hello, world!」となるプログラムみたいです。
今回は、何もいじらず、そのままデプロイします。
ちなみに、テスト用のコードが同じようなパスのところにあって、ソースを変えたとき、ここも変える感じです。
$ ls helloworld-func/src/test/java/com/example/fn/
HelloFunctionTest.java
中身はこんなんでした。
$ cat helloworld-func/src/test/java/com/example/fn/HelloFunctionTest.java
package com.example.fn;
import com.fnproject.fn.testing.*;
import org.junit.*;
import static org.junit.Assert.*;
public class HelloFunctionTest {
@Rule
public final FnTestingRule testing = FnTestingRule.createDefault();
@Test
public void shouldReturnGreeting() {
testing.givenEvent().enqueue();
testing.thenRun(HelloFunction.class, "handleRequest");
FnResult result = testing.getOnlyResult();
assertEquals("Hello, world!", result.getBodyAsString());
}
}
引数なしで呼んだとき、「Hello, world!」って返すことをテストしているようです・・。
細かい書き方は、まだ調べてません・・(^^;
デプロイ
以下のコマンドを実行し、ファンクションプロジェクトに移動します。
$ cd helloworld-func
以下のコマンドを実行し、ファンクションをデプロイします。
--appでアプリケーション名を指定します。
指定するアプリケーションは、先程コンソール画面で指定したアプリケーション名(今回は、helloworld-app)です。
$ fn deploy --app helloworld-app
ちょっと時間かかります。
アプリケーション(レジストリ)の確認
コンソールで、「開発者サービス」→「レジストリ(OCIR)」とすると、
[コンテキスト名]/[Oracle Functionsプロジェクト名]
なものが表示されてばOKです。
今回は、
functions-dev/helloworld-func
ができてればOKです。
Oracle Functionsの実行
今回は、チュートリアル通り、開発環境の仮想マシンから、Oracle Functionsを実行してみます。
fn invoke [アプリケーション名] [プロジェトト名]
今回は、下記ですね。
fn invoke helloworld-app helloworld-func
以下のように表示されれば成功です。
Hello, World!
ちなみに、
引数を入れれるようになってましたので、下記もやってみました。
$ echo -n 'Japan' | fn invoke Helloworld-app helloworld-func
結果↓
Hello, Japan!