Kubernetes-in-docker(kind)でkubernetesクラスタを構築する

![logo-resized.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/705474/ca16c32c-23c5-3d68-1892-11df95336e34.png)

# はじめに

**対象読者**

- コンテナでKubernetesクラスタを構築したい方
- kindを試したい方

**前提知識**

- Dockerやコンテナに関する知識
- Kubernetesの基礎的な知識


**背景**
複数ノードのKubernetesクラスタを簡単に構築したい！！と思い、
下記のような要望を満たせないかと調べたところ[kind (kubernetes-in-docker)](https://kind.sigs.k8s.io/)というツールの存在を知ったので使ってみました。
本記事は備忘録です。

- 仮想マシンで構築するのは面倒なのでしたくない（ローカルでもクラウドでも）
- クラウドのk8sサービスも使いたくない
- docker-composeみたいに1コマンドでクラスタの作成削除ができると嬉しい
- クラスタは使い捨てにしたい


# kindとは

kindの全体像は下の図のようになります。
goアプリケーションであるkindから、クラスタの作成コマンドを叩くと`kindest/node`のコンテナが起動しkubernetesクラスタを構築します。
図中では区別していませんが、`kindest/node`のコンテナはそれぞれMasterノードとWorkerノードとして起動されます。

![kind_fig.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/705474/3245dbcb-5c4d-4fc3-fc00-8c528091b873.png)


kindを使うと何がうれしいのか...?
公式ページには`for testing Kubernetes itself`と記載があり、Kubernetesそのものをテストするために作られたものらしい。
多くのKubernetesユーザは`for local development or CI`とあるように、ローカルでの開発やKubernetesの勉強、CI/CDのパイプラインなどの方で活用できそうです。

> kind is a tool for running local Kubernetes clusters using Docker container “nodes”.
> kind was primarily designed for testing Kubernetes itself, but may be used for local development or CI.
> https://kind.sigs.k8s.io/

# 環境構築
## dockerのインストール
はじめにDockerをインストールします。

https://www.docker.com/products/docker-desktop

Windows10を使用しているので、`Docker Desktop for Windows`をインストールしています。

```shell
C:\>docker -v
Docker version 20.10.5, build 55c4c88
```

## goのインストール
次にgoをインストールします。
下記URLからダウンロードできるインストーラを利用してインストールできます。

https://golang.org/doc/install

```shell
C:\>go version
go version go1.16.7 windows/amd64
```

## kindのインストール
kindのインストール方法は下記のQuick Startに記載があります。


https://kind.sigs.k8s.io/docs/user/quick-start#installation

Windows向けの実行ファイルは下記URLからダウンロードします。
https://kind.sigs.k8s.io/dl/v0.11.1/kind-windows-amd64

ダウンロードされたファイルに拡張子がついていませんが、`.exe`を追加するだけでOKです。
Windows環境なので`mklink`コマンドを利用してダウンロードしたファイルのシンボリックリンクを作成します。

```shell
mklink kind.exe kind-windows-amd64
```

これで`kind`コマンドが使用できるようになりました。
（`kind.exe`のあるディレクトリで作業をする or PATHを通すのどちらかが必要）

# kindでクラスタの作成

## とりあえずクラスタを作成してみる

`kind create cluster`コマンドを実行してクラスタを起動してみました。

```shell
C:\>kind create cluster
Creating cluster "kind" ...
 • Ensuring node image (kindest/node:v1.21.1) 🖼  ...
 ✓ Ensuring node image (kindest/node:v1.21.1) 🖼
 • Preparing nodes 📦   ...
 ✓ Preparing nodes 📦
 • Writing configuration 📜  ...
 ✓ Writing configuration 📜
 • Starting control-plane 🕹️  ...
 ✓ Starting control-plane 🕹️
 • Installing CNI 🔌  ...
 ✓ Installing CNI 🔌
 • Installing StorageClass 💾  ...
 ✓ Installing StorageClass 💾
Set kubectl context to "kind-kind"
You can now use your cluster with:

kubectl cluster-info --context kind-kind

Not sure what to do next? 😅  Check out https://kind.sigs.k8s.io/docs/user/quick-start/
```

特に何も指定しないと`kind`という名前でkubernetesクラスタが作成されるようです。

```shell
C:\>kind get clusters
kind
```

`docker ps`コマンドを実行すると、下記のように`kind-control-plane`という名前のコンテナが起動していることが確認できます。
デフォルトでは`kind-control-plane`の1ノードしか起動されないようですね。

```shell
C:\>docker ps
CONTAINER ID   IMAGE                  COMMAND                  CREATED         STATUS         PORTS                       NAMES
c01d1fc6b936   kindest/node:v1.21.1   "/usr/local/bin/entr…"   2 minutes ago   Up 2 minutes   127.0.0.1:57863->6443/tcp   kind-control-plane
```

作成したクラスタを削除します。

```
C:\>kind delete cluster
Deleting cluster "kind" ...
```

## 複数ノードのクラスタを作成する

kindではyamlにクラスタの構成を記述することができます。
下のyamlではMasterノード1つ、Workerノード3つで構成されるクラスタが作成されます。

```yaml:mycluster.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
  extraPortMappings:
  - containerPort: 30001
    hostPort: 30001
- role: worker
  extraPortMappings:
  - containerPort: 30002
    hostPort: 30002
- role: worker
  extraPortMappings:
  - containerPort: 30003
    hostPort: 30003
```

下記のコマンドで`mycluster.yaml`を元にkubernetesクラスタを作成します。

```shell
kind create cluster --config mycluster.yaml
```

`docker ps`すると、コンテナが起動していることが確認できます。
コンテナとホスト間でポートがマッピングされていることも確認できます。

```shell
C:\>docker ps
CONTAINER ID   IMAGE                  COMMAND                  CREATED              STATUS              PORTS                       NAMES
8de298506989   kindest/node:v1.21.1   "/usr/local/bin/entr…"   About a minute ago   Up About a minute   0.0.0.0:30003->30003/tcp    kind-worker3
78772c73a52a   kindest/node:v1.21.1   "/usr/local/bin/entr…"   About a minute ago   Up About a minute   127.0.0.1:58237->6443/tcp   kind-control-plane
a2a7a3c46e95   kindest/node:v1.21.1   "/usr/local/bin/entr…"   About a minute ago   Up About a minute   0.0.0.0:30001->30001/tcp    kind-worker
cafaf17da932   kindest/node:v1.21.1   "/usr/local/bin/entr…"   About a minute ago   Up About a minute   0.0.0.0:30002->30002/tcp    kind-worker2
```

Masterノードのコンテナに入って`kubectl get nodes`コマンドを実行すると、複数ノード（コンテナ）でクラスタが構築されていることが確認できます。

```shell
C:\>docker exec -it kind-control-plane bash
root@kind-control-plane:/#
root@kind-control-plane:/# kubectl get nodes
NAME                 STATUS   ROLES                  AGE     VERSION
kind-control-plane   Ready    control-plane,master   10m     v1.21.1
kind-worker          Ready    <none>                 9m48s   v1.21.1
kind-worker2         Ready    <none>                 9m48s   v1.21.1
kind-worker3         Ready    <none>                 9m48s   v1.21.1
```

最後にクラスタを削除します。

```shell
C:\>kind get clusters
kind

C:\>kind delete cluster
Deleting cluster "kind" ...
```