Kubernetesことはじめ 続編〜CockroachDBをデプロイ〜

# KubernetesでCockroachDBをデプロイ

ここでは分散SQLのCockroachDBをデプロイします。
CockroachDBは、Raftをコンセンサスにもつ分散データベースです。
リーダー選挙で、ノードがログレプリケーションを行い、他のノードたちに更新内容を複製します。この機構によって、複数のノードが同じDBを持ち、変更されるとログレプリケーションによって同期していきます。

こちらのチュートリアルを読みつつ、分散DBを堪能します！！

参考
https://www.cockroachlabs.com/docs/v24.2/orchestrate-a-local-cluster-with-kubernetes?

## 環境

2024年9月27日時点

Machine
```
Apple M1
macos Ventura 13.2.1（22D68）
```

Kubernetes
```
% minikube version
minikube version: v1.34.0
commit: 210b148df93a80eb872ecbeb7e35281b3c582c61
```

CockroachDB
```
Cockroachdb Version 24.21
```

## 予備知識

kubernetesを使用して、分散SQLを使います！登場人物を先に知っておきましょう。
Podたちを次のように構成します。

| Pods | 役割 |
| ---- | ---- |
|cockroach-operator-manager| cockroachdb-* を作成します|
| - cockroachdb-0 <br> - cockroachdb-1 <br> - cockroachdb-2 | ステートフルにデータを保持します|
|cockroachdb-client-secure | clientリクエストを受け付けます|



| 機能 | 説明 |
| ---- | ---- |
| minikube | VM内のkubernetes clusterを実行します |
| pod | docker containerのグループの一つです。全てのpodたちはローカルマシン上で実行され、各podはそれぞれが一つのCockroachDB nodeを起動する一つのContainerを含みます。３つのpodから初めて4つのpodに拡張してみましょう。 |
| Statefulset | データの状態をステートフルに持ち、各ポッドは区別可能なネットワーク ID を持ち、再起動時に常に同じ永続ストレージにバインドされます。 |
| persitentvolume | Podにマウントされた永続ボリュームです。有効期間はPodの有効期間とは別です。続ボリュームは、手動で削除されるか、Kubernetes クラスター全体が削除されるまで存続する外部一時ディレクトリです。 |
|persitentvolume claim|ポッドが作成されると (CockroachDB ノードごとに 1 つ)、各ポッドはそのノードの耐久性ストレージを「要求」するために永続ボリューム要求を要求します。|


## Start Kubernetes

```
minikube start
```

まっさらな状態から始めました。
```
% kubectl get pods
No resources found in default namespace.
```

## Start CockroachDB

### Operatorの導入

Operatorは`namespace: cockroach-operator-system`にインストールされ、CockroachDB instancesを操作するように構成されます。

#### CRD

CRDはCustom Resource Definitionの略で、独自リソースを定義するものです。詳しくはこちら。

https://qiita.com/cvusk/items/773e222e0971a5391a51


```
kubectl apply -f https://raw.githubusercontent.com/cockroachdb/cockroach-operator/v2.14.0/install/crds.yaml
customresourcedefinition.apiextensions.k8s.io/crdbclusters.crdb.cockroachlabs.com configured
```

#### Operator

<details><summary>operator.yamlをgiturlを指定してリモート実行する場合</summary>

```
kubectl apply -f https://raw.githubusercontent.com/cockroachdb/cockroach-operator/v2.14.0/install/operator.yaml
namespace/cockroach-operator-system unchanged
serviceaccount/cockroach-operator-sa unchanged
clusterrole.rbac.authorization.k8s.io/cockroach-operator-role configured
clusterrolebinding.rbac.authorization.k8s.io/cockroach-operator-rolebinding unchanged
service/cockroach-operator-webhook-service created
deployment.apps/cockroach-operator-manager created
mutatingwebhookconfiguration.admissionregistration.k8s.io/cockroach-operator-mutating-webhook-configuration configured
validatingwebhookconfiguration.admissionregistration.k8s.io/cockroach-operator-validating-webhook-configuration configured
```

