Node-RED starter とは
IBM Cloud とその前身の IBM Bluemix では Node-RED を簡単に稼働できる Node-RED のボイラープレートやスターターキットと呼ばれるワンクリックでサービスインスタンスとアプリを組み合わせて環境を払い出せる機能がありました。これらは 2023 年 2 月までに Node-RED starterは利用できなくなり、現在では簡単に利用できるスターターキットのような環境はありません。
Node-RED starter はもともと IBM により開発されたもので、2023年10月現在はメンテナンスされていないことを明記した上で github 上のレポジトリ https://github.com/IBM/node-red-app にて公開されています。
IBM Cloud Code Engine とは
マルチテナントのコンテナ環境のマネージドサービスで、コンテナイメージの稼働のほか、アプリケーションのコードをビルドして稼働させたり、Function-as-a-service としてコードだけを稼働させることもできます。
Cloud Foudry Public サービスはグローバル IP アドレスをもつ、パブリック・エンドポイントしか利用できませんでしたが、IBM Cloud 上で稼働するシステムのバックエンドとして稼働するような利用形態で、プライベート・エンドポイントが利用できるようになったのも嬉しいポイントです。東京、大阪を含むマルチゾーンリージョンで利用することができます。これも Cloud Foundry Public と比べると強化されたうれしいポイントです。
利用者はアベイラビリティーゾーンを意識する必要は有りませんが、3つのアベイラビリティーゾーンにサービスの構成要素が分散配置されており、可用性が高いサービスの提供を可能としています。
さらに、IBM Cloud 上でコンテナを稼働できるサービスでは唯一ゼロスケールできることも特徴です。利用しない時間にはインスタンスを停止して使用量を小さく抑えることができます。また、毎月適用される無償枠があり、一定の範囲内であれば無料で利用できるのも魅力です。
一方で https プロトコルでのみアクセス可能で、http プロトコルでアクセスしようとすると https プロトコルを使用するように自動的に転送されます。また、永続的なストレージは Code Engine サービス自体にはないので、別のサービスを利用する必要があります。
旧 Node-RED Starter を IBM Cloud Code Engine で稼働させるための準備
ここからは Node-RED を IBM Cloud Code Engine 上で稼働させてみて、うまく動かすために調整する必要がある部分を整理していきます。
今回は Node-RED starter を稼働させるサービスをなるべく無料もしくはとても安価で利用できるサービスで構成したいと思います。IBM Cloudではセキュリティ対策など様々な理由で無償で利用できるアカウントを制限し、利用できるプランも減らしてきました。しかし有償サービスを使えるアカウントには無償枠も用意されているので、それらを最大限活用していきます。
旧 Node-RED starter の 新旧稼働環境
従来の Node-RED Starter は Cloud Foundry Public上で稼働し、ノードやフローの情報をCloudant NoSQL Database 上に保管するように構成されていました。Cloud Foundry PublicのほかにIBM Cloud Kubernetes ServiceやRed Hat OpenShift on IBM Cloudサービスで稼働されていた方もいらっしゃるかもしれませんが、最も代表的だった SDK for Node.js での稼働で表現した下図のとおりです。
図. Node-RED starter のトポロジー (Cloud Foundry Public上で稼働の場合)
今回利用する Code Engine サービスではいくつかのアプリケーションのビルド方法が利用できますが、コンテナイメージのビルドを行う機能を利用して環境を構築していきます。下図のとおりです。Cloud Foundry Public のような Buildpack を利用する方法は Code Engine でも利用できるので、そちらを使う方法もあるかもしれません。
Code Engineには
図、 Node-RED starter のトポロジー (Code Engine上で稼働の場合)
Node-RED starter のコードに足りない部分
Node-RED starter https://github.com/IBM/node-red-app 自体のコードには一部足りない部分があります。具体的に環境変数を Code Engineサービスを利用するために変換するテーブルを追加する必要があり、以下のレポジトリで足りないコードを mapping.json ファイルとして追加して公開されている方がいらっしゃり、コードは https://github.com/tomdev10/node-red-app で公開されています。
今回はこちらを更に fork したものを利用します。一部コードを変更した部分があり、私のレポジトリに公開しています。https://github.com/masaffff/node-red-app 以下は変更した後の mapping.json です。
マッピングファイル
{
"application_name": {
"searchPatterns": ["cloudfoundry:$.application_name", "env:K_SERVICE"]
},
"cloudant_apikey": {
"searchPatterns": [
"env:CLOUDANT_APIKEY",
"env:service_cloudant:$.apikey",
"file:/server/localdev-config.json:$.cloudant_apikey"
]
},
"cloudant_host": {
"searchPatterns": [
"env:CLOUDANT_HOST",
"env:service_cloudant:$.host",
"file:/server/localdev-config.json:$.cloudant_host"
]
},
"cloudant_iam_apikey_description": {
"searchPatterns": [
"env:CLOUDANT_IAM_APIKEY_DESCRIPTION",
"env:service_cloudant:$.iam_apikey_description",
"file:/server/localdev-config.json:$.cloudant_iam_apikey_description"
]
},
"cloudant_iam_apikey_name": {
"searchPatterns": [
"env:CLOUDANT_IAM_APIKEY_NAME",
"env:service_cloudant:$.iam_apikey_name",
"file:/server/localdev-config.json:$.cloudant_iam_apikey_name"
]
},
"cloudant_iam_role_crn": {
"searchPatterns": [
"env:CLOUDANT_IAM_ROLE_CRN",
"env:service_cloudant:$.iam_role_crn",
"file:/server/localdev-config.json:$.cloudant_iam_role_crn"
]
},
"cloudant_iam_serviceid_crn": {
"searchPatterns": [
"env:CLOUDANT_IAM_SERVICEID_CRN",
"env:service_cloudant:$.iam_serviceid_crn",
"file:/server/localdev-config.json:$.cloudant_iam_serviceid_crn"
]
},
"cloudant_password": {
"searchPatterns": [
"env:CLOUDANT_PASSWORD",
"env:service_cloudant:$.password",
"file:/server/localdev-config.json:$.cloudant_password"
]
},
"cloudant_port": {
"searchPatterns": [
"env:CLOUDANT_PORT",
"env:service_cloudant:$.port",
"file:/server/localdev-config.json:$.cloudant_port"
]
},
"cloudant_url": {
"searchPatterns": [
"env:CLOUDANT_URL",
"env:service_cloudant:$.url",
"file:/server/localdev-config.json:$.cloudant_url"
]
},
"cloudant_username": {
"searchPatterns": [
"env:CLOUDANT_USERNAME",
"env:service_cloudant:$.username",
"file:/server/localdev-config.json:$.cloudant_username"
]
},
"cloudant_serviceInfo": {
"searchPatterns": [
"env:service_cloudant:$.serviceInfo",
"file:/server/localdev-config.json:$.cloudant_serviceInfo"
]
}
}
IBM Cloudのリソースを作る
ここからは Node-RED starter を稼働させるために必要なIBM Cloudの設定ならびにリソース作成を進めます。いままで説明した Code Engineを中心とする新しい環境を作っていきます。
1. IBM Cloudのコンソール https://cloud.ibm.com にログインします。 以降の作業を進めるためには有償サービスを利用できるアカウントが必要です。クレジットカードの登録、サブスクリプションの購入が必要です。ただし、今回利用するすべてのサービスは無償プランもしくは無償枠があるので、利用する数量や時間によっては無料枠内で利用できます。
2. 利用するリソースグループを決定し、必要があれば作成します。。 この記事では noderedstarter
を使用します。以降で作成するリソースではこのリソースグループを指定します。作成する場合は https://cloud.ibm.com/account/resource-groups にて作成します。
3. 利用するリージョンを決定します。この記事では 東京リージョン
を使用します。
4. Cloudant サービスのインスタンスを決定します。この記事ではインスタンス名 Cloudnat-noderedstarter
とします。作成する場合には https://cloud.ibm.com/catalog/services/cloudant にアクセスし、”Select an environment”を Multitenant
、"Instance Name"を Cloudant-noderedstarter
、 "Resource group" を noderedstarter
とします。そしてここがとても大事なのですが、"Authentication method"を IAM and legacy credentials
と設定します。最後に"Plan"を Lite
として 「Create」ボタンをクリックします。
5. Container Registry サービスで利用する namespace を決定します。この記事では nsnoderedstarter
を使用します。 作成する場合には https://cloud.ibm.com/registry/namespaces にアクセスし、ロケーションとして 東京
を選択した後に作成します。下図のようにリソース・グループとして noderedstarter
を指定し、名前に nsnoderedstarter
を指定し、「作成」ボタンをクリックします。
6. Code Engine プロジェクトで利用するプロジェクトの名称を決定します。この記事では cenoderedstarter
を使用します。
作成する場合にはhttps://cloud.ibm.com/codeengine/projects にて作成します。表の右上にある「作成」ボタンをクリックします。下図のようにロケーションとして 東京
、名前として nsnoderedstarter
、リソース・グループとして noderedstarter
をそれぞれ指定し、右下の「作成」ボタンをクリックします。
7. Code Engine でビルドしたコンテナイメージを Container Registry に格納するための サービスID と、それに対応する API Keyを作成します。
Code Engineのプロジェクト一覧 https://cloud.ibm.com/codeengine/projects から cenoderedstarter
の名称をクリックします。
プロジェクトに関する情報が表示される画面が表示されます。左下「プロジェクト設定」の部分が閉じているので、一度クリックすると、下図のように「統合」メニューが表示されます。赤い矢印が指す「統合」をクリックすると、右側に統合の設定状況が表示されます。青い矢印が指す「東京」をクリックします。
以下のような画面が表示されるので、「構成」をクリックします。
先程は未構成だった「東京」の行が 構成済み
となりました。
ここまででリソースの作成と設定は一旦終了します。この後も必要な設定がいくつかありますが、アプリケーションを稼働させる中で合わせて実施していきます。
Node-RED starter を Code Engine 上で稼働する
Code Engine アプリケーションを作成し、Node-RED starter のコードからビルドする
Code Engine 上で Node-RED starter を稼働させるための作業に入っていきます。Code Engineの cenoderedstarter
プロジェクトの画面で左メニューにある「アプリケーション」を選択し、「作成」ボタンをクリックします。
アプリケーションを設定していきます。まず名前は application-node-red-starter
とします。実行するコードの選択は ソース・コード
、ソースコードURLは https://github.com/masaffff/node-red-app
、リスニングポートは 3000
、CPUおよびリソースはリストの一番上 0.125個のvCPU / 0.25GB
とします。またその下にある インスタンスの最小数が 0
となっていることも確認します。
少し上に戻って 「ビルド詳細の指定」 をクリックします。
CPUとメモリの指定は最小のものを指定しましたが、Node-RED上で少数のノードを稼働させる範囲ではこのスペックで問題ありませんでした。ノードを稼働させてリソースが足りないエラーなどが発生するようでしたらこのスペックを増やしたリビジョン(別の構成)を作り稼働させます。
以下のような画面が表示されます。左から順番に表示されるので、それぞれ入力を進めていきます。変更する部分のみを記述します。左の画面では ブランチ名 を master
として、「次へ」をクリックします。(Watson APIsのノードを使いたい場合には最新版の3.xではノードが稼働しないことがあるので master
の代わりに oldernodered
とすることで、Node-REDの一つ前のメジャー版である2.xを利用した環境を利用できます。) 真ん中の画面はそのまま「次へ」をクリックします。最後の画面では 名前空間として Container Registry の namespace 名であるnsnoderedstarter
を設定します。「リポジトリー(イメージ名)」は機械的に名称が振られるので、そのままにします。タグに適当な値 この記事では 0.1
として「完了」をクリックします。
最後に以下のような画面が表示されるので「作成」をクリックします。
ビルドの結果とゼロスケールされることの確認
しばらくするとビルドが実行され、この状態のアプリが稼働します。画面上に「インスタンス 01」と表示されインスタンスが1つ稼働していることがわかります。まだアプリを実際に起動させる必要はないので、しばらくこのまま待機します。(時間がない!という方は待機せず進めていただいても結構です)
しばらくすると、画面上に「インスタンス 00」と表示されインスタンスがゼロスケールしたことがわかります。
Code Engine アプリケーションと Cloudant サービス・インスタンスのサービス・バインディング
Code Engine アプリケーションと Cloudant をバインドさせます。バインドを行うことでサービスインスタンスを構成するパラメータ値に環境情報を通じてアクセスできるようになります。
「サービス・バインディング」タブを選択し、「作成」をクリックします。
サービス・バインディングの追加画面では以下のように指定します。IBM Cloudサービス・インスタンスに Cloudant-noderedstarter
、カスタム接頭部にCLOUDANT
。「追加」ボタンをクリックします。
稼働確認
アプリケーションのページで「概要」タブをクリックすると新しいリビジョンが準備されて稼働していることがわかります。右上にある「アプリケーションのテスト」をクリックします。
さらに 「アプリケーションのURL」をクリックします。
しばらくすると、すごく見慣れた初期画面が表示されます。このときWebブラウザーのアドレスに表示されているURLがCode EngineでPublicに公開されるときに使われるFQDNのホスト名です。<アプリ名>.<ランダムな文字列>.<リージョン>.codeengine.appdomain.cloud
というフォーマットが採用されています。
ここからウィザードに従って構成します。パスワードはきちんと設定しましょう。
構成が終わると以下の画面が表示されるので「Go to your Node-RED flow editor」をクリックして、認証情報を入力すると、、、
おぉ、Node-REDの画面が表示されました。
フロー情報が Cloudant に確認されていることの確認
ここからは自由に使っていただいて結構なのですが、念のため、フローの情報などが保存されていることを確認しましょう。別のブラウザーからログインしたり、10分ほど何もせずに放置した後にゼロスケールさせた後にログインするなど確認する方法はありますが、今回は直接DBを見にいってみます。
新しいフロー「フロー2」を作成し、Node-RED のチュートリアル https://nodered.org/docs/tutorials/first-flow にある簡単なフローを作成しました。忘れずにデプロイして、稼働させてください。
IBM Cloudのリソースリスト https://cloud.ibm.com/resources からCloudant-noderedstarter
を探してクリックします。
画面右上の「Launch Dashboard」をクリックします。
Cloudantのダッシュボードに「applicationnoderedstarter」というデータベースのエントリーが表示されます。ここにフローを含む構成情報が含まれていそうです。「applicationnoderedstarter」> 「nodered/flow」と選択します。
作成した「フロー2」の情報も文書内に含まれていますね。作成したノードとフローの情報が期待通りDBに書き込まれていることが確認できました。
DBに格納されていたフローの情報
{
"_id": "nodered/flow",
"_rev": "2-e03fe2a754c70bb0205e47140af36881",
"flow": [
{
"id": "e53f607bcec72602",
"type": "tab",
"label": "フロー 1",
"disabled": false,
"info": "",
"env": []
},
{
"id": "228d2522a042b5f4",
"type": "tab",
"label": "フロー 2",
"disabled": false,
"info": "",
"env": []
},
{
"id": "b1b11140.4e4ef",
"type": "inject",
"z": "e53f607bcec72602",
"name": "",
"repeat": "",
"crontab": "",
"once": false,
"topic": "",
"payload": "Hello Node-RED!",
"payloadType": "string",
"x": 141,
"y": 61,
"wires": [
[
"f2f2649a.0d0d98"
]
]
},
{
"id": "f2f2649a.0d0d98",
"type": "debug",
"z": "e53f607bcec72602",
"name": "",
"active": true,
"console": "false",
"complete": "false",
"x": 401,
"y": 87,
"wires": []
},
{
"id": "37b0566c152912ce",
"type": "inject",
"z": "228d2522a042b5f4",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 180,
"y": 80,
"wires": [
[
"07d7c27ac723fdf1"
]
]
},
{
"id": "07d7c27ac723fdf1",
"type": "function",
"z": "228d2522a042b5f4",
"name": "function 1",
"func": "// Create a Date object from the payload\nvar date = new Date(msg.payload);\n// Change the payload to be a formatted Date string\nmsg.payload = date.toString();\n// Return the message so it can be sent on\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 360,
"y": 160,
"wires": [
[
"0734b5aaa95ee8ff"
]
]
},
{
"id": "0734b5aaa95ee8ff",
"type": "debug",
"z": "228d2522a042b5f4",
"name": "debug 1",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 460,
"y": 260,
"wires": []
}
]
}
Watson APIsのノードを追加してみた (最新版のNode-REDと組み合わせた場合エラーあり!!)
Node-RED starterと最も組み合わせて使われていたサービスはWatson APIsかと思います。Node-RED starterの環境のパレットを追加してみます。
Watson APIs用のノードは2023年10月のこの記事の執筆時には2022年2月が最終更新となっています。
Node-RED flow editorにログインします。
画面右上にある三本線のメニューを表示し「パレットの管理」を選択します。
赤い矢印が指す「ノードを追加」をクリックします。
注意喚起のダイアログが表示されるので、「追加」をクリックします。
しばらくするとエラーになりました。npmのログにはWARNINGが出力されています。deprecatedとかno supportedとあるので、使用しようとしているライブラリが古いのでしょうね。
気を取り直して、もう一度ノードを追加してみると、今度はうまく追加されました。
なぜ追加されるのかは不明ですが、初回は必ず失敗、2回目以降は成功する確率が高くなります(5回試行して2回目でインストールできたのが3回、3回目でインストールできたのが2回でした)。
このあとノードを削除してしまうと再インストールはできませんでした。CLIを用いてインスタンスの再起動すると再インストールは2回目以降のインストールで成功しました。
余談ですが、稼働させる上で試行錯誤している中で、Red Hat Enterprise Linuxのコンテナのベースイメージをバージョン8.8のものとすると一度もうまく導入できませんでした。今回使用したレポジトリではRed Hat Enterprise Linux バージョン8.7ベースの最新版のUBIイメージを採用しました。こちらも導入できないことが多いのですが、数回試行すると1回導入できることがあるのです。バージョンの違いがどう寄与しているのかわかりませんが、とりあえず少しでも動く方で。
(2023/11 追記) さらに調査を進めたところ、Node-REDの最新版(3.x)と Watson APIs のノードの組み合わせだと問題が発生し、一つ前の Node-RED のバージョン(2.x)と Watson APIs のノードを組み合わせると問題が発生しないことがわかりました。問題が発生しないバージョンの Node-RED を導入するために github 上のレポジトリにブランチ oldernodered
に一式用意したので、必要に応じてそちらを利用ください。上述の手順にも反映してあります。
この後、watson-assistant-v2ノードを使ってみましたが、特に問題なく動作しました。
ただしゼロスケールさせた後にフローエディターを起動すると unknown node となりました。これはブラウザーのページを再読み込みさせたところ node を認識しました。なんらかの timeout が発生しているようにみえる挙動でした。有効な回避策はいまのところ見つかっていません。
これらをまとめると Watson のノードは少し古いもので、現行の Node-RED ではかろうじて動くといった所管です。ご利用されているサービスについては稼働を確認した後に利用するのと、ゼロスケールは行わない運用にしたほうがよいのかもしれません。
利用料金の試算
常時稼働とした場合、Code Engine では 0.125 vCPU/0.25 GB メモリの構成としましたが、月額でおよそ12ドルの利用料金になります。その倍の 0.25vCPU/0.5 GB メモリの構成の場合、月額でおよそ25ドルの利用料金となります。実際には無償枠があるので、これより3ドル程度安くなります。
最低インスタンスをゼロとする「ゼロスケール」とした場合には、利用時間に応じた課金となります。1日のうち3時間の稼働とすると 0.125 vCPU/0.25 GB メモリの構成で月額約 1.5 ドル、0.25vCPU/0.5 GB メモリの構成で月額約 3 ドルとなります。これ以外に Code Engine を稼働していない場合、おおよそ無償枠内で収まる利用量になります。
他のサービスは無償枠内、無料プランの利用なので、無償枠内を使い切っていない場合には料金は発生しません。
まとめ
IBM Cloud Code Engine で 旧 Node-RED starter を稼働させてみました。いわゆるコードの開発は一切行わず、設定を工夫して動かしてみました。
一方で数年前と同じ環境を再現しようとすると、最後の Watson のノードあたりをはじめ、難しい点がいくつもあるよう思いました。
簡単に複数のロジックを組み合わせて API やアプリにできる Node-RED の使い勝手の良さを享受するにはメンテナンスが簡単に済む Code Engine のような環境との組み合わせがベストかなと思います(あくまで個人の意見です)。
参考文献
IBM Cloud Docs - Code Engine https://cloud.ibm.com/docs/codeengine
IBM Cloud Code Engine の料金 https://cloud.ibm.com/codeengine/overview ページ内の「料金」セクションにあります。
Node-RED tutorial - First Flow https://nodered.org/docs/tutorials/first-flow