【IBM Cloud】Helm チャートを使用してアプリケーションをデプロイしてみた

## はじめに
今回はIBM Cloud上のKuberenetes環境でHelmを使ってアプリケーションをデプロイする流れを整理します。
Kubernetesを使用したことがない方や、これから勉強される初心者の方向けの基礎的な内容です。
全体的な流れを記述するとともに、問題なくアプリケーションがデプロイされたことを確認することが目的です。

## 前提条件
・今回の内容にはIBM Cloudの[アカウント](https://cloud.ibm.com/docs/account?topic=account-accounts)（無料利用可能）が前提となっています。
・この記事でのコマンドは全てMacOS向けとなっています。

## Helmについて
![ㅇㅇㅇ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/f4251ba1-c13f-d032-f7b7-a12deb9d6f5b.png)

Helmは[公式HP](https://helm.sh/)にも記載されているとおり、「Kubernetesパッケージ管理」をサポートするツールです。
Kubernetesでのアプリケーション・リソースをパッケージングし、それを「Chart(チャート)」という一つのパッケージとしてKuberenetesクラスターに配布するツールとなります。

## Kubernetes環境の構築
今回Kubernetes環境はIBM CloudのKubernetesソリューションである、「IBM Cloud Kubernetes Service（IKS）」のクラシック環境を使用します。

[IBM Cloudコンソール](https://cloud.ibm.com/)のナビゲーション・メニューで`Kubernetes`→`クラスター`をクリックします。
![スクリーンショット 2023-01-27 14.21.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/b67bc18d-1c0c-113f-ea14-4579a57114be.png)

右上の`クラスターの作成`をクリックします。
![スクリーンショット 2023-01-27 14.21.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/2d399bee-30aa-5a0b-bbfd-61cb4a12f13a.png)

今回はクラシック環境で、東京リージョンでの最小限構成で作成しました。
![FireShot Capture 066 - クラスターの作成 - IBM Cloud - cloud.ibm.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/a2c12f0f-2a40-f275-8a49-34756cd179cf.png)
![スクリーンショット 2023-01-27 16.27.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/6836f113-fae0-5505-ee50-064e53867f7d.png)


無料枠も利用可能ですので、もし無料で試してみたい方は、料金プランを`無料`に変更し、適切なクラスター名を設定して環境を作成してください。
![FireShot Capture 065 - クラスターの作成 - IBM Cloud - cloud.ibm.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/4fdeea70-8817-62bb-5872-0034df173a12.png)

クラスターの一覧で作成したクラスターに入ると、以下の画面が表示されます。
なお、クラスター作成時には多少の時間がかかる可能性があります。Statusが「正常」になっていることを確認してください。
(もしErrorなどが発生した場合には、[IBM Cloud Docs](https://cloud.ibm.com/docs/containers?topic=containers-debug_master)を参照ください。)
![スクリーンショット 2023-01-27 14.32.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/0d295580-c8c4-e6c4-dd0d-6f446554571f.png)
![スクリーンショット 2023-01-27 14.33.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/3ca57f4c-9624-771c-5af0-90747b5943cb.png)

なお、コンソールではなくコマンドでもKubernetes環境を立ち上げる方法については、過去の[記事](https://qiita.com/Sungyun_Moon/items/2d014c6083c315c801b7)を参考にしてください。

これでKuberenetes環境の立ち上げは完了です。

## アプリケーションデプロイの流れ
#### Helmのインストール
まず、Helmがインストールされていない場合には、[手順に従って](https://helm.sh/docs/intro/)自分のPCなどの開発環境にHelmをインストールします。
Helmはv3.0.2以上であることを確認します。（2024/12/18現在、v3.16.4です。）

インストールが完了したら、コマンドにてHelmのバージョンを確認します。
```shell:Helmのバージョン確認
helm version
```

```shell:Helmのバージョン確認結果
version.BuildInfo{Version:"v3.16.4", GitCommit:"472c5736ab01133de504a826bd9ee12cbe4e7904", GitTreeState:"clean", GoVersion:"go1.18.10"}
```

#### IBM Cloudにログイン
IBM Cloudにログインします。ログインはCLIを使用したワンタイム・パスコードを利用すると便利です。
右上のプロフィールアイコンをクリックし、`CLIとAPIにログイン`をクリックしますと、以下のログインCLIが表示されます。
IBM Cloud CLIをコピーしコマンド入力にてログインを行います。
![スクリーンショット 2023-01-27 14.52.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/85389613-4b70-eda8-43d4-a0da1211064c.png)
![スクリーンショット 2023-01-27 14.52.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/04c3ad3e-31da-6abc-804c-506a5536429d.png)

#### Kubernetesクラスター指定
今回アプリケーションをデプロイするクラスターを指定します。
Kubernetesの環境を設定するには、exportコマンドが必要です。exportコマンドは、`ibmcloud ks cluster config`コマンドを入力して取得します。
なお、クラスターIDはクラスター画面に表示されています。
```shell:クラスター環境指定
ibmcloud ks cluster config --cluster <cluster-id>
```

```shell:クラスター環境指定の結果
<cluster-id> のコンテキストを現在の kubeconfig ファイルに追加しました。
これで、クラスターに対して「kubectl」コマンドを実行できます。 例えば、「kubectl get nodes」を実行します。
クラスターに初めてアクセスする場合、RBAC の同期中に「kubectl」コマンドが数秒間失敗することがあります。
```
![スクリーンショット 2023-01-27 15.05.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/b737f13f-2b5f-980e-a4dd-57c223ac7d4b.png)

#### Helmを使用してデプロイするアプリケーションのクローン
今回Helmチャートを使用してデプロイするアプリケーションは「JpetStore」アプリケーションです。
「JpetStore」は簡潔なECサイト機能を含んでいるサンプルアプリケーションです。

Gitコマンドを使って、JpetStoreリポジトリをクローンします。
```shell:JpetStoreリポジトリをクローン
git clone https://github.com/ibm-cloud-labs/jpetstore-kubernetes-compact.git --depth 1
```

「JpetStore」アプリケーションをデプロイします。
なお、デプロイは`jpetstore-kubernetes-compact/helm`ディレクトリで操作します。
```shell:JpetStoreアプリケーションのデプロイ
cd ../helm
helm install jpetstore ./modernpets/
```
```shell:JpetStoreアプリケーションのデプロイ結果
NAME: jpetstore
LAST DEPLOYED: Fri Jan 27 15:57:43 2023
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Get Cluster Public IP Adress:
$ ibmcloud ks workers mycluster
```

デプロイの確認を行います。
```shell:デプロイの確認
helm list
```
```shell:デプロイの確認結果
NAME     	NAMESPACE	REVISION	UPDATED                             	STATUS  	CHART           	APP VERSION
jpetstore	default  	1       	2023-01-26 19:03:06.402354 +0900 JST	deployed	modernpets-0.1.5	1.0    
```

デプロイされたPodsも確認します。
```shell:デプロイのPods確認
kubectl get pods
```
```shell:デプロイのPods確認結果（例）
NAME                                                 READY   STATUS    RESTARTS   AGE
jpetstore-modernpets-jpetstoredb-54644d98f5-lgwfr    1/1     Running   0          117s
jpetstore-modernpets-jpetstoreweb-68f5bd5d79-6bhnt   1/1     Running   0          117s
jpetstore-modernpets-jpetstoreweb-68f5bd5d79-lzbjl   1/1     Running   0          117s
```
上記出力から、Webコンテナ(jpetstoreweb)のPodsが2つ，DBコンテナ(jpetstoredb)のPodsが1つがデプロイされていることが分かります。

DeploymentやServiceについても確認します。
```shell:DeploymentとServiceの確認
kubectl  get all
```
```shell:DeploymentとServiceの確認結果
NAME                                                 READY   STATUS    RESTARTS   AGE
jpetstore-modernpets-jpetstoredb-54644d98f5-lgwfr    1/1     Running   0          117s
jpetstore-modernpets-jpetstoreweb-68f5bd5d79-6bhnt   1/1     Running   0          117s
jpetstore-modernpets-jpetstoreweb-68f5bd5d79-lzbjl   1/1     Running   0          117s
sungyunmoon@SungyunnoMacBook-Pro helm % kubectl  get all
NAME                                                     READY   STATUS    RESTARTS   AGE
pod/jpetstore-modernpets-jpetstoredb-54644d98f5-lgwfr    1/1     Running   0          2m33s
pod/jpetstore-modernpets-jpetstoreweb-68f5bd5d79-6bhnt   1/1     Running   0          2m33s
pod/jpetstore-modernpets-jpetstoreweb-68f5bd5d79-lzbjl   1/1     Running   0          2m33s

NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
service/db           ClusterIP   172.21.198.176   <none>        3306/TCP       2m33s
service/kubernetes   ClusterIP   172.21.0.1       <none>        443/TCP        15m
service/web          NodePort    172.21.67.242    <none>        80:31000/TCP   2m33s

NAME                                                READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/jpetstore-modernpets-jpetstoredb    1/1     1            1           2m33s
deployment.apps/jpetstore-modernpets-jpetstoreweb   2/2     2            2           2m33s

NAME                                                           DESIRED   CURRENT   READY   AGE
replicaset.apps/jpetstore-modernpets-jpetstoredb-54644d98f5    1         1         1       2m33s
replicaset.apps/jpetstore-modernpets-jpetstoreweb-68f5bd5d79   2         2         2       2m33s
```

#### ブラウザーでのアプリケーションの確認
アプリケーションのデプロイが完了すると、次はブラウザーでの状態を確認します。現在「Jpetstore」アプリケーションは、Kubernetesクラスター上で動作していて、インターネットに公開されている状態です。
確認のために、ワーカーノードのパブリックIPアドレス(Public IP)とノードポートを取得します。

```shell:パブリックIPアドレスの取得
ibmcloud ks worker ls --cluster <cluster-id>
```

```shell:パブリックIPアドレスの取得結果
OK
ID                                                       パブリック IP    プライベート IP   フレーバー          状態     状況    ゾーン   バージョン   
kube-cf9n2nnt0ven2m0lmlqg-moonmyclust-default-0000019d   169.56.0.231     10.132.238.120    u3c.2x4.encrypted   normal   Ready   tok02    1.25.5_1528   
kube-cf9n2nnt0ven2m0lmlqg-moonmyclust-default-00000280   165.192.80.43    10.193.189.3      u3c.2x4.encrypted   normal   Ready   tok05    1.25.5_1528   
kube-cf9n2nnt0ven2m0lmlqg-moonmyclust-default-0000033b   128.168.82.163   10.192.64.52      u3c.2x4.encrypted   normal   Ready   tok04    1.25.5_1528 
```

```shell:ノードポートの取得
kubectl get service
```

```shell:ノードポートの取得の結果
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
db           ClusterIP   172.21.198.176   <none>        3306/TCP       13m
kubernetes   ClusterIP   172.21.0.1       <none>        443/TCP        26m
web          NodePort    172.21.67.242    <none>        80:31000/TCP   13m
```

ブラウザで`Public IP`:`NodePort`を開きます。
今回の場合の`Public IP`:`NodePort`は以下の通りです。
- Public IP: 169.56.0.231 (３つとも可能ですが、今回は1行目のIPアドレスを使用します。)
- NodePort: 31000

つまり、「169.56.0.231:31000」 にアクセスするとアプリケーションが開きます。画面は以下のようになります。
![スクリーンショット 2023-01-27 16.15.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/d542ddd1-fc29-756d-07bc-fa6a9fb58c19.png)

カテゴリーをクリックして情報を確認したり、右上の検索欄なども使えるので、一度いじりながら確認してみてください。

## Kubernetesダッシュボードの確認
最初に立ち上げたKubernetesに入り、ダッシュボードを確認してみます。
右上の`Kubernetesダッシュボード`をクリックしアクセスします。
![スクリーンショット 2023-01-27 14.33.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/cedbd74f-e2a1-39dd-7f95-74d867d3ea91.png)

ダッシュボードに入りますと、先ほどデプロイしたアプリケーションの情報が記載されていることがわかります。
ワークロードのStatusやCPUとメモリーの使用量など、クラスター情報が見やすくなっているので確認してみてください。
![スクリーンショット 2023-01-27 16.18.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/48ea319d-f349-698f-5b62-20eb46b67642.png)
![スクリーンショット 2023-01-27 16.19.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626032/7ce0f08b-e9d7-8d6d-dd1e-a303b2b613c2.png)

## 最後に
今回はIBM Cloud上にKubernetesクラスターを立ち上げ、Helmを利用したサンプルアプリケーションのデプロイを実施しました。
前回の記事ではサンプルアプリケーションとしてguestbookを使用してデプロイしたことがありますが、Helmを使用することによってより簡単にデプロイができちゃうことがわかりました。
ただ、Kubernetesダッシュボードの操作法などはまだまだ勉強が必要であるため、今後も引き続きスキルを身につけ、記事を投稿していきたいと思います。

## 注意点
1. このアカウントではディスカウントが適用されているため、表示価格が通常の定価と異なる場合があります。
2. 料金はドル-円為替レートに基づいて課金されるため、同じサービスでも料金の変動があります。
3. Qiita記事作成にあたり、環境の時間軸の前後やインスタンス名の違いなどがあります。

## 参考
・[【IBM Cloud】 IBM Open Labs上のKubernetesでアプリをデプロイしてみた](https://qiita.com/Sungyun_Moon/items/2d014c6083c315c801b7)
・[IBM Cloud Docs - IBM Cloud Kubernetes Service](https://cloud.ibm.com/docs/containers?topic=containers-getting-started)
・[Helm HP](https://helm.sh/docs/intro/quickstart/)