Kubernetes Operator基本②（Helmベースのoperatorデモ）

前回の記事ではKubernetes Operatorに関して簡単な説明を行いました。
https://qiita.com/huachiting/items/b6e5b6062eef4f50750f

本記事ではRedHatのOperator SDKを使用し、HelmベースのOperatorのチュートリアルを実施しました。

### 1. 背景
私自身はkubernetesへのアプリデプロイ経験、運用経験がありますが、開発経験が一切ございません。
理解深めるためには簡単なデモを公式サイトを見ながら実施しました。

### 2. Operator SDKとは
Operator SDK は Kubernetes Operator を簡単に開発・ビルド・デプロイできるツールキットです。三つの開発言語（Go, Helm, Ansible)でOperatorを開発することができます。

今回Helmベースのoperatorデモを実施します。


### 3. Helmとは
Helm は Kubernetes のパッケージマネージャーであり、Kubernetes にアプリケーションをデプロイするには、たくさんの YAML ファイル（Deployment, Service, PVC など）の作成の代わりに、テンプレート化してまとめてデプロイできるのはHelmです。
Helmはチャートという単位で管理されてようです。1-チャーム＝１つのアプリケーション。


### 4. チュートリアル
Operator Sdkのチュートリアルは以下のサイトを見ながら実施しました。
https://redhat-scholars.github.io/operators-sdk-tutorial/template-tutorial/02-helm.html#init

#### 4.1 Operator sdk インストール
バイナリファイルダウンロード
```
export ARCH=$(case $(uname -m) in x86_64) echo -n amd64 ;; aarch64) echo -n arm64 ;; *) echo -n $(uname -m) ;; esac)
export OS=$(uname | awk '{print tolower($0)}')
export OPERATOR_SDK_DL_URL=https://github.com/operator-framework/operator-sdk/releases/download/v1.39.2
curl -LO ${OPERATOR_SDK_DL_URL}/operator-sdk_${OS}_${ARCH}
```

```
chmod +x operator-sdk_${OS}_${ARCH} && sudo mv operator-sdk_${OS}_${ARCH} /usr/local/bin/operator-sdk
```

以下のコマンドを実施し、問題なくインストールされたことを確認
```
operator-sdk version
```
#### 4.2 前提条件
1.OpenshiftクラスタやKubernetesクラスタが構築され、ユーザーに cluster-admin 権限があること。（私の場合、Azure Red Hat OpenShiftを構築しました。）
2.アクセスできるイメージレジストリがあること。
（私の場合、Dockerhubのアカウントを持っているので、作業用のサーバからCLIでログイン済）

#### 4.3 チュートリアル内容
HelmベースのnginxのOperatorを作成する
Operatorを使用し、nginxのデプロイを実施。
Deployment のレプリカ数が、Nginx のカスタムリソース（CR）仕様で指定された数と一致していること。

#### 4.4 新規プロジェクト作成

以下のコマンドで、APIバージョンはdemo.huachiting/v1alpha1、タイプはNginx のリソースを制御するための nginx-operator プロジェクトをする。

```
mkdir nginx-operator
cd nginx-operator
operator-sdk init --plugins helm --domain huachiting --group demo --version v1alpha1 --kind Nginx
```

#### 4.5 Operatorロジックのカスタマイズ
ロジック詳細：
nginx の Deployment が存在しない場合は作成。
nginx の Service が存在しない場合は作成。
Ingress が有効になっていて、存在しない場合は nginx の Ingress を作成。
Deployment、Service、および（必要に応じて）Ingress が、Nginx カスタムリソース（CR）で指定された希望の構成（例：レプリカ数、イメージ、サービス種別など）と一致していることをチェック。

#### 4.6 watches.yaml
4.4のコマンドで一部のひな形のソースコードを生成し、その中にwatches.yamlというファイルがあります。
watches.yaml は、Operator が監視するカスタムリソース（CR）やKubernetesオブジェクトの定義を記述するYAMLファイルです。このファイルは、Operator がどのCRやオブジェクトを監視し、その変更に対してどのようなアクション（Reconciliation）を実行するかを指示します。

#### 4.7 Helm ChartのYAMLファイル
4.4のコマンドでリソースをデプロイ時のサンプル用のYamlファイル（deployment,service,serviceaccountなど）を生成する。必要性に合わせてカスタマイズを行ことができます。

#### 4.8 Nginx CRファイル
Helmに詳しい方がご存じかと思いますが、Helm は、values.yaml というファイルを使って、Helm チャートのデフォルト設定をカスタマイズすることができます。
今回このvalues.yamlファイルに定義するデフォルトの値をカスタマイズするように自動生成されたconfig/samples/demo_v1alpha1_nginx.yamlファイルを編集。

```
apiVersion: demo.huachiting/v1alpha1
kind: Nginx
metadata:
  name: nginx-sample
spec:
  replicaCount: 2
  service:
    port: 8080
```
#### 4.9 レジストリにOperatorイメージをビルド、プッシュ
プッシュする前に、CLIからdockerにログインする必要がございます。
```
podman login --username XXXXXXXX --password XXXXXXXXX docker.io/huachiting/operator
```
ビルド、プッシュ：
```
make docker-build IMG=huachiting/operator:latest
make docker-push IMG=huachiting/operator:latest
```

#### 4.10 Openshift/Kubernetesクラスタにデプロイする。
通常開発者としてはlocalデプロイがよく使われるようです。localデプロイの場合、operatorはKubernetesの外からKubernetes APIを呼び出して、リソースの作成、削除、変更を実施する。その一方でKubernetesにデプロイする場合、operatorのイメージをまず生成し→レジストリにイメージプッシュ→Kubernetesへデプロイという流れになるので、Localデプロイより手間がかかります。

```
make deploy IMG=huachiting/operator:latest
```
デフォルトとしては、nginx-operator-systemというNSを作成し、このNSにOperatorをデプロイします。以下のコマンドOperatorがデプロイされたことを確認。

```
oc get deployment -n nginx-operator-system
NAME                                READY   UP-TO-DATE   AVAILABLE   AGE
nginx-operator-controller-manager   1/1     1            1           2m2s
```

#### 4.11 Nginx CR（Custom resource)ファイル作成

私はOpenshiftクラスタを使用するため、セキュリティコンテキスト(SCC)をsaに追加する必要があります。Kubernetesクラスタの場合不要
```
oc adm policy add-scc-to-user     anyuid system:serviceaccount:nginx-operator-system:nginx-sample -n nginx-operator-system
```

4.8で作成したCRファイルをデプロイ
```
kubectl apply -f config/samples/demo_v1alpha1_nginx.yaml -n nginx-operator-system
```
以下のコマンドを実施し、Operatorが CR（カスタムリソース）に従いデプロイメントを作成することを確認。
```
kubectl get deployment
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
nginx-sample   2/2     2            2           2m13s
```

### 5. 感想

このチュートリアルを実施し、なんとなくKubernetes operatorの開発手順を理解していますが、実際これより複雑なControllerのロジックの開発はどのように行うか正直わからないままです。
今後学習しながら最新の内容をアップデータしようと思います。