本ブログは、オラクル・クラウドの個人ブログの1つです。
初めに
OCI外部から、APIゲートウェイ経由でOCI Functionを呼び出し、オブジェクト・ストレージに格納されるファイルをアクセスできます。例えば、HTTPSリクエストで郵便番号から住所を検索するのは可能です。簡単なデモを紹介させていただきます。
このデモの目的は、OCI Functionが「API Gateway」及び「Object Storage」との連携を示すことで、サーバレスの特徴を少し感じていただければと思います。
検証環境
分類 | 項目 | 内容 | コメント |
---|---|---|---|
OCI Function | 言語 | Python | |
メモリ | 512 GB | デフォルトの256 GBより引き上げた | |
タイムアウト | 30 秒 | デフォルトのまま | |
Object Storage | ファイルフォーマット | JSON | 全日本の12万件の郵便番号は登録済 |
エンコード | UTF-8 | 改行: LFのみ (Unix) | |
呼出元 | Cloud Shell | Linux | On-PのLinuxからでもOK |
On-Pクライアント | Windows | コマンド・プロンプト、PowerShell |
※、この例で使用しているソースは、ここより取得できます。
ステップ
1. 事前準備
1-1. APIキーの追加
オブジェクト・ストレージへアクセスするため、APIキーは必要です。追加方法は、以下の記事のSTEP 1-1をご参照ください。既にお持ちの場合、このステップを飛ばしてもよいです。
OCIカスタム・メトリックでディスク使用率を監視
1-2. OCI構成ファイルの作成
APIキー作成後、ほかの認証情報と一緒に構成ファイルに格納します。作成方法は、上記の同記事のSTEP 1-2をご参照ください。
ファイルの保存場所は、Functionを作成する端末です。
Linuxの場合(Cloud Shellも):/home/<your_user_name>/.oci/config
Windowsの場合:C:\Users\<your_user_name>\.oci\config
1-3. 検索対象ファイルをオブジェクト・ストレージに保存
OCIのバケットに、対象ファイルをアップロードします。バケットの可視性(Visibility)は、プライベートでOKです。バケット名をメモし、Function作成時、固定値として使います。
この例で使用しているファイルはJSONフォーマットで、イメージは以下のようです。
{
"japan": [
...<omitted>...
{
"zipcode": "1070061",
"address1": "東京都",
"address2": "港区",
"address3": "北青山"
},
...<omitted>...
]
}
2. API GWとFunctionの作成
OCI Functionを作成するのに、「Cloud Shell」を利用することは、OCIの推奨方法です。もちろん、ローカルの端末か、クラウド上のVMでも作成できます。その場合、OCI CLI、DockerとFn Projectのインストールと設定作業は必要です。
今回は「Cloud Shell」を例にして紹介します。作成方法の全体流れは、この記事(API GWでOCI Functionsの呼び出し)をご参照ください。
↑この例は、"Hello World"の出力だけで、Object Storageの利用がないから、関連ポリシーを含めません。FunctionからObject Storageへアクセスするため、以下の動的グループとポリシーを追加してください。
リソース | 名前 | 内容 |
---|---|---|
動的グループ | Func_DG | コンパートメント内のすべてのファンクションがリソースにアクセスできるようにする場合は、次のようなルールを追加:ALL {resource.type = 'fnfunc', resource.compartment.id = 'ocid1.compartment.oc1..aaaaaaaa23______smwa'}
|
特定のファンクションがリソースにアクセスできるようにする場合は、次のようなルールを追加:resource.id = 'ocid1.fnfunc.oc1.iad.aaaaaaaaacq______dnya'
|
||
ポリシー | Func_DG_Policy | 特定のオブジェクト・ストレージ・バケットに対する読取りおよび書込みができるようにするには、次のようなルールを追加:allow dynamic-group Func-DG to manage objects in compartment PoC where {target.bucket.name='<BucketName>'}
|
※「Cloud Shell」で作成する時、ほかの関連ポリシーについて、以下のドキュメントをご参照ください。
Cloud ShellでのファンクションQuickStart - 4.グループおよびサービス用のポリシーの作成
ここからFunctionソース(3個)を取得して、初期化で作成された下記ソースを置き換えたら、Deployしてください。
func.py
, func.yaml
, requirements.txt
公式なOCIドキュメントを参照したい場合、関数QuickStartガイドをご覧ください。「Cloud Shell」、ローカル・ホスト及び「OCI Computeインスタンス」の選択肢がありますので、作成場所を選んでください。
3. Functionの呼び出し
3-1. Linuxクライアントからの呼び出し
以下のシェル・スクリプトを用意しております。
シェル・スクリプト名:call_oci_func_zipcode.sh
引数: 郵便番号(7桁数値)
シェルに、引数の有無チェックと数値チェックが入っています。チェックを通した後、入力された郵便番号をJSONフォーマットの文字列に変換し、CURLコマンドを実行します。
CURLコマンドの形式:curl -k -X GET https://<Endpoint_URL> -d '{"zipcode": "1070061"}'
出力結果のフォーマット:JSON形式
初回目
初回目は、コンテナの準備時間は必要であり、時間がかかりました。平均リスポンス時間は35秒以内でした。
liu_wei@cloudshell:shell (ap-tokyo-1)$ ./call_oci_func_zipcode.sh 1070061
---------------------------------------
CURL command:
curl -k -X GET https://<OCID>.apigateway.ap-tokyo-1.oci.customer-oci.com/v1/zipcode -d '{"zipcode": "1070061"}'
---------------------------------------
12:15:24.467 - Begin invoke function.
{"zipcode": "1070061","address1": "東京都","address2": "港区","address3": "北青山"}
12:15:55.224 - End.
---------------------------------------
liu_wei@cloudshell:shell (ap-tokyo-1)$
二回目
二回目から大分速くなり、およそ2~3秒ほどでした。
liu_wei@cloudshell:shell (ap-tokyo-1)$ ./call_oci_func_zipcode.sh 1070061
...<omitted>...
---------------------------------------
12:17:05.002 - Begin invoke function.
{"zipcode": "1070061","address1": "東京都","address2": "港区","address3": "北青山"}
12:17:07.383 - End.
---------------------------------------
liu_wei@cloudshell:shell (ap-tokyo-1)$
Functionがしばらくアイドルになったら、コンテナが自動的に削除されます。再度呼出の時、またコンテナの準備時間は必要です。これはFunctionの特徴です。
3-2. Windowsクライアントからの呼び出し
引数を渡す時、Linuxの書き方と少し差異がありますので、ご注意ください ('\'
は必要)。
コマンド・プロンプトからの場合: (ダブル・クォーテーションで引数を囲む)
curl -k -X GET https://<Endpoint_URL> -d "{\"zipcode\": \"1070061\"}"
PowerShellからの場合: (シングル・クォーテーションで引数を囲む)
curl.exe -k -X GET https://<Endpoint_URL> -d '{\"zipcode\": \"1070061\"}'
(curl.exeはフルーネーム)
トラブル・シューティング
API GWのエンドポイントを呼び出して、エラーが発生した場合、以下の対処方法をご参考ください。
問題-1「API GWに接続できない」
エラーメッセージ: curl: Failed to connect to <API_Gateway_Hostname> 443 after xxxxxx ms: Couldn't connect to server
API_Gateway_Hostnameの例:<OCID>.apigateway.<Region_ID>.oci.customer-oci.com
可能の原因:API GWがアタッチされているサブネットは、外部からのアクセスが許可されていない。
対策:サブネットに紐づいているセキュリティ・リストを編集し、アクセス元のIPアドレスと宛先ポート(TCP 443)を追加する。
問題-2「オブジェクト・ストレージにアクセスできない」
エラーメッセージ:{"Message": "Failed: Either the bucket named '<BucketName>' does not exist in the namespace '<tenancy_namespace>' or you are not authorized to access it"}
可能の原因:関連ポリシーが漏れた。
対策:次のようにポリシーを追加する。
allow dynamic-group Func-DG to manage objects in compartment PoC where {target.bucket.name='<BucketName>'}
問題-3「内部サーバーエラー」
エラーメッセージ:{"code":500,"message":"Internal Server Error"}
可能の原因:関連ポリシーが漏れた。
対策:API GWからファンクションを呼び出せるように、次のポリシーを追加する。
Allow dynamic-group <API-GW-DG> to use functions-family in compartment PoC
サマリ
今回のデモは、基本的に全部「Always Free Tier」でカバーできます。
- OCI Functionsの価格について、呼出回数と実行時間(GB-秒)により課金しますが、毎月無料枠(詳細はこちらへ)がありますので、このようなデモには全然余裕があります。
- Functionの作成は、無料の「Cloud Shell」を利用するのは推奨です。その理由は、Fn ProjectとDockerは既にインストール済で、環境設定の手間を省きます。
- VMを利用したい方は、「Always Free」のComputeシェープを指定していただければOKです。OCPUとメモリは比較的に低いけど、Functionの作成と呼出には問題ないです。
- オブジェクト・ストレージの無料利用枠は10GBです。今回のJSONファイルはMB単位で、心配がありません。
ご興味のある方は、ゼロコストで体験できますので、ぜひ試していただければと思います。
以上です。
関連記事
オラクル・クラウドの個人ブログ一覧
API GWでOCI Functionsの呼び出し
「OCI Functions」と「 AWS Lambda」の比較