k3sを使ってTiDB Operatorをmacosで動かしてみた

オープンソース版のTiDB(TiDB Community)では、ローカルホストやオンプレミスなど様々な環境でTiDBを動作させることができます。このTiDB Community、[TiUP](https://docs.pingcap.com/ja/tidb/stable/production-deployment-using-tiup)と呼ばれるツールを使い必要なプロセスをインストール、起動する方法と、HelmとOperatorを使ってK8s上で動作させる方法があります。

macOSでもTiUPを使ってローカルでTiDBを動かすことができます。ただ、TiDB Operatorの動作確認などK8s環境で動かしたいときもあります。軽量K8sのK3sを利用してmacosでTiDBを動作させてみたので手順を紹介します。

## K3s環境の構築
### Multipassのインストール
K3sをmacOSで動作させるために、Ubuntu仮想マシンを簡単に起動できる[Multipass](https://multipass.run/)をインストールします。Multipassはbrewで簡単にインストールできます。
```zsh
brew install multipass
```

### K3s, Helmをインストール済みのUbuntuを起動
Multipassを使ってUbuntuを起動します。Multipassではcloud-initが利用できるので、cloud-initでK3s, helmをインストールしておきます。また、TiDB Operatorを動かすにはストレージがデフォルトの5GBだと不足するので、10GBで起動します。

まず、cloud-initのyamlファイルを作成します。

```yaml
# cloud-init.yaml
repo_update: true
repo_upgrade: all

runcmd:
  - 'curl -sfL https://get.k3s.io | sh -'
  - 'curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash'

ssh_authorized_keys:
  - <あなたのssh公開鍵へのパス>
```

次にこれを使ってイメージを作成、起動します。
```zsh
multipass launch --cpus 4 --memory 4G --disk 10G --name k3s --cloud-init cloud-init.yaml
```
作成できたら、ログインしてみます。
```zsh
multipass shell k3s
```

## TiDB Operatorのインストール
無事イメージが作成できたら、Ubuntu上でTiDB Operatorをインストールしていきます。

### K3s設定
標準ではK3sはsudoでkubectlを動かすようになっています。これだとコマンドを実行するとき少し不便なので、ubuntuユーザーでも実行出来るようにしておきます。

```bash
mkdir -p ~/.kube
sudo kubectl config view --raw >> ~/.kube/config
chmod 600 ~/.kube/config
echo "export KUBECONFIG=~/.kube/config" >> ~/.bashrc
source ~/.bashrc
```

### TiDB Operatorのインストール
ここからの手順は基本的に[Creating a Kubenetes Cluster using minikube](https://docs.pingcap.com/tidb-in-kubernetes/dev/get-started#method-2-create-a-kubernetes-cluster-using-minikube)の手順に沿っています。

Operatorのバージョンなどは適宜修正してください。

```bash
# CRDのインストール
kubectl create -f https://raw.githubusercontent.com/pingcap/tidb-operator/master/manifests/crd.yaml
# helmリポジトリの追加
helm repo add pingcap https://charts.pingcap.org/
# namespace作成
kubectl create namespace tidb-admin
# tidb operatiorのインストール。バージョンは適宜修正
helm install --namespace tidb-admin tidb-operator pingcap/tidb-operator --version v1.5.0-beta.1
# podが立ち上がっていることの確認
kubectl get pods --namespace tidb-admin -l app.kubernetes.io/instance=tidb-operator
```

最後のpodの確認で、tidb-controller-managerとtidb-schedulerが必要数起動していればOKです。

## TiDBクラスタの作成
TiDBクラスタを作成します。TiDBクラスタの作成には少し時間がかかります。

```bash
# クラスタ作成。時間がかかる。
kubectl create namespace tidb-cluster && \
    kubectl -n tidb-cluster apply -f https://raw.githubusercontent.com/pingcap/tidb-operator/master/examples/basic/tidb-cluster.yaml
# クラスタが起動するまで確認。起動したら Ctrl-Cで中断し先に進む
# basic-pd, basic-tikv, basic-tidb が起動するまで待つ。pd -> tikv -> tidbの順に起動する
watch kubectl get po -n tidb-cluster
# TiDB Dashboardの作成
kubectl -n tidb-cluster apply -f https://raw.githubusercontent.com/pingcap/tidb-operator/master/examples/basic/tidb-dashboard.yaml
# モニタリングの作成
kubectl -n tidb-cluster apply -f https://raw.githubusercontent.com/pingcap/tidb-operator/master/examples/basic/tidb-monitor.yaml
# dashboardとmonitoringが起動するまで確認。起動したら Ctrl-Cで中断し先に進む
watch kubectl get po -n tidb-cluster
```

## TiDBへの接続
podが全て想定数起動していれば、TiDBクラスタが作成できています。ここからはTiDB、TiDB Dashboard、Grafanaに接続していきます。

### ポートフォーワード設定
TiDBクラスタを動作させているUbuntu上で、下記のコマンドを実行します。
```bash
kubectl port-forward --address 0.0.0.0 -n tidb-cluster svc/basic-tidb 4000 > pf4000.out &
kubectl port-forward --address 0.0.0.0 -n tidb-cluster svc/basic-grafana 3000 > pf3000.out &
kubectl port-forward --address 0.0.0.0 -n tidb-cluster svc/basic-tidb-dashboard-exposed 12333 > pf12333.out &
```
これでK3s上のTiDBクラスタに外部から接続できるようになります。
別のターミナルを開いて、今度はmacOS側からMultipassを使い、実行中のK3sのIPアドレスを確認します。
```zsh
multipass list 
Name                    State             IPv4             Image
k3s                     Running           <IP>             Ubuntu 22.04 LTS
```
このIPv4列がK3sが実行されているUbuntuのIPです。macOS側からはこのIPを使って先ほどポートフォーワード設定をしたサービスに接続します。いくつかIPが表示された場合は、プライベートアドレスのものを利用してください。

```zsh
# mysqlに接続
mysql -u root -h <IP> -P 4000
```

また、http://<IP>:3000 でGrafanaに、http://<IP>:12333 でTiDB Dashboardにアクセスできます。

この状態での利用リソースはメモリ3.6GB、ディスク6GBというところでした。pd/tikv が1台、tidbが2台という構成なので、あまりPlaygroundと変わらないです。基本的にHelm/Operatorの動作や手順確認等で利用して、実際のワークロードはクラウド上のマネージドK8sサービスを使うのが良いのではと思います。