この記事はNode-RED Advent Calendar 2016の20日目になります
前日はtseigoさんのnode-red-contrib-usbhid がRaspberryPiでうまく入らないときの対処法でした
TL; DR
これとこれと各種ツールを利用して無停止でNodeをdeployするはなし
Motivation
PrivateなNodeを追加する際、Node-REDに極力ダウンタイムを発生させずに追加したい
さらに言うとNodeとNode-REDの管理を分けることによってより柔軟なNode管理を行いたい
もっと言うとAdvent Calendar駆動で色々お勉強しておきたい
Node-REDにNodeを追加する為にはどうしたらよいのか
公式より、以下3通りの方法で追加が可能
1.Node-RED画面上からエディタを利用する
2.npmからインストール & Node-REDインスタンスを再起動
3.nodes
ディレクトリ下にファイルを配置する
上述した理由(Node/Node-REDの管理を分ける、無停止追加)より
2.npmからインストール & Node-REDインスタンスを再起動
に各種ツールを組み合わせて実現することとした
前提環境
MacBook(Early 2015)
Node-RED: 0.15.2
Concourse: 2.5.0
PCF-dev: 0.21.0
sinopia: 0.13.0
Node-RED: PCF-dev上にdeploy(node-red.local.pcfdev.io)
Concourse: local上にdocker-compose up
PCF-dev: vagrant上のVM(192.168.11.XXX)
sinopia: vagrant上のVM(192.168.33.XXX)上のDocker(port:4873)
1.環境構築
1.1.PCF-dev(CloudFoundry)を起動する
以下を読むとだいたいできる
1.2.Concourseを起動する
以下を読むとだいたいできる
オススメはBOSH/BOSH-lite上の構築らしい、確かに管理は楽そう(TODO)
1.3.Private Node Registry(sinopia)を起動する
docker-sinopiaやdockerでsinopiaを試したメモを読んで起動する
docker run --name sinopia -d -p 4873:4873 keyvanfatehi/sinopia:latest
注)sinopia自身は更新が停止しているっぽい
npmへのアクセスをnpmコマンドでproxyしてくれるやつであれば何でも良い
2.Nodeの作成と登録
2.1.Nodeを作成する
公式のCreating Nodesを読みながらサンプルを作成する
今回はNodeの追加までを確認したかったので表示のみの簡素なNodeを作成した
<script type="text/javascript">
RED.nodes.registerType("Sample Node", {
category: "private",
color: "#FFFFFF",
defaults: {
name: { value: "aaa", required: true },
value: { value: "bbb", required: false },
},
inputs: 1,
outputs: 1,
icon: "",
label: function() {
return this.name || "SampleNode"
}
});
</script>
<script type="text/x-red" data-template-name="sampleNode">
<div class="form-row">
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
</div>
<div class="form-row">
<label for="node-input-value"><i class="icon-tag"></i> Value</label>
<input type="text" id="node-input-value" placeholder="Value">
</div>
</script>
<script type="text/x-red" data-help-name="sampleNode">
<p>A node that is only examine between private repository and Node-RED instance</p>
</script>
2.2.作成したRegistryへNodeをPublishする
npmの接続先を作成したPrivate Registryへ切り替える
npm set registry http://192.168.33.10:4873
publish用ユーザを作成する
npm adduser
作成したNode directory上でpublish!
npm publish
Nodeが追加された
3.Private Node管理用ファイルの作成
3.1.Private Node追加用のファイルを作成する
Node-REDへPrivate Nodeを追加する際に必要なファイルは以下
-
package.json
... Node-REDのものを利用する -
.npmrc
... npmの接続先をprivateへ切り替える為に必要
それぞれ以下のように編集/追加する
{
"name" : "node-red",
"version" : "0.15.2",
...
"dependencies": {
"basic-auth": "1.0.4",
...
"node-red-node-rbe":"0.1.*",
"sample-node": "0.0.1" ## 追加するNode
},
...
}
registry=http://192.168.33.10:4873/
3.2.CloudFoundryへのdeploy用manifest.ymlを作成する
詳しくはここ
今回は必要最小限の記載とした
---
applications:
- name: node-red
memory: 128M
disk_quota: 128M
3.3.Concourse用のpipelineやtaskを作成する
Concourse自身の説明については以下を参照
今回NodeとNode-REDの管理を分離する為、以下のようなpipelineとした
[Node-REDのrelease code(from github)]
|
| <-(overwrite)- [3.1, 3.2のgithub repo]
|
∨
[CloudFoundry] ## ここでnpm installされる
上記より、(Nodeがpublish済みであれば)上書き元のpackage.jsonを修正するだけで必要な構成のNode-REDインスタンスが用意できるようになる
今回はNode-REDの記事なのでConcourse用のpipeline.ymlやtask.yml, scriptの説明は割愛する
4.動かしてみる
Githubにconfigリポジトリを作成する
login, pipelineの登録, pipelineのunpauseを実行
fly -t cci login
fly -t cci sp -p node-red-deploy -c pipeline.yml
fly -t cci up -p node-red-deploy
こんな感じのpipelineが登録される
cloudfoundryへのdeploy時に作成したPrivate Nodeがinstallされていることが確認できる
deployされたNode-REDインスタンスに作成したPrivate Nodeが追加されている事が確認できた
無停止は?
今回途中で説明を省略したが、Concourseが用意しているCloudFoundryへのdeploy用resourceはautopilotプラグインが組み込まれている
その為、以下のようにpipelineを定義すれば、同名のappについては自動的にrenameやroute設定(無停止による切り替え)が実施される
- put: pcf-dev
params:
manifest: integrate-output/manifest.yml
path: integrate-output
current_app_name: node-red ## 差し替えたいapp
まとめ
Node-REDへPrivateなNodeを追加するときの実現方法について色々考えて実装/設定してみました
実運用下に持ち込む場合はまた別な部分(GitHub的な部分とか管理者の定義とか)が必要そうです
今回、CloudFoundryとしてPCF-devを用いてdeployを実施しましたが、Cloud Foundry Certified Providerであればどれも同様の定義でデプロイ可能です(たぶん)
動かなかったよ!という方がいらっしゃいましたらコメント/twitterまでご連絡下さい。