Node-REDをGoogleComputeEngine(GCE)で動かす

# はじめに
Node-REDをGoogleComputeEngine(GCE)で動かす方法をまとめてみました。
こちらの記事はざっくりとした内容になっています。もし試してみたい方は[GitHub](https://github.com/NearMugi/node-redOnGCE_Sample)を参照ください。Node-REDを動かすまでの手順を詳しくまとめています。

# 背景  

GCEでNode-REDを動かす方法 は[Low code programming with Node-RED comes to GCP](https://cloud.google.com/blog/products/application-development/using-node-red-with-google-cloud)で紹介されている方法が一般的と思われます。ここに書いてある通り、VMインスタンスに"nodered/node-red"コンテナを指定すれば、GCEでNode-REDが動きます。(数ステップであっという間にNode-REDが動くので驚きます。)
しかし、VMインスタンスを再起動すると **フローが全て消えてしまいます**。
これではVMインスタンスを起動するたびにフローを手作業で追加するので非現実的です。
また「VMインスタンスを停止できない = 24時間稼働 = 費用がかかる」のも問題です。
  
そのためVMインスタンスを起動してもフローが消えない、かつ運用費を抑える方法を考えてみました。

# 今回の目標と結果  

* **VMインスタンスを再起動してもフローに影響しない仕組みを作りたい。**  
→独自のDockerイメージを用意することで解決しました。
* **Node-REDのフローをGCEへ簡単にデプロイできるようにしたい。**  
→ローカル環境で作成したフローをバッチファイルを使って簡単にデプロイできるようにしました。
* **運用費をなるべく抑えたい。**  
→5:00～24:00稼働にすると毎月8ドル程度で運用できます。(2020年7月現在)  
月1回ラーメン1杯、もしくはビール1杯を我慢すれば良いのです。まあ許容範囲内です。

# 調査 
まずGCEを知るところから始めます。
## GCEで動くNode-REDの環境

Node-REDは、VMインスタンスで動くDockerコンテナ内で動いています。
![flow_0.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237144/e4e12b59-efe9-fdfc-303f-14ecb73f4257.jpeg)
VMインスタンスのOSは[Container-Optimized OS](https://cloud.google.com/container-optimized-os/docs?hl=ja)で、Dockerコンテナを実行するためのOSが用意されてます。(このOSが厄介で、pipがインストールされていなかったり、Node-REDとフォルダをマウントさせるのが大変だったり…)
またDocker内にフォルダが存在するのでexecノードが使えます。今までGoogleCloudFunctionsで動かしていたプログラムを、GCEでNode-REDと簡単に組み合わせて動かせるのはかなりのメリットだと思います。

GCE+Dockerコンテナについては[GoogleCloudの公式ページ"VM と MIG へのコンテナ"](https://cloud.google.com/compute/docs/containers/deploying-containers?hl=ja#advantages)に詳しく書いてあります。

## GCPでDockerイメージを扱うには？  
独自に用意したDockerイメージは[Container Registry](https://cloud.google.com/container-registry?hl=ja)にアップロードします。
さらにDockerイメージをデプロイしてVMインスタンスを生成するには[Cloud Deployment Manager](https://cloud.google.com/deployment-manager?hl=ja)を使います。

## 費用を抑える方法は？  

[プリエンプティブル VM インスタンス](https://cloud.google.com/compute/docs/instances/preemptible?hl=ja)を利用すると **いつ停止するか分からないリスク** はありますが、費用を抑えられます。
また"起動時間＝課金"なので、24時間稼働にしないことも効果的です。

## 調査して分かったこと 

調査した結果、以下の点を解決すればよいと分かりました。 

* ローカル環境でNode-REDのフローを含んだDockerイメージを作成する
* GCPへDockerイメージをアップロードする
* DockeイメージをデプロイしてVMインスタンスを生成する
* VMインスタンスの起動・停止を管理する


# フロー作成からVMインスタンス生成までの手順

 **詳細は[GitHub](https://github.com/NearMugi/node-redOnGCE_Sample)にまとめています。**  


デプロイまでの流れは以下の通りです。
![flow_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237144/76b280f0-228e-d869-bbea-68e90f7fcc5e.jpeg)
1. Node-REDフローを用意する
2. Dockerイメージを作る
3. GCPのContainerRegistryへアップロードする
4. GCSにGCEで使用するファイルをアップロードする
5. GCPのDeploymentManagerを使ってGCEインスタンスを生成する
6. GCEインスタンスが起動する

2～6はバッチファイル実行で自動的に行われます。

# VMインスタンスの起動・停止の手順

 **こちらも[GitHub](https://github.com/NearMugi/node-redOnGCE_Sample)にまとめています。**  

[Cloud Scheduler + Cloud Pub/Sub + Cloud Functions でGCEのインスタンスの自動起動or停止させてみた](https://qiita.com/uu4k/items/4075acff6ef6a7ed9384) を参考にしました。  

* GoogleCloudFunctions(GCF)にGCEインスタンスの起動・停止を指示するプログラムを追加
* Cloud Schedulerでプログラムを定期的に実行

# まとめ  

GCE＋Node-REDの例がほとんどなく、かなり苦労しました。2か月以上運用して、特に問題なく稼動しているので上手く使えているのかなと思います。(GCPを使う人が増えるといいな)

何か参考になれば幸いです。ではでは。

# 参考URL  
[GoogleCloudの公式ページ"VM と MIG へのコンテナ"](https://cloud.google.com/compute/docs/containers/deploying-containers?hl=ja#advantages)
[プリエンプティブル VM インスタンス](https://cloud.google.com/compute/docs/instances/preemptible?hl=ja)
[Cloud Scheduler + Cloud Pub/Sub + Cloud Functions でGCEのインスタンスの自動起動or停止させてみた](https://qiita.com/uu4k/items/4075acff6ef6a7ed9384)