LoginSignup
5
3

More than 5 years have passed since last update.

Node-REDが動作するコンテナをビルドして Kubernetes で実行するまでを解説 (3/3)

Last updated at Posted at 2018-03-12

この記事は、Node-REDのコンテナをビルドして、Kubernetesの上で他のサービスと連携させるまでの道のり解説の最終回です。 前回までに作ったNode-REDのコンテナをKubernetesにデプロイして、Cloudant、MySQL、REST APIの動作について、進めていきます。

Node-REDのコンテナのビルド、DockerHubへの登録は、Node-RED v0.18が動作するコンテナをビルドして Kubernetes で実行するまでを解説 (1/3)に解説しました。

そして、Node-REDコンテナから、IBM Cloudのサービスや、同じコンテナの CloudantやMySQLサーバーとの連携は、第2回目 Node-REDが動作するコンテナをビルドして Kubernetes で実行するまでを解説 (2/3) で解説しました。

第3回目は、無料で利用できるIBM Cloud Container Service (Kubernetes)のライトプランでの利用方法です。

無料で利用できるKubernetesのデプロイ

IBM Cloud にログインして、Container Serviceをクリックして、Kubernetesのクラスタのオーダー画面を開きます。

無料で利用できるk8sクラスタのオーダー

Regionによっては、無料プランを利用できない場所もある様です。 この例では米国南部を選択して、クラスタ・タイプに無料を選択しました。

スクリーンショット 2018-03-12 0.14.50.png

Cluster name に名前をセットして、「クラスターの作成」をクリックして先へ進めます。 無料プランでは、ノードは1個に制限されています。また、ロードバランサーや永続ストレージも利用できないので、お試し用という位置づけです。 しかし、Node-REDの開発であれば十分利用できますので、無料プランで進めていきます。

デプロイ中画面

Kubernetesを利用できる様セットアップするには、ユーザー専用のマスタとノードを起動する必要があり、およそ20分〜30分くらい時間がかかります。 準備作業中は、プロビジョニング中と表示されていますので、待ちます。

スクリーンショット 2018-03-12 0.17.00.png

準備完了状態

準備が完了したら次の画面の様に、状態欄に「準備完了」と表示されます。

スクリーンショット 2018-03-12 7.43.41.png

kubectl コマンドのセットアップ

これで、Kubernetesを利用するクラウド側の準備が完了しました。 Kubernetesの利用には、コマンド・ライン・インタフェースが必須になりますので、以下2つのコマンドをインストールして、ログインします。

k8sの利用には必須のプラグインをインストールします。 このプラグインのサブコマンドで、k8sより下層部分の設定を行います。

bx plugin install container-service -r Bluemix

IBM Cloudにログインして、米国南部(us-south)のリージョンをセットします。

bx login -a https://api.ng.bluemix.net
bx cs region-set us-south

kubectlコマンドの認証情報をダウンロードするために、次のコマンドを実行します。 コマンドが正常終了すると、KUBECONFIG=から始まる環境変数の雛形を表示しますので、コピペして環境変数にセットします。

bx cs cluster-config mycluster1

上記の操作で、kubectlが利用できる様になりました。 IBM Cloud 上の k8sマスタと接続ができるか、確認してみます。 次のコマンドでノードのリストを表示できます。 ライトプランですから、1個しかありません。 IPアドレスは、旧SoftLayerで良く知られた、プライベート側IPアドレスで、ユーザー専用のネットワークになります。 このIPを公開しても、他のユーザーは、一般のルートから、このアドレスへ到達できません。

kubectl get node
NAME            STATUS    ROLES     AGE       VERSION
10.76.193.109   Ready     <none>    8h        v1.8.8-2+9d6e0610086578

Node-REDコンテナ を k8s上にデプロイ

ここまでの作業で、kubectlコマンドが利用できる様になりましたので、k8sへコンテナをデプロイするためのYAMLのファイルを作成して、適用していきます。

