【IBM Cloud】 IBM Open Labs上のKubernetesでアプリをデプロイしてみた

## はじめに
今回はIBM Open Labsを使ってKubernetesに触れるデモを行ったため、その流れをご紹介したいと思います。
そもそもそコンテナがどういったものかについての理解度が浅かった中、IBM Open Labs自ら手を動かしてみたら概念の理解がスムーズにでき、個人的な感想では非常に勉強になったと思います。
そのため、これからKubernetesを試してみたいと思われる方には是非使っていただきたく、ハンズオンの全般的な内容を初心者目線で整理してみました。今回の内容にはIBM Cloudの[アカウント](https://cloud.ibm.com/docs/account?topic=account-accounts)（無料利用可能）が前提となっています。
## デモの流れ
### IBM Open Labsとは？
IBM Open LabsとはIBMで提供しているデモ環境のラボです。予め環境を構築したり、プログラムなどをダウンロードする必要なく、ブラウザーだけで自らデモやハンズオンを行うことで学習できるデモンストレーションラボとなっています。
### IBM Open Labsの操作法
まずはIBM Open Labsの[URL](https://openlabs3-ui.mybluemix.net/openlabs/demo)にアクセスしましょう。
![スクリーンショット 2022-07-22 14.57.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/f0612f92-0105-98e3-e67e-130caf05af5a.png)
IBM Open Labsでデモを行えるコンテンツは何種類かありますが、プログラミングコンテンツはJava、Python、JavaScriptがあり、システムコンテンツはRedHat OpenShift、Docker（コンテナ）、Kubernetesがあります。今回はKubernetesでアプリのデプロイをしてみたので、System Admin101をクリックし、Kubernetes FundamentalをLaunchします。
![スクリーンショット 2022-07-22 14.58.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/3a769c76-328f-ddd2-8fa0-fe150524dff8.png)
冒頭でも記載していますが、IBM Open Labsを利用するにはIBM Cloudのアカウントが必要ですが、IBM Open Labsは全て無料でのデモが可能となりますので、もしお持ちでない方は`Register`での作成が可能です。私はすでに持っているアカウントでログインしました。
![スクリーンショット 2022-07-22 14.59.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/2e857aa0-567c-4cd9-35a8-4ca52c9bb92e.png)
ログインすると、LaunchしたKubernetes on IBM Cloudの画面が開きます。今回はContainers and Kubernetes Essentialsを実施しています。
![スクリーンショット 2022-07-22 15.00.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/cbd27324-77f1-dacd-4970-7c13c4ab8baa.png)
こちらがContainers and Kubernetes Essentialsの最初の画面です。右側にはブラウザー内で使用できるTerminalが配置されていて、左側にはハンズオンのガイド（Exercise）が整理されています。基本的な流れは左のガイドを順番に進めていけば問題ないです。
今回のハンズオンの目的としては、以下の内容を達成できることです。
- Kubernetesのコアコンセプトを理解する
- Dockerイメージをビルドし、IBM Cloud Kubernetes ServiceのKubernetesにアプリをデプロイする
- インフラストラクチャ管理の時間を最小限に抑えながら、アプリケーションの展開を制御する
- AIサービスを追加してアプリを拡張する
- クラスターとアプリを保護および監視する
![スクリーンショット 2022-07-22 15.00.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/74f6bbde-c1f6-7566-b6e6-8322df1d262c.png)
#### Exercise 1 : クラスターアクセスを構成する
IBM Cloudではプラットフォームやクラウド・サービスを使用するためのIBM Cloud CLIと呼ばれるCLIを提供しています。このラボでは主にIBM Cloud CLIを利用してハンズオンを実施します。通常自分のPC上のコンソールから利用する場合には[CLIのインストール](https://cloud.ibm.com/docs/cli?topic=cli-getting-started)が必要ですが、このラボではIBM Cloud CLIがインストール済みの環境が用意されており、画面右側のTerminalから操作することができます。

まずはIBM Cloudにログインするコマンドを入力します。
（今後の操作も同様ですが、IBM Open Labsでのコマンドは基本的にクリックするだけで入力されるため、コピーペーストは不要です）
```shell:IBM Cloud Login
ibmcloud login --sso -a cloud.ibm.com -r us-south --apikey b848c66b8fae12f32cfa9fba0f98ac83
```
問題なくログインができた場合には、以下のように表示されます。
また、最後にusage statisticsをIBMに送るか？（`Do you want to send usage statistics to IBM?`）の質問対して、今回はNo（`N`）を入力しています。
```
Authenticating...
OK

Targeted account Cloud Lab Tutorials (c098d833f9b04883942bcec5c7b6a37d) <-> 2030430

Targeted resource group (resource group name here)

Targeted region (region here)

                      
API endpoint:      https://cloud.ibm.com   
Region:            (region here)  
User:              (your IBM id here)   
Account:           Cloud Lab Tutorials (c098d833f9b04883942bcec5c7b6a37d) <-> 2030430   
Resource group:    No resource group targeted, use 'ibmcloud target -g RESOURCE_GROUP'
CF API endpoint:      
Org:                  
Space:

Do you want to send usage statistics to IBM? [y/n]> 
```
その次は以下のコマンドをクリックして、IKS（IBM Kubernetes Service）クラスターへのCLIアクセスをセットアップします。
```shell:Setup CLI to access IKS
ibmcloud ks cluster config --cluster cbbuormf0ppbs05e4qng
```
また、最新のDocker APIにはバージョンの違いによる問題が起こる可能性があるため、以下のコマンドもクリックしてみます。
```
export DOCKER_API_VERSION=1.40
```
#### Exercise 2 : アプリケーションをデプロイする
次はアプリケーションをデプロイしてみます。すでにビルドされ、DockerHubにアップロードされている`guestbook`というアプリケーションを`ibmcom/guestbook:v1.`という名前でデプロイします。
以下のコマンドをクリックして`guestbook`のデプロイメントを作成します。
```shell:creating a guestbook deployment 
kubectl create deployment guestbook --image=ibmcom/guestbook:v1
```
現在のアプリケーションステータスを確認したい場合には、以下のコマンドをクリックします。
```shell:check the status of the running application
kubectl get pods
```
もし、問題なくポッドが開始した場合には、以下のようにSTATUSがRunningになっています。（ポッドが作成されている途中であれば、ContainerCreatingが表示されます）
```
$ kubectl get pods
NAME                          READY     STATUS              RESTARTS   AGE
guestbook-59bd679fdc-bxdg7    1/1       Running             0          1m
```
STATUSがRunningになったら、そのデプロイメントをサービスとして公開し、アクセスできるようにする必要があるので、以下のコマンドをクリックします。（今回guestbookアプリケーションのポートは3000で設定されています。特定のポート番号が必要な場合は、`NodePort`フィールドに値を指定すると、システムがそのポートを割り当てます。指定する値は、ノードポートの設定範囲内にある必要があります。）
```shell:expose that deployment as a service
kubectl expose deployment guestbook --type="NodePort" --port=3000
```
`Service`として公開されたとの出力が出ます。
```
service "guestbook" exposed
```
これにより、Kubernetesに新しいリソースが作成されました。

その次はワーカーノードで使用されているポートを見つけるため、以下のコマンドをクリックして新しいポートを調べます。
```
kubectl get service guestbook
```
出力としては以下の結果が出ます。PORT(S)を確認すると、内部ポート3000が外部ポート30000台の範囲で設定されたことがわかります。これは30000台で自動的に設定されるため、ユーザーによって異なります。こちらのポートは別途メモをとっておきます。
*特定のポート番号が必要な場合は、`NodePort`フィールドに値を指定すると、システムがそのポートを割り当てます。指定する値は、ノードポートの設定範囲内にある必要があります。

ここまで完了すると、`guestbook`がクラスター上で実行され、インターネットに公開されている状態になります。そのアクセス方法を把握する必要があります。そのため、以下のコマンドをクリックし、外部IPアドレスを取得します。
```
ibmcloud ks workers --cluster dte-iks-lab-x72vsp
```
以下のような出力が表示されますが、こちらもアクセスするノードによって番号が異なります。
（*記事作成中に新たに学んだ内容ですが、外部ポートのようにユーザーによってポート番号が異なるのではなく、アクセスするノードごとに異なるとの概念は注意が必要かと思います。）
```
$ ibmcloud ks workers --cluster kube-cluster
OK
ID                                                 Public IP        Private IP     Machine Type   State    Status   Zone    Version  
kube-hou02-pa1e3ee39f549640aebea69a444f51fe55-w1   xxx.xxx.xx.xxx   10.76.194.30   free           normal   Ready    hou02   1.5.6_1500*
```
同様に、`<Public IP>`を確認し、別途メモをとっておきましょう。
現在公開されている`guestbook`は、`<public-IP>`:`<Nodeport>`で確認することができます。メモをとったポート番号とIPアドレスを組み合わせてページを確認してみたら、無事公開されていることが確認できました。
![スクリーンショット 2022-07-22 16.41.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/6430fb96-af38-b439-81e5-aaccb5e7fb18.png)

#### Exercise 3 : インスタンスのスケーリング、更新、ロールバッグを行う
次はデプロイされたインスタンスの数を増すスケーリングを行います。インスタンスのスケーリングは`replica`で行いますが、`replica`はポッドのコピーを意味します。ポッドの`replica`を複数持つことで、アプリケーションの負荷の増加を処理するために使用可能なリソースをデプロイメントに確保できます。

まず、既存のデプロイメントのサイズを変更するコマンドをクリックします。最大10個のインスタンスまでスケーリングが可能です。
```shell:increase instances
kubectl scale --replicas=10 deployment guestbook
```
現在のステータスを確認するには以下のコマンドをクリックします。
```shell:check the running status
kubectl rollout status deployment guestbook
```
以下のメッセージが出力されたら、ロールアウトの完了です。
（通常ロールアウトは非常に迅速な速度で行われるため、以下のメッセージが表示されない場合もありますが、最後の`deployment "guestbook" successfully rolled out`が表示されたら大丈夫です）
```
$ kubectl rollout status deployment guestbook
Waiting for rollout to finish: 1 of 10 updated replicas are available...
Waiting for rollout to finish: 2 of 10 updated replicas are available...
Waiting for rollout to finish: 3 of 10 updated replicas are available...
Waiting for rollout to finish: 4 of 10 updated replicas are available...
Waiting for rollout to finish: 5 of 10 updated replicas are available...
Waiting for rollout to finish: 6 of 10 updated replicas are available...
Waiting for rollout to finish: 7 of 10 updated replicas are available...
Waiting for rollout to finish: 8 of 10 updated replicas are available...
Waiting for rollout to finish: 9 of 10 updated replicas are available...
deployment "guestbook" successfully rolled out
```
ロールアウトが完了したら、以下のコマンドをクリックして10個のポッドが実行されていることを確認します。
```shell:check the pods
kubectl get pods
```
出力として、合計10個のインスタンスに増えたことが確認できます。右側の`AGE`はインスタンスを作成して経過した時間を表示しており、最初に作成したインスタンスのみコピーしたインスタンスとの時間が異なることが確認できます。
```
$ kubectl get pods
NAME                        READY     STATUS    RESTARTS   AGE
guestbook-562211614-1tqm7   1/1       Running   0          1d
guestbook-562211614-1zqn4   1/1       Running   0          2m
guestbook-562211614-5htdz   1/1       Running   0          2m
guestbook-562211614-6h04h   1/1       Running   0          2m
guestbook-562211614-ds9hb   1/1       Running   0          2m
guestbook-562211614-nb5qp   1/1       Running   0          2m
guestbook-562211614-vtfp2   1/1       Running   0          2m
guestbook-562211614-vz5qw   1/1       Running   0          2m
guestbook-562211614-zksw3   1/1       Running   0          2m
guestbook-562211614-zsp0j   1/1       Running   0          2m
```
Kubernetesを使用すると、アプリケーションを新しいコンテナイメージにローリングアップグレードできます。これにより、実行中のイメージを簡単に更新でき、展開中または展開後に問題が発見された場合にロールアウトを簡単に元に戻すことができます。その作業を進めていきます。
（今回行うローリングアップグレードでは、前回guestbookの`v1`と異なって`v2`を使用します。）

以下のコマンドをクリックして、既存のリソースに関する詳細を変更（v1→v2）できます。
```shell:change resource detail
kubectl set image deployment/guestbook guestbook=ibmcom/guestbook:v2
```
次は以下のコマンドをクリックし、ロールアウトのステータスを確認します。
```shell:check the rollout
kubectl rollout status deployment/guestbook
```
出力としては以下のようになります。
（こちらのプロセスも非常に迅速に行われるため、次のメッセージが表示されない場合があります。）
```
$ kubectl rollout status deployment/guestbook
Waiting for rollout to finish: 2 out of 10 new replicas have been updated...
Waiting for rollout to finish: 3 out of 10 new replicas have been updated...
Waiting for rollout to finish: 3 out of 10 new replicas have been updated...
Waiting for rollout to finish: 3 out of 10 new replicas have been updated...
Waiting for rollout to finish: 4 out of 10 new replicas have been updated...
Waiting for rollout to finish: 4 out of 10 new replicas have been updated...
Waiting for rollout to finish: 4 out of 10 new replicas have been updated...
Waiting for rollout to finish: 4 out of 10 new replicas have been updated...
Waiting for rollout to finish: 4 out of 10 new replicas have been updated...
Waiting for rollout to finish: 5 out of 10 new replicas have been updated...
Waiting for rollout to finish: 5 out of 10 new replicas have been updated...
Waiting for rollout to finish: 5 out of 10 new replicas have been updated...
Waiting for rollout to finish: 6 out of 10 new replicas have been updated...
Waiting for rollout to finish: 6 out of 10 new replicas have been updated...
Waiting for rollout to finish: 6 out of 10 new replicas have been updated...
Waiting for rollout to finish: 7 out of 10 new replicas have been updated...
Waiting for rollout to finish: 7 out of 10 new replicas have been updated...
Waiting for rollout to finish: 7 out of 10 new replicas have been updated...
Waiting for rollout to finish: 7 out of 10 new replicas have been updated...
Waiting for rollout to finish: 8 out of 10 new replicas have been updated...
Waiting for rollout to finish: 8 out of 10 new replicas have been updated...
Waiting for rollout to finish: 8 out of 10 new replicas have been updated...
Waiting for rollout to finish: 8 out of 10 new replicas have been updated...
Waiting for rollout to finish: 9 out of 10 new replicas have been updated...
Waiting for rollout to finish: 9 out of 10 new replicas have been updated...
Waiting for rollout to finish: 9 out of 10 new replicas have been updated...
Waiting for rollout to finish: 1 old replicas are pending termination...
Waiting for rollout to finish: 1 old replicas are pending termination...
Waiting for rollout to finish: 1 old replicas are pending termination...
Waiting for rollout to finish: 9 of 10 updated replicas are available...
Waiting for rollout to finish: 9 of 10 updated replicas are available...
Waiting for rollout to finish: 9 of 10 updated replicas are available...
deployment "guestbook" successfully rolled out
```
更新されたページを確認してみます。`v1`と同様に`<public-IP>`:`<Nodeport>`で確認することができます。私も確認しましたが、無事`v2`に更新されていることが確認できました。
（更新ができなかった場合には、`Ctrl+Shift+R`または`Cmd+Shift+R`を入力したらいいかもしれません。）
![スクリーンショット 2022-07-26 14.04.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/e815920c-4222-e572-f505-ac1348ad8b4c.png)

次に、最新のロールアウトを元に戻す場合は、以下のコマンドを使用します。
```
kubectl rollout undo deployment guestbook
```
もう一度`<public-IP>`:`<Nodeport>`で確認すると、`v1`にもどっていることがわかります。
![スクリーンショット 2022-07-22 16.41.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/dda7303f-b3bc-1583-7bfd-9471337737f4.png)

ロールアウトを実行すると、古いレプリカと新しいレプリカへの参照が表示されます。
- 古いレプリカ：アプリケーションをスケーリングしたときにデプロイされた元の10個のポッド
- 新しいレプリカ：異なるイメージで新しく作成されたポッドから取得される

これらのポッドはすべて、Deploymentが所有して、デプロイメントはReplicaSetと呼ばれるリソースを使用して2セットのポッドを管理します。以下のコマンドを入力しポッドを確認します。
```shell:check pods
kubectl get replicaset
```
guestbookのReplicaSetsの出力はは次のように表示されます。
```
$ kubectl get replicaset
NAME                   DESIRED   CURRENT   READY     AGE
guestbook-5f5548d4f    10        10        10        21m
guestbook-768cc55c78   0         0         0         3h
```
これで、アプリのVersion 2をデプロイしました。

ハンズオンが終了したら、以下のコマンドを入力し、guestbookのデプロイとサービスを削除します。
```shell:展開削除
kubectl delete deployment guestbook
```
```shell:サービス削除
kubectl delete service guestbook
```
## 最後に
今回はIBM Open Labs上のKubernetesを使ってアプリケーションをデプロイするハンズオンデモを行ってみました。

ターミナルなどを使って手入力あるいはコマンドのペーストなどよりは入力間違いが少なく、画面の右側にステータスなどがすぐ表示されるため、初心者にとっては非常に使いやすいと感じました。そのため、個人的にはテクノロジーの概要や仕組みを把握するには最適なサービスだと思います。

本文に記載していますが、KubernetesだけではなくOpenShiftを含めた様々なハンズオンがございますので、ぜひ一度ご活用ください。

## 参考リンク
- [IBM Open Labs](https://developer.ibm.com/openlabs/)
- [IBM Cloud Docs](https://cloud.ibm.com/docs/cli?topic=cli-getting-started#step1-install-idt)