appsodyを使ってクラウド上のK8sクラスタにNode-REDをデプロイする。

[appsodyがNode-REDに対応したので使ってみた](https://qiita.com/motuo/items/2c59fd0f4410e8a7d014)では、自分のMac上のK8sクラスタへのデプロイをappsodyを使って行いました。

```sh
appsody deploy
```

上記のコマンド一発でローカルクラスタへのデプロイには成功しましたが、こうなると当然ながらクラウド上のKubernetesサービスへのデプロイ方法も気になってきますよね！
というわけで、今回はIBM Cloud Kubernetes Service(IKS)へのデプロイ例をご紹介します！
**ただ、ppsodyで作成したプログラムは基本的にクラウドネイティブですので、EKSだろうがAKSだろうが、OpenShiftだろうが関係なくNode-REDが動作する環境を構築する事ができます！**

## 事前準備(IBM Cloud Kubernetesサービスを準備する)
カタログなどからKubernetes Serviceを作成しましょう！とりあえず、試す場合は無料クラスタがあります！(30日間で消えてしまいますが、、、)

<img width="925" alt="スクリーンショット 2020-02-26 13.58.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154110/c4003790-a84b-27cd-cfc5-4f4e9dd44e9b.png">

## Kubernetes Serviceにデプロイする
###IBM Cloud Kubernetes Serviceへの接続
#### ログイン
```sh
ibmcloud login -a cloud.ibm.com -r us-south -g Default
```

#### クラスターの kubeconfig ファイルをダウンロードします。
```sh
ibmcloud ks cluster config --cluster クラスタID
```
#### 環境変数をエクスポート
```sh
export KUBECONFIG=コンソールで出力されたyamlのPath
```

## 事前準備(コンテナのビルド)
### Dockerリポジトリを作成する
Dockerリポジトリが必要になります！
今回は`Docker Hub`を利用します。まずはここでパブリックリポジトリを作成します。
(今回は`node-red-demo`という名前のリポジトリを作成しています)

### appsodyで作成したモジュールをビルドする
`appsody`にはbuild機能が備わっています。自信のプロジェクトディレクトリ配下で下記のコマンドを叩きます。

```sh
appsody build -t アカウント/node-red-demo
```

このコマンドでDockerイメージが自動でビルドされます。
念のため確認しましょう。

```sh
$docker image ls
REPOSITORY                           TAG                 IMAGE ID            CREATED              SIZE
アカウント名/node-red-demo           latest              1784ae510508        About a minute ago   216MB
```
こうなっていればOKです。このままDockerリポジトリにPushしちゃいましょう！

```sh
$ docker push アカウント名/node-red-demo
```
Docker Hubのリポジトリがアップデートされていれば成功です！
<img width="527" alt="スクリーンショット 2020-02-26 13.53.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154110/4126291e-2a0e-8b85-3ff5-2d94b067e4da.png">

これでコンテナの事前準備は完了です。

### appsodyのデプロイ
#### appsody operatorのインストール
```sh
appsody operator install
```

インストールの確認

```sh
$ kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
appsody-operator-7ff45fd6cc-pc5fm   1/1     Running   0          57s
```

これはappsodyで作成したイメージをデプロイするために必要な物になります。
これを指定しないと、

```sh
the server could not find the requested resource (post appsodyapplications.appsody.dev)
```
というエラーが出てしまいます。

#### デプロイ用のyamlファイルを作成する
下記のコマンドです。

```sh
$ appsody deploy --generate-only -t DockerHubのアカウント名/node-red-demo
```

簡単にいうと、yamlファイルを作成するコマンドです。`-t`オプションをつけるとDockerHubのリポジトリ名を指定する事ができます。

このコマンドを実行すると`app-deploy.yaml`という名前のファイルが生成されます。
内容はこんな感じです。

```yaml
apiVersion: appsody.dev/v1beta1
kind: AppsodyApplication
metadata:
  annotations:
    image.opencontainers.org/created: "2020-02-26T18:14:52+09:00"
    stack.appsody.dev/authors: Nick O'Leary <nick.oleary@gmail.com>
    stack.appsody.dev/configured: docker.io/appsody/node-red:0.1
    stack.appsody.dev/created: "2020-02-11T16:25:51Z"
    stack.appsody.dev/description: Node-RED runtime for running flows
    stack.appsody.dev/licenses: Apache-2.0
    stack.appsody.dev/tag: docker.io/appsody/node-red:0.1.1
    stack.appsody.dev/title: Node-RED
  creationTimestamp: null
  labels:
    image.opencontainers.org/title: node-red-demo
    stack.appsody.dev/id: node-red
    stack.appsody.dev/version: 0.1.1
  name: node-red-demo
spec:
  applicationImage: DockerHubのアカウント名/node-red-demo
  createKnativeService: false
  expose: true
  livenessProbe:
    failureThreshold: 12
    httpGet:
      path: /live
      port: 3000
    initialDelaySeconds: 5
    periodSeconds: 2
  monitoring:
    labels:
      k8s-app: node-red-demo
  readinessProbe:
    failureThreshold: 12
    httpGet:
      path: /ready
      port: 3000
    initialDelaySeconds: 5
    periodSeconds: 2
    timeoutSeconds: 1
  service:
    annotations:
      prometheus.io/scrape: "true"
    port: 3000
    type: NodePort
  stack: node-red
  version: 1.0.0
status: {}
```

ここまでできたら、あとは`apply`できます！

```sh
$ kubectl apply -f app-deploy.yaml 
appsodyapplication.appsody.dev/node-red-demo created
```

あとは、KubernetesのグローバルIPを調べて、、、

```sh
$ kubectl describe node |grep ExternalIP
  ExternalIP:  X.X.X.X
```

使えるポートを調べて(この場合は31636)

```sh
$ kubectl get services
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes      ClusterIP   172.21.0.1      <none>        443/TCP          8d
node-red-demo   NodePort    172.21.22.155   <none>        3000:31636/TCP   2m14s
```

アクセスしてみましょう。(http://上記で調べたIP:port)でアクセス可能です！

## 実は１行でDockerHubへのPushからKubernetesへのデプロイまでできる。
説明のために、長々と書きましたが、実は以下のコマンド一発で、Kubernetesへのデプロイまで可能なんです！

```sh
appsody deploy -t DockerHubのアカウント名/node-red-demo --push
```

## Kubernetes基盤ならどこでも動きます。
上記でも書きましたが、**appsodyで作成したプログラムは基本的にクラウドネイティブですので、EKSだろうがAKSだろうが、OpenShiftだろうが関係なくNode-REDが動作する環境を構築する事ができます！**

うまく利用して、自分にとってベストな環境で構築してみましょう！