YAMLファイルの作成

次は、Node-REDのコンテナをデプロイするためのYAMLです。 image項目のフィールに、DockerHubに登録したコンテナのイメージを入れます。それ以外は、そのまま、利用します。

node-red-depoy.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: node-red
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: node-red
    spec:
      containers:
      - name: node-red
        image: maho/node-red:1.0
        ports:
        - containerPort: 1880

kubectl create -f ファイル名 でファイルを適用します。 これでNode-REDコンテナを動作させるポッドが1個起動します。

kubectl create -f node-red-depoy.yaml

起動の確認には、kubectl get deploy node-red を利用します。 AVAILABLEの値が1になれば、起動完了です。

$ kubectl get deploy node-red
NAME       DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
node-red   1         1         1            1           1h

ここまでの状態では、k8sのクラスタネットワーク上だけに、コンテナを内包するポッドが繋がった状態ですから、どこからもアクセスできません。そこで、次のYAMLファイルを利用して、ポッドをホストしているノードにアクセスポートを開きます。 nodePortの値で 31880 が外部に解放されるNode-REDのポート番号になります。

node-red-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
  name: node-red
spec:
  type: NodePort
  selector:
    app: node-red
  ports:
  - protocol: TCP
    port: 1880
    nodePort: 31880

次のコマンドで、YAMLファイルを適用して、NodePortサービスを開始します。

kubectl create -f node-red-nodeport.yaml

公開先IPアドレスの確認

NodePortは、コンテナをホストするノードのIPアドレスを利用して、ポートを開いて、アクセスを提供するというものです。 そこで、ノードのパブリックIPアドレスを調べます。 これには、プラグインとして追加した bx cs サブコマンドを利用していきます。 はじめに、k8sのクラスターの名前を取得します。

imac:k8s maho$ bx cs clusters
OK
Name         ID                                 State    Created        Workers   Location   Version   
mycluster1   890f1e136a2f4054854059fa70ea0fca   normal   10 hours ago   1         hou02      1.8.8_1507   

次に、クラスタ名を指定して、workersで、ノードのリストを表示します。 k8sのプロジェクトでは、コンテナをホストするサーバーを単なるノードと読んでいるのですが、IBM Cloudeでは、同じノードを Worker node という呼び方をしているので、混乱しない様に覚えていると良いでしょう。

Public IPの欄にあるIPアドレスが、外部のインターネットからアクセスできるIPアドレスになります。

imac:k8s maho$ bx cs workers mycluster1
OK
ID                                                 Public IP        Private IP      Machine Type   State    Status   Zone    Version   
kube-hou02-pa890f1e136a2f4054854059fa70ea0fca-w1   173.193.xxx.yyy   10.76.193.109   free           normal   Ready    hou02   1.8.8_1507   

k8s上のNode-REDコンテナへアクセス

ここまでで、ノードのIPアドレス、ポート番号が解りましたので、ブラウザからアクセスしてみます。 次の様なログイン画面が出てくれば成功です。
ユーザーIDとパスワードは、第一回目に記述していますので、参照願います。ログインして、先へ進めていきます。

スクリーンショット 2018-03-12 10.25.31.png

現在のところ、ユーザーIDやパスワードを変更するには、設定ファイルにユーザーIDとパスワードのハッシュが書き込まれているため、コンテナの再ビルドが必要になります。 プロジェクトで利用する場合などは、Node-REDコンテナの再ビルドを検討してください。

k8s上のCloudantなど他のサービスと連動

ここまでで、Node-REDのコンテナが、k8sで動作する事が確認できましたので、次は、Node-REDとサービスと連携させていきます。 具体的なイメージは、次の図の様になります、 前章で立ち上げたのが、図中真ん中付近の、Node-REDコンテナとNodePortサービスになります。次に、ここから、CoudantのコンテナとClusterIPサービスを起動して、連携させます。