</details>

`namespace: cockroach-operator-system`を自分で作ったものにしたい場合は、operator.yamlをダウンロードして、フィールドの値を変更してください。
<details><summary>operator.yamlをダウンロードする場合</summary>
```
curl -O https://raw.githubusercontent.com/cockroachdb/cockroach-operator/v2.14.0/install/operator.yaml
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 19504  100 19504    0     0  48910      0 --:--:-- --:--:-- --:--:-- 49377
```

```
kubectl apply -f operator.yaml
namespace/cockroach-operator-system unchanged
serviceaccount/cockroach-operator-sa unchanged
clusterrole.rbac.authorization.k8s.io/cockroach-operator-role configured
clusterrolebinding.rbac.authorization.k8s.io/cockroach-operator-rolebinding unchanged
service/cockroach-operator-webhook-service unchanged
deployment.apps/cockroach-operator-manager unchanged
mutatingwebhookconfiguration.admissionregistration.k8s.io/cockroach-operator-mutating-webhook-configuration configured
validatingwebhookconfiguration.admissionregistration.k8s.io/cockroach-operator-validating-webhook-configuration configured
```
</details>




```
kubectl config set-context --current --namespace=cockroach-operator-system
Context "minikube" modified.
```

```
kubectl get pods
NAME                                          READY   STATUS    RESTARTS   AGE
cockroach-operator-manager-6dc7489d4d-mpq7x   1/1     Running   0          38s
```

### クラスタの初期化

```
curl -O https://raw.githubusercontent.com/cockroachdb/cockroach-operator/v2.14.0/examples/example.yaml
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  2191  100  2191    0     0   5593      0 --:--:-- --:--:-- --:--:--  5661
```

```
kubectl apply -f example.yaml
crdbcluster.crdb.cockroachlabs.com/cockroachdb created
```

```
kubectl get pods
NAME                                          READY   STATUS              RESTARTS   AGE
cockroach-operator-manager-6dc7489d4d-mpq7x   1/1     Running             0          67s
cockroachdb-vcheck-28775966-k4h7f             0/1     ContainerCreating   0          5s
```

Operatorがレプリカを作ってくれる。
2分後にもう一度見てみる
```
kubectl get pods
NAME                                          READY   STATUS        RESTARTS   AGE
cockroach-operator-manager-6dc7489d4d-mpq7x   1/1     Running       0          2m31s
cockroachdb-0                                 0/1     Running       0          4s
cockroachdb-1                                 0/1     Pending       0          4s
cockroachdb-2                                 0/1     Pending       0          4s
cockroachdb-vcheck-28775966-k4h7f             1/1     Running       0          89s
cockroachdb-vcheck-28775967-9ztkt             1/1     Terminating   0          22s

```

## SQL client作成



```
kubectl create \
-f https://raw.githubusercontent.com/cockroachdb/cockroach-operator/v2.14.0/examples/client-secure-operator.yaml
pod/cockroachdb-client-secure created

```


kubenetesから`cockroachdb-client-secure`に接続する。
```
kubectl exec -it cockroachdb-client-secure \
-- ./cockroach sql \
--certs-dir=/cockroach/cockroach-certs \
--host=cockroachdb-public
#
# Welcome to the CockroachDB SQL shell.
# All statements must be terminated by a semicolon.
# To exit, type: \q.
#
# Server version: CockroachDB CCL v23.2.3 (aarch64-unknown-linux-gnu, built 2024/03/14 16:32:17, go1.21.5 X:nocoverageredesign) (same version as client)
# Cluster ID: 1e074b37-7164-4274-aae8-fb585b81f9bd
#
# Enter \? for a brief introduction.
#
```

## CockroachDB

bank DATABASEを作成
```
root@cockroachdb-public:26257/defaultdb> CREATE DATABASE bank;                           
CREATE DATABASE

Time: 25ms total (execution 25ms / network 1ms)

```

