WSLでminikubeの環境構築をしてみる

この記事は[ニフクラ](https://www.nifcloud.com/) 等を提供している、[富士通クラウドテクノロジーズ Advent Calendar 2022](https://qiita.com/advent-calendar/2022/fjct) の9日目の記事です。

前日は[@nakanosika](https://qiita.com/yusayoshi)さんの[Istioでカスタムメトリクスの取得をやってみた](https://qiita.com/nakanosika/items/00d5874edc7984cbef38) でした。 
マイクロサービスを管理するにあたって[Istio](https://istio.io)は便利そうですよね。
Kubernetesをしっかり理解して使いこなせるようになりたいです。


## はじめに

Kubernetesが便利とは話には聞くのですが、なかなか難しそうと避けがちです。
やはり、何かしらのきっかけが欲しいと考え、先月から社内でKubernetesの勉強会を実施しています。

勉強会では主に[『Kubernetes完全ガイド 第2版』](https://book.impress.co.jp/books/1119101148)の輪読をメインに行っています。
この本はDockerの解説から丁寧にされているので、Kubernetesの初心者だけではなく、コンテナ技術初心者からでも参加しやすい勉強会になるのではないかと考え、輪読の題材として選択しました。

https://book.impress.co.jp/books/1119101148

来週からは実際にKubernetesを触っていく章に突入します。
そのためにKubernetesを体験できる環境を各自で構築する必要があります。
『Kubernetes完全ガイド 第2版』ではmacOSを使った環境構築が紹介されています。
しかし、私の持っている環境はWindowsであるため、今回はWSLを利用した開発環境の構築を行いました。
記録も兼ねてAdvent Calendarの記事として残しておこうと思います。

## ローカル環境でのKubernetes

手元の環境でKubernetesを構築するにはいくつかの方法があります。
- [Minikube](https://minikube.sigs.k8s.io/docs/)
- Docker Desktop for MAC/Windows
- [kind (Kubernetes in Docker)](https://kind.sigs.k8s.io/)
- [microk8s](https://microk8s.io/docs/getting-started)

書籍ではローカル環境でマルチノードクラスタを構築するにはkind一択だと紹介されていましたが、minikubeでもver1.10.1からマルチノードクラスタの構築が可能になったようです。
参考：[minikube/multi_node](https://minikube.sigs.k8s.io/docs/tutorials/multi_node/)

そこで、本記事ではWSLでminikubeの環境を構築してみます。
利用するLinuxのディストリビューションは**Ubuntu22.04**です。

> 追記:
WSLのバージョンは2です。
最近はデフォルトでWSL2が入ってきますが、既に導入済みの方はアップグレードが必要です。
https://learn.microsoft.com/ja-jp/windows/wsl/install

## systemdを有効化する

今年の9月21日からWSLでsystemdが動かせるようになりました。
参考:[Systemd support is now available in WSL!](https://devblogs.microsoft.com/commandline/systemd-support-is-now-available-in-wsl/)
minikubeの動作環境にはDockerが必要なのですが、せっかくなので今回はDockerをsystemdを利用して動かしてみます。

まず、PowerShellで WSLをアップデートします。
```shell
# PowerShellでの操作
wsl --update
```
バージョンが最新のものになったことを確認します。
```shell
# PowerShellでの操作
wsl --version
WSL バージョン: 1.0.1.0
カーネル バージョン: 5.15.74.2
WSLg バージョン: 1.0.47
MSRDC バージョン: 1.2.3575
Direct3D バージョン: 1.606.4
DXCore バージョン: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windowsバージョン: 10.0.22623.891
```

次にWSLでの操作を行います。
WSLでsystemdを利用するための設定ファイルを作成します。
```bash
# WSLでの操作
sudo vim /etc/wsl.conf
```
```wsl.conf
[boot]
systemd=true
```

再度PowerShellから操作し、WSLを再起動します。
```shell
# PowerShellでの操作
wsl --shutdown
```

## Dockerのinstall

[公式ドキュメント](https://docs.docker.com/engine/install/ubuntu/)を参考にInstallします。
```bash
# WSLでの操作
sudo apt update
sudo apt install \
    ca-certificates \
    curl \
    gnupg \
    lsb-release
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin
```
dockerコマンドをsudo権限無しで実行できるようにします。
```bash
sudo usermod -aG docker $USER
```
ターミナルを再起動すると、dockerコマンドが利用できるようになっていることが確認できました。
```bash
⬢ [Systemd] ❯ docker version
Client: Docker Engine - Community
 Version:           20.10.21
 API version:       1.41
 Go version:        go1.18.7
 Git commit:        baeda1f
 Built:             Tue Oct 25 18:01:58 2022
 OS/Arch:           linux/amd64
 Context:           default
 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          20.10.21
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.18.7
  Git commit:       3056208
  Built:            Tue Oct 25 17:59:49 2022
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.10
  GitCommit:        770bd0108c32f3fb5c73ae1264f7e503fe7b2661
 runc:
  Version:          1.1.4
  GitCommit:        v1.1.4-0-g5fd4c4d
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0
```

## minikubeのinstall

[公式ドキュメント](https://minikube.sigs.k8s.io/docs/start/)を参考にInstallします。
私の環境でのInstall方法は以下を利用しました。
![](https://i.imgur.com/xdrCLwp.png)
```bash
⬢ [Systemd] > curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 73.1M  100 73.1M    0     0  57.1M      0  0:00:01  0:00:01 --:--:-- 57.2M

~/workspace
⬢ [Systemd] > sudo install minikube-linux-amd64 /usr/local/bin/minikube
[sudo] password for nori3636:
```
無事Installできると`minikube start`コマンドでminikube環境が起動できるようになります。
```bash
⬢ [Systemd] ❯ minikube start
😄  minikube v1.28.0 on Ubuntu 22.04 (amd64)
✨  Automatically selected the docker driver
📌  Using Docker driver with root privileges
👍  Starting control plane node minikube in cluster minikube
🚜  Pulling base image ...
💾  Downloading Kubernetes v1.25.3 preload ...
    > preloaded-images-k8s-v18-v1...:  385.44 MiB / 385.44 MiB  100.00% 80.01 M
    > gcr.io/k8s-minikube/kicbase:  386.27 MiB / 386.27 MiB  100.00% 19.87 MiB
    > gcr.io/k8s-minikube/kicbase:  0 B [________________________] ?% ? p/s 16s
🔥  Creating docker container (CPUs=2, Memory=2200MB) ...
🐳  Preparing Kubernetes v1.25.3 on Docker 20.10.20 ...
    ▪ Generating certificates and keys ...
    ▪ Booting up control plane ...
    ▪ Configuring RBAC rules ...
🔎  Verifying Kubernetes components...
    ▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
🌟  Enabled addons: storage-provisioner, default-storageclass
💡  kubectl not found. If you need it, try: 'minikube kubectl -- get pods -A'
🏄  Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
```

## Kubectlのinstall

minikubeの環境は構築できましたが、Kubernetesクラスタを操作するには[Kubectl](https://kubernetes.io/ja/docs/reference/kubectl/overview/)というコマンドラインツールが必要です。
[公式サイト](https://kubernetes.io/ja/docs/tasks/tools/install-kubectl/)によると複数のInstall方法が紹介されていますが、今回はcurlを利用したInstallを実施しました。
```bash
curl -LO "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl
```
無事Installできたことを確認します。
```bash
⬢ [Systemd] ❯ kubectl version --short
Flag --short has been deprecated, and will be removed in the future. The --short output will become the default.
Client Version: v1.25.4
Kustomize Version: v4.5.7
Server Version: v1.25.3
```

### 入力補完の設定

Kubectlは導入したままの状態だと、コマンド入力時に補完は効かないようです。
[公式ドキュメント](https://kubernetes.io/ja/docs/reference/kubectl/cheatsheet/#bash)を参考に、コマンドの補完が効くようにします。
```bash
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc
```


## Hello Kubernetes !

環境構築が終わったので、実際に何かdeployをしてみます。

今回は試しにnginxのPodを3つ持つクラスタを構築してみます。
hello-world.ymlという名前でymlファイルを作成します。
参考:https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#creating-a-deployment

```hello-world.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
```
`kubectl apply`コマンドでデプロイします
```bash
⬢ [Systemd] ❯ kubectl apply -f hello-world.yml
deployment.apps/nginx-deployment created
```
無事にデプロイできたようです。

`kubectl get pods`コマンドでPodが3つ立っていることが確認できました。
```bash
⬢ [Systemd] ❯ kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-7fb96c846b-9pkzr   1/1     Running   0          2m53s
nginx-deployment-7fb96c846b-b7dgq   1/1     Running   0          2m53s
nginx-deployment-7fb96c846b-wgd4w   1/1     Running   0          2m53s
```

`minikube dashboard`というコマンドを使うとWebUI上からもデプロイされていることが確認できます。
```bash
minikube dashboard
🔌  Enabling dashboard ...
    ▪ Using image docker.io/kubernetesui/metrics-scraper:v1.0.8
    ▪ Using image docker.io/kubernetesui/dashboard:v2.7.0
💡  Some dashboard features require the metrics-server addon. To enable all features please run:

        minikube addons enable metrics-server


🤔  Verifying dashboard health ...
🚀  Launching proxy ...
🤔  Verifying proxy health ...
🎉  Opening http://127.0.0.1:44159/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/ in your default browser...
👉  http://127.0.0.1:44159/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/
```
![](https://i.imgur.com/oGX4U6h.png)
問題なく動いてそうです！

### お片付け

```bash
⬢ [Systemd] ❯ kubectl delete -f hello-world.yml
deployment.apps "nginx-deployment" deleted

⬢ [Systemd] ❯ minikube stop
✋  Stopping node "minikube"  ...
🛑  Powering off "minikube" via SSH ...
🛑  1 node stopped.
```

以上で環境構築は終わりです。
今後は実際に輪読会を進めながら、詳しいコマンドの使い方や、podsやサービスの扱い方を学んでいきたいです。

## おわりに

この記事は[富士通クラウドテクノロジーズ Advent Calendar 2022](https://qiita.com/advent-calendar/2022/fjct) の9日目の記事でした。

明日は [@e10persona](https://qiita.com/e10persona) さんの「青空文庫の書籍の表紙自動生成チャレンジ」です。
自分はデータ分析には疎く、どのような内容になるのか検討もつかないですがとても楽しみですね。