Azure Kubernetes Service (AKS) で  Helm Chart を使用して Confluent Platform を動かしてみました

## 概要

Confuent Platform の Helm Chart と ACRにあるコンテナイメージ（Kafka Connector）から AKS でコンテナアプリケーションを稼働させるための環境構築手順をまとめました

このようなことをやってみたい、、、、ってところですが、この記事は下図の「④」の Confuent Platform 環境構築のみとなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/544022/99e68f8b-3482-4527-18c0-62b5174578e6.png)


---

### ローカル環境

- macOS Monterey 12.3
- python 3.8.12
- Azure CLI 2.34.1
- helm v3.6.3

### 事前準備

1. [この記事](https://qiita.com/turupon/items/b2f679ec6f9a69e30995) を実行して、AKSクラスタ環境を構築しておくこと　⇒　上図「②」
2. [この記事](https://qiita.com/turupon/items/e277728d0ebaccecf23b) を実行して、Kafka Connector のカスタマイズされたDockerイメージが ACR（Azure Container Registry） にプッシュされていること　⇒　上図「③」

---

## Helm Chart の作成（編集）

### Helm関連の事前設定・確認

```
## 現在ローカルにインストールされている Helm リポジトリ一覧
$ helm repo list                                                           
NAME         	URL                                           
stable       	https://charts.helm.sh/stable                 
bitnami-azure	https://marketplace.azurecr.io/helm/v1/repo   
confluentinc 	https://confluentinc.github.io/cp-helm-charts/
bitnami      	https://charts.bitnami.com/bitnami            

## アップデートコマンド
$ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "confluentinc" chart repository
...Successfully got an update from the "stable" chart repository
...Successfully got an update from the "bitnami" chart repository
...Successfully got an update from the "bitnami-azure" chart repository
Update Complete. ⎈Happy Helming!⎈

## Confluentのレポジトリの確認
$ helm search repo confluentinc
NAME                       	CHART VERSION	APP VERSION	DESCRIPTION                                       
confluentinc/cp-helm-charts	0.6.1        	1.0        	A Helm chart for Confluent Platform Community E...
stable/schema-registry-ui  	0.4.4        	v0.9.5     	DEPRECATED - This is a web tool for the conflue...

##  Helm Chrat の Pull
$ helm pull confluentinc/cp-helm-charts
$ tar zxf cp-helm-charts-0.6.1.tgz
$ ls -l
total 112
drwxr-xr-x   5 ituru  staff    160  4  6 23:29 ./
drwxr-xr-x   3 ituru  staff     96  4  6 22:59 ../
drwxr-xr-x  15 ituru  staff    480  4  6 23:29 cp-helm-charts/
-rw-r--r--   1 ituru  staff  50496  4  6 23:29 cp-helm-charts-0.6.1.tgz
```

### values.yaml ファイルの編集

cp-helm-charts の values.yaml については以下の部分を編集します（Confluent Platform は 6.1.0 を使用します）。ただし、Kafka Connector のみACRに登録されているコンテナイメージを使用します。また、今回は REST-Proxy を使用しないので無効化にしておきます

|Chart|タグ|項目|値|
|:---:|:---|:---|:---|
|cp-helm-charts|cp-kafka-rest|enabled|false|
||cp-kafka-connect|image|acr0ituru.azurecr.io/cp-connect-demo-cp610|
||cp-kafka-connect|imageTag|1.1.1|

---

## AKSへのインストール準備

### AKSクラスタ接続のためのための認証情報の取得

```
$ az aks get-credentials --resource-group rg_ituru_aks01 --name aks_ituru_cp01
The behavior of this command has been altered by the following extension: aks-preview
A different object named aks_ituru_cp01 already exists in your kubeconfig file.
Overwrite? (y/n): y
A different object named clusterUser_rg_ituru_aks01_aks_ituru_cp01 already exists in your kubeconfig file.
Overwrite? (y/n): y
A different object named aks_ituru_cp01 already exists in your kubeconfig file.
Overwrite? (y/n): y
Merged "aks_ituru_cp01" as current context in /Users/ituru/.kube/config
```

### AKSへのデプロイ

全てのPoｄが立ち上がるまでに数分かかります。しばし、待ちましょう、、、、、

```
## namespace の作成
$ kubectl create namespace akscp610
namespace/akscp610 created

## namespace のデフォルトとしての指定
$ kubectl config set-context --current --namespace akscp610
Context "aks_ituru_cp01" modified.

## デプロイ
$ helm install cp610 ./cp-helm-charts
```

### デプロイ後の確認

```
## インストール済み Chart の表示
$ helm list
NAME 	NAMESPACE	REVISION	UPDATED                             	STATUS  	CHART               	APP VERSION
cp610	akscp610 	1       	2022-05-13 11:20:11.255235 +0900 JST	deployed	cp-helm-charts-0.6.1	1.0        

## Pod の確認
$ kubectl get pod -o wide
NAME                                       READY   STATUS    RESTARTS      AGE     IP          NODE                               NOMINATED NODE   READINESS GATES
cp610-cp-control-center-f46bc647d-gxd4g    1/1     Running   3 (89s ago)   2m38s   10.0.1.10   aks-cpdemo01-25979417-vmss000000   <none>           <none>
cp610-cp-kafka-0                           2/2     Running   0             2m37s   10.0.1.78   aks-cpdemo01-25979417-vmss000002   <none>           <none>
cp610-cp-kafka-1                           2/2     Running   0             87s     10.0.1.42   aks-cpdemo01-25979417-vmss000001   <none>           <none>
cp610-cp-kafka-2                           2/2     Running   0             56s     10.0.1.19   aks-cpdemo01-25979417-vmss000000   <none>           <none>
cp610-cp-kafka-connect-7d8fb4c776-25x6l    2/2     Running   2 (86s ago)   2m38s   10.0.1.41   aks-cpdemo01-25979417-vmss000001   <none>           <none>
cp610-cp-ksql-server-656b866794-zt6mj      2/2     Running   2 (93s ago)   2m38s   10.0.1.17   aks-cpdemo01-25979417-vmss000000   <none>           <none>
cp610-cp-schema-registry-d8466d9dd-jzmtf   2/2     Running   2 (45s ago)   2m38s   10.0.1.69   aks-cpdemo01-25979417-vmss000002   <none>           <none>
cp610-cp-zookeeper-0                       2/2     Running   0             2m37s   10.0.1.40   aks-cpdemo01-25979417-vmss000001   <none>           <none>
cp610-cp-zookeeper-1                       2/2     Running   0             94s     10.0.1.12   aks-cpdemo01-25979417-vmss000000   <none>           <none>
cp610-cp-zookeeper-2                       2/2     Running   0             50s     10.0.1.76   aks-cpdemo01-25979417-vmss000002   <none>           <none>

## リソースの確認
$ kubectl get deployment
NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
cp610-cp-control-center    1/1     1            1           3m37s
cp610-cp-kafka-connect     1/1     1            1           3m37s
cp610-cp-ksql-server       1/1     1            1           3m37s
cp610-cp-schema-registry   1/1     1            1           3m37s

 ## 起動サービスの確認
 $ kubectl get service
NAME                          TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)             AGE
cp610-cp-control-center       ClusterIP   10.1.0.83    <none>        9021/TCP            4m
cp610-cp-kafka                ClusterIP   10.1.0.209   <none>        9092/TCP,5556/TCP   4m
cp610-cp-kafka-connect        ClusterIP   10.1.0.38    <none>        8083/TCP,5556/TCP   4m
cp610-cp-kafka-headless       ClusterIP   None         <none>        9092/TCP            4m
cp610-cp-ksql-server          ClusterIP   10.1.0.150   <none>        8088/TCP,5556/TCP   4m
cp610-cp-schema-registry      ClusterIP   10.1.0.168   <none>        8081/TCP,5556/TCP   4m
cp610-cp-zookeeper            ClusterIP   10.1.0.250   <none>        2181/TCP,5556/TCP   4m
cp610-cp-zookeeper-headless   ClusterIP   None         <none>        2888/TCP,3888/TCP   4m

## Config Map の確認
$ kubectl get configmap
NAME                                          DATA   AGE
cp610-cp-kafka-connect-jmx-configmap          1      4m27s
cp610-cp-kafka-jmx-configmap                  1      4m27s
cp610-cp-ksql-server-jmx-configmap            1      4m27s
cp610-cp-ksql-server-ksql-queries-configmap   1      4m27s
cp610-cp-schema-registry-jmx-configmap        1      4m27s
cp610-cp-zookeeper-jmx-configmap              1      4m27s
kube-root-ca.crt                              1      5m23s
```

---

## 設定の前の下準備

### kafka-client Pod の作成

kafka topic の設定を行うためのクライントのコンテナを用意します。cp-helm-charts/examples に予め用意されている kafka-client.yaml を以下のように変更します。

```
apiVersion: v1
kind: Pod
metadata:
  name: kafka-client
spec:
  containers:
  - name: kafka-client
    image: confluentinc/cp-kafka:6.1.0
    command:
      - sh
      - -c
      - "exec tail -f /dev/null"
```

この Pod を起動させます。

```
$ kubectl apply -f cp-helm-charts/examples/kafka-client.yaml
pod/kafka-client created
```

### ksql-client Pod の作成

ksql の設定を行うためのクライントのコンテナを用意します。cp-helm-charts/examples に予め用意されている ksql-demo.yaml を ksql-client.yaml としてコピーし、以下のように変更します。

```
apiVersion: v1
kind: Pod
metadata:
  name: ksql-client
spec:
  containers:
  - name: ksql-client
    image: confluentinc/cp-ksqldb-cli:6.0.0
    command:
      - sh
      - -c
      - "exec tail -f /dev/null"
```

この Pod を起動させます。

```
$ kubectl apply -f cp-helm-charts/examples/ksql-client.yaml
pod/ksql-client created
```

### Pod の最新情報の確認

```
$ kubectl get pod -o wide
NAME                                       READY   STATUS    RESTARTS        AGE     IP          NODE                               NOMINATED NODE   READINESS GATES
cp610-cp-control-center-f46bc647d-gxd4g    1/1     Running   3 (5m8s ago)    6m17s   10.0.1.10   aks-cpdemo01-25979417-vmss000000   <none>           <none>
cp610-cp-kafka-0                           2/2     Running   0               6m16s   10.0.1.78   aks-cpdemo01-25979417-vmss000002   <none>           <none>
cp610-cp-kafka-1                           2/2     Running   0               5m6s    10.0.1.42   aks-cpdemo01-25979417-vmss000001   <none>           <none>
cp610-cp-kafka-2                           2/2     Running   0               4m35s   10.0.1.19   aks-cpdemo01-25979417-vmss000000   <none>           <none>
cp610-cp-kafka-connect-7d8fb4c776-25x6l    2/2     Running   2 (5m5s ago)    6m17s   10.0.1.41   aks-cpdemo01-25979417-vmss000001   <none>           <none>
cp610-cp-ksql-server-656b866794-zt6mj      2/2     Running   2 (5m12s ago)   6m17s   10.0.1.17   aks-cpdemo01-25979417-vmss000000   <none>           <none>
cp610-cp-schema-registry-d8466d9dd-jzmtf   2/2     Running   2 (4m24s ago)   6m17s   10.0.1.69   aks-cpdemo01-25979417-vmss000002   <none>           <none>
cp610-cp-zookeeper-0                       2/2     Running   0               6m16s   10.0.1.40   aks-cpdemo01-25979417-vmss000001   <none>           <none>
cp610-cp-zookeeper-1                       2/2     Running   0               5m13s   10.0.1.12   aks-cpdemo01-25979417-vmss000000   <none>           <none>
cp610-cp-zookeeper-2                       2/2     Running   0               4m29s   10.0.1.76   aks-cpdemo01-25979417-vmss000002   <none>           <none>
kafka-client                               1/1     Running   0               52s     10.0.1.68   aks-cpdemo01-25979417-vmss000002   <none>           <none>
ksql-client                                1/1     Running   0               36s     10.0.1.52   aks-cpdemo01-25979417-vmss000001   <none>           <none>
```

---

## 各種Podの接続・確認方法

### Pod への接続

```
## Pod へのログイン（例）
$ kubectl exec -it kafka-client -- /bin/bash
$ kubectl exec -it ksql-client -- /bin/bash
```

### Control Center への接続

```
## Confluent Platform の Control Center への接続（ポートフォワードの設定） 
$ kubectl port-forward --address localhost svc/cp610-cp-control-center 9021:9021

Forwarding from 127.0.0.1:9021 -> 9021
Forwarding from [::1]:9021 -> 9021
```

ローカル環境のブラウザを立ち上げ「http://localhost:9021」で Confluent Platform の Control Center に接続できます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/544022/42b25b64-e4e0-2a33-7070-07c3ec2d5341.png)


### Kafka Connector の確認

確認するために Connect をローカルホストにリダイレクトします

```
$ kubectl port-forward --address localhost svc/cp610-cp-kafka-connect 8083:8083
Forwarding from 127.0.0.1:8083 -> 8083
Forwarding from [::1]:8083 -> 8083

※ CTRL+C で終了できます
```

別のターミナルを立ち上げ、Kafka Connector の Plug-in が存在することを確認する

```
$ curl http://localhost:8083/connector-plugins | jq
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  2031  100  2031    0     0  13891      0 --:--:-- --:--:-- --:--:-- 13910
[
  {
    "class": "com.azure.cosmos.kafka.connect.sink.CosmosDBSinkConnector",
    "type": "sink",
    "version": "null"
  },
  {
    "class": "com.azure.cosmos.kafka.connect.source.CosmosDBSourceConnector",
    "type": "source",
    "version": "null"
  },
    ：
   中略
    ：
  {
    "class": "io.confluent.connect.azuresqldw.AzureSqlDwSinkConnector",
    "type": "sink",
    "version": "1.0.4"
  },
    ：
   中略
    ：
  {
    "class": "io.debezium.connector.mysql.MySqlConnector",
    "type": "source",
    "version": "1.8.1.Final"
  },
    ：
   省略
    ：
]
```

Control Center　から確認すると以下のようになっています
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/544022/e2d22a6c-5c54-f31c-ac51-897c3c01b915.png)


---

### AKSクラスターの停止・起動

```
$ az aks stop -g rg_ituru_aks01 -n aks_ituru_cp01
$ az aks start -g rg_ituru_aks01 -n aks_ituru_cp01
```

### リソースのアンインストール方法

```
## Pod のアンインストール方法（例）
$ helm delete cp610             
W0407 17:38:18.658767   39907 warnings.go:70] policy/v1beta1 PodDisruptionBudget is deprecated in v1.21+, unavailable in v1.25+; use policy/v1 PodDisruptionBudget
release "cp610" uninstalled

$ kubectl delete -f cp-helm-charts/examples/kafka-client.yaml
$ kubectl delete -f cp-helm-charts/examples/ksql-client.yaml

## namespace の削除方法（namespace配下のPodも削除される）
$ kubectl delete namespace akscp610
namespace "akscp610" deleted
```

---

### まとめ

これで、AKS に Confluent Platform 環境が構築できました。次はトップの構成図のようにデータストリーミングができる設定を施していきたいと思います。

### 参考記事

過去に投稿した記事となります
[#1 Azure Kubernetes Service (AKS) で Confluent Platform の Helm Chart を使用してアプリケーションを動かしてみました](https://qiita.com/turupon/items/7f9265856480288f4bc7)
[#2 Azure Kubernetes Service (AKS) で Confluent Platform の Helm Chart を使用してアプリケーションを動かしてみました](https://qiita.com/turupon/items/4736b6d28ecfca727ef8)