`bank.accounts` Tableを作成

```
root@cockroachdb-public:26257/defaultdb> CREATE TABLE bank.accounts (id INT PRIMARY KEY, 
                                      -> balance DECIMAL);                               
CREATE TABLE

Time: 29ms total (execution 28ms / network 1ms)

```

recordを挿入
```
root@cockroachdb-public:26257/defaultdb> INSERT INTO bank.accounts VALUES (1, 1000.50);  
INSERT 0 1

Time: 21ms total (execution 21ms / network 0ms)

```

`bank.accounts`Tableから全レコードを表示

```
root@cockroachdb-public:26257/defaultdb> SELECT * FROM bank.accounts;                    
  id | balance
-----+----------
   1 | 1000.50
(1 row)

Time: 2ms total (execution 1ms / network 1ms)

```

パスワード付きユーザーを作成
```
root@cockroachdb-public:26257/defaultdb> CREATE USER roach WITH PASSWORD 'Q7gc8rEdS';    
CREATE ROLE

Time: 554ms total (execution 553ms / network 1ms)


```

SQL入力受付を終了
```
root@cockroachdb-public:26257/defaultdb> \q 
```

## クラスタのDB consoleにアクセス

```
% kubectl exec -it cockroachdb-client-secure \
-- ./cockroach sql \
--certs-dir=/cockroach/cockroach-certs \
--host=cockroachdb-public
#
# Welcome to the CockroachDB SQL shell.
# All statements must be terminated by a semicolon.
# To exit, type: \q.
#
# Server version: CockroachDB CCL v23.2.3 (aarch64-unknown-linux-gnu, built 2024/03/14 16:32:17, go1.21.5 X:nocoverageredesign) (same version as client)
# Cluster ID: 1e074b37-7164-4274-aae8-fb585b81f9bd
#
# Enter \? for a brief introduction.
#

```

```
root@cockroachdb-public:26257/defaultdb> GRANT admin TO roach;                           
GRANT

Time: 484ms total (execution 481ms / network 3ms)

```

```
root@cockroachdb-public:26257/defaultdb> \q   
```

### ポートを転送

ターミナルウィンドウを新しく開き次を実行します。
```
% kubectl port-forward service/cockroachdb-public 8080
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080

```

ブラウザから見てみます。
https://localhost:8080

先ほど作ったユーザとパスワードを入力します。


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443312/80a8654d-504f-55b8-4301-baa0f0ca4128.png" width="400">

ログインできました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443312/e5289643-39c2-7f0c-1743-2afcbbbd91ce.png" width="400">

Databaseを見ると、先ほど作成したDB`bank`があります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443312/d2012b51-6615-c28d-6927-6b078f69af09.png" width="400">

bankの中身を見ると、`accounts`テーブルが確認できました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443312/7690efb8-2293-a2e9-9263-863750f5c66f.png" width="400">

Insightsには先ほどのリクエストが記録されています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443312/63517031-27cf-4fcc-4883-2d385c752330.png" width="400">


## クラスタを停止

最後はクラスタを停止しましょう。
```
minikube stop
```

ここまでで一通り、レプリカ数3個で構成されるクラスタを使用して分散DBであるCockroachDBを作成、Clientからアクセスしました。続編では、Podの追加を行います。CockroachDBのコンセンサスRaftの真髄、Membership変更です！

## 参考；デプロイに使用したファイル

[crds.yaml](https://github.com/cockroachdb/cockroach-operator/blob/v2.14.0/install/crds.yaml)
[operator.yaml](https://github.com/cockroachdb/cockroach-operator/blob/v2.14.0/install/operator.yaml)
[example.yaml](https://github.com/cockroachdb/cockroach-operator/blob/v2.15.0/examples/example.yaml)
[client-secure-operator.yaml](https://github.com/cockroachdb/cockroach-operator/blob/v2.14.0/examples/client-secure-operator.yaml)