スクリーンショット 2018-03-12 10.58.52.png

Cloudantコンテナのデプロイ

Cloudantのコンテナをk8sの上にデプロイして、他のデプロイメント(コンテナ)と連携できる様に、ClusterIPのサービスを起動します。

次のYAMLがCloudantのサーバーを起動するための定義です。 spec.containes.imageの値であるibmcom/cloudant-developer:2.0.1は、DockerHubに登録されているコンテナのイメージです。

cloudant-deploy.yml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: cloudant
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: cloudant
    spec:
      containers:
      - name: cloudant
        image: ibmcom/cloudant-developer:2.0.1
        ports:
        - containerPort: 80

Node-REDのコンテナと同様に、YAMLを提供して起動します。

$ kubectl create -f cloudant-deploy.yml 

次のコマンドで起動を書くにします。 前回同様にAVAILABLEが 1 になれば、起動完了です。

$ kubectl get deploy cloudant
NAME       DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
cloudant   1         1         1            1           1h

そして、Node-REDのコンテナからCloudantoをアクセスできる様にサービスを立ち上げます。 前回は外部に公開するものでしたが、今回は、spec.typeの値が ClusterIPとなっており、内部に公開するためのサービスです。

cloudant-service.yml
apiVersion: v1
kind: Service
metadata:
  name: cloudant
spec:
  type: ClusterIP
  selector:
    app: cloudant
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 80

次のコマンドでk8sクラスタに適用します。 この適用によって、k8s内で動作するDNSに登録され、CloudantのDNS名でアクセスできる様になりますので、Node-REDに設定する場合は、k8sのDNS名で登録します。

$ kubectl create -f cloudant-service.yml 

サービスの起動は、次のコマンドで確認できます。 元のコンテナが解放するポート番号は80番でしたが、サービスで8080番に変換して提供します。

$ kubectl get svc cloudant
NAME       TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
cloudant   ClusterIP   172.21.175.93   <none>        8080/TCP   28m

疎通確認

ここでNode-REDのコンテナ(ポッド)にログインして、curlコマンド、Cloudantへアクセスできるか確認してみます。 必須の作業ではありませんから、参考程度に見てください。 興味があれば、kubectl get nodesでCloudantのポッド名を調べて、ポッド名を置き換えて実行します。そして、curlコマンドで、http://cloudant:8080/ で Welcomeが帰ってくれば、疎通確認完了です。

$ kubectl exec -it node-red-64d45cfd95-nzx57 sh
/node-red # curl http://cloudant:8080/
{"couchdb":"Welcome","version":"2.0.0","vendor":{"name":"IBM Cloudant","version":"1.1.0","variant":"local"},"features":["geo"]}

Cloudantノードへの設定

k8sのNode-REDコンテナをアクセスして、フローエディタで、次の様にCloudantのノードを配置します。 TimestampノードとCloudantノードに空のFunctionノードを置く理由は、Cloudantにデータベースが作成されていない場合、自動的にFunctionがデータベースを作成してくれるためです。

Cloudantのノードをダブルクリックして、プロパティを設定していきます。 Serverの行の「えんぴつ」マークをクリックして、ホスト名などを設定します。 パスワードなどは、第2回目で記載していますので参照をお願いします。

スクリーンショット 2018-03-12 12.58.33.png

ここで、ホスト名は、http://cloudant:8080/ とします。CloudantがRESTサービスであるので、URLのインプットが想定されているためです。 cloudantは、先に起動したcludantのサービス名で、Node-REDのコンテナからkube-dnsを介して、アドレスが解決されます。

スクリーンショット 2018-03-12 12.58.46.png

Node-REDとCloudantの連携テスト

ここまでで、Node-REDコンテナとCloudantコンテナの連携の設定が完了したので、テストします。 次のフローは、Timestampノードをクリックして、デバック・ウィンドに、タイムスタンプの値が表示されると同時に、Cloudantへ登録されるものです。

スクリーンショット 2018-03-12 13.08.47.png

Cloudant 管理画面を見るための設定

上記の操作で、正しく、Cloudantへデータが登録されているか、Cloudantの管理コンソールにアクセスして確かめたいと思います。 インターネット越しにアクセスできる様するには、次のYAMLでNodePortの設定を加えます。 これによって、nodePortの値、31080で Cloudantの管理画面のポートが開きます。

cloudant-nodeport.yml
cloudant-nodeport.yml 
apiVersion: v1
kind: Service
metadata:
  name: cloudant-nodeport
spec:
  type: NodePort
  selector:
    app: cloudant
  ports:
  - protocol: TCP
    port: 80
    nodePort: 31080

次のコマンドで適用します。

$ kubectl create -f cloudant-nodeportyml 

設定の確認を実施ます。

$ kubectl get svc cloudant-nodeport
NAME                TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
cloudant-nodeport   NodePort   172.21.182.158   <none>        80:31080/TCP   38m

$ kubectl get node
NAME            STATUS    ROLES     AGE       VERSION
10.76.193.109   Ready     <none>    12h       v1.8.8-2+9d6e0610086578

$ bx cs workers mycluster1
OK
ID                                                 Public IP        Private IP      Machine Type   State    Status   Zone    Version   
kube-hou02-pa890f1e136a2f4054854059fa70ea0fca-w1   173.193.xx.yyy   10.76.193.109   free           normal   Ready    hou02   1.8.8_1507   

それでは、ブラウザでアクセスします。 上記のアドレス http://173.193.xx.yyy:31080/となり、認証情報は、第2目に記載した通り、username: admin, password: pass です。

次の様にデータベース testdb1が作成され、3個のデータが登録されている事が確認できます。

スクリーンショット 2018-03-12 13.09.02.png

最初の1個を開いて、登録されたデータとデバックウインドの表示値があっているか確認します。

スクリーンショット 2018-03-12 13.09.28.png

注意

無料枠内で利用できる事、解りやすさ、目的への到達の早さを考慮して、下記の点を省略していますので、ご注意をお願いします。

  • この例では、永続ストレージをマウントしていないので、ポッドが再起動されたり、削除されると、データを失います。
  • コンテナのパスワードは、プロジェクト等で利用する場合は、変更が必要です。

k8s上のMySQLのサービスと連動

次は、MySQLとの連携を確認していきます。 Cloudantの様に確認用のコンソールが無いので、コマンドラインが利用できるポッド(コンテナ)を起動してMySQLクライアントを実行して、設定や確認を進めていきます。

今回は、最初に Node-REDコンテナとMySQLコンテナの連携をフローエディタで描いてから、進めます。function-2には、データをテーブルにインサートするためのSQL文を書く必要があります。 ノードの設定内容は、詳しくは第2回目を参照してください。

スクリーンショット 2018-03-12 14.19.55.png

次は、MySQLサーバーのコンテナを起動するためのYAMLです。 DockerHubに登録された公式MySQLイメージを取得して、K8s上にデプロイします。このコンテナの詳しい説明は、DockerHub mysqlの説明を参照願います。 YAMLに環境変数を設定する事で、パスワード設定やcreate databaseを実行してくれる良くできたコンテナです。

mysql-deploy.yml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: mysql
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:5.7
        ports:
        - containerPort: 3306
        env:
        - name: MYSQL_DATABASE
          value: "testdb2"
        - name: MYSQL_ROOT_PASSWORD
          value: "password"

同じ要領で、デプロイの実行と、起動の確認をおこないます。

$ kubectl create -f mysql-deploy.yml


$ kubectl get deploy mysql
NAME      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
mysql     1         1         1            1           16m

これまで同様に、サービスを起動して、他のデプロイメント(コンテナ)からkube-dnsの名前解決でアクセスできる様にします。

mysql-service.yml
apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  type: ClusterIP
  selector:
    app: mysql
  ports:
  - protocol: TCP
    port: 3306

同様に適用と起動の確認をします。

$ kubectl create -f mysql-service.yml

$ kubectl get svc mysql
NAME      TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
mysql     ClusterIP   172.21.247.189   <none>        3306/TCP   17m

MySQLサーバーには、testdb2というデータベースが作成されていますが、データを格納するテーブルがありません。そこで、コマンドライン用のポッド(コンテナ)を起動して、テーブルを作成します。

$ kubectl run -it --image mysql my-client bash
If you don't see a command prompt, try pressing enter.

上記で Enter キーを押すと、以下の様にmy-clientコンテナの中に入り、mysqlコマンドで、mysqlコンテナのMySQLサーバーへログインして、テーブルを作ります。

root@my-client-65bbd59569-x4v8t:/# mysql -h mysql -u root -ppassword testdb2
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.21 MySQL Community Server (GPL)

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.


mysql> show tables;
Empty set (0.00 sec)


mysql> CREATE TABLE payload (id MEDIUMINT NOT NULL AUTO_INCREMENT, msg CHAR(30) NOT NULL, PRIMARY KEY (id) );
Query OK, 0 rows affected (0.00 sec)


mysql> show tables;
+-------------------+
| Tables_in_testdb2 |
+-------------------+
| payload           |
+-------------------+
1 row in set (0.00 sec)


mysql> desc payload;
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | mediumint(9) | NO   | PRI | NULL    | auto_increment |
| msg   | char(30)     | NO   |     | NULL    |                |
+-------+--------------+------+-----+---------+----------------+
2 rows in set (0.01 sec)

mysql> 

Node-REDの設定

次の図の様に、フリーエディタのMySQLノードをクリックして、MySQLのコンテナと接続するための設定を入力していきます。

スクリーンショット 2018-03-12 14.10.31.png

IPアドレスではなく、サービス名を設定します。 コンテナのIPアドレスは、再起動すると再割り当てされるため、一定しません。このためmysqlというDNS名で設定が必要になるのです。

スクリーンショット 2018-03-12 14.11.04.png

動作テスト

timestampノードをクリックして、タイムスタンプの値が、MySQLノードにセットされるか確認してみましょう。

スクリーンショット 2018-03-12 14.12.17.png

先にログインしたmysqlクライアントで、select文を実行すると、デバックウインドに表示されたデータと同じ値が登録されている事がわかります。

スクリーンショット 2018-03-12 14.12.46.png

これで、k8s上のNode-REDコンテナとMySQLコンテナの連携の解説は完了です。 dockerコマンドの代わりに、yamlを作成して適用する点、必ずサービスを起動する点など多少の差がありますが、コンテナを理解していれば、大きな違いが無い事が判ったと思います。

RESTサービスの雛形

最後にK8s上のNode-REDが提供するRESTサービスの設定方法とアクセス方法について、簡単に確認します。

次のフローは、RESTサービスで簡単な文字列を返すフローです。 このフローの作成は、第2回目の記事を参照願います。/recvをGETでアクセスすると、次のフローがコールバックされ、functionでセットされる文字列が返されます。

スクリーンショット 2018-03-12 14.24.42.png

k8sではNodePortで開いていますから、URLのディレクトリ部分を前述の/recvに変更する事で、次の結果を得る事がきます。

スクリーンショット 2018-03-12 14.36.44.png

まとめ

Node-REDは、コードを書かない人にも、プログラムが出来そうな気にさせる、凄く優れたツールだと思います。 そして、プログラミングの敷居を下げ、IoTなどの高速開発の道を開いた様に思います。 この優れたNode-REDをKubernetesのコンテナ上で動かして、他のコンテナと関連付けて、コンテナの再利用の効果によって、さらなる高い生産性を達成していく事ができる様に思います。 是非、試して体験して頂きと思います。

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3