k0sでkubernetesクラスタ構築

# 概要

[k0s](https://k0sproject.io/)はシングルバイナリのkubernetesディストリビューション。
kubernetesの構築が簡単にできる。

[参考にした記事](https://medium.com/better-programming/k0s-kubernetes-in-a-single-binary-224bb43f4520)

複数マシンにまたがった手順になるのでプロンプトを変えてどのマシンで実行するかわかるようにしてます。それぞれの意味は以下。

`>` : ホストマシン（windows powershell）
`(node1) $` : node1（ubuntu 20.04 multipass）
`(node2) $` : node2（ubuntu 20.04 multipass）

# VMを用意する

multipassを使用してVMを用意する。

```
> multipass version
multipass  1.5.0+win
multipassd 1.5.0+win
```

```
> multipass launch -n node1 -c 2 -m 2G
> multipass launch -n node2 -c 2 -m 2G
```

note. virtualboxをドライバにしてる場合以下のようなメッセージが出てlaunchに失敗した

```
launch failed: The following errors occurred:
node1: timed out waiting for response
```

virtualboxでうまく動かない場合は、Hyper-Vをドライバにするといい。（推奨はHyper-V）
うまく起動したかはlistで確認できる。

```
> multipass list
Name                    State             IPv4             Image
node1                   Running           192.168.249.123  Ubuntu 20.04 LTS
node2                   Running           192.168.249.124  Ubuntu 20.04 LTS
```

note. launchでtimeoutしてStoppedになっている場合がある、その時は手でstartしてやるとうまく動作することがある

```
> multipass list
Name                    State             IPv4             Image
node1                   Running           192.168.249.123  Ubuntu 20.04 LTS
node2                   Stopped           --               Ubuntu 20.04 LTS
> multipass start node2
> multipass list
Name                    State             IPv4             Image
node1                   Running           192.168.249.123  Ubuntu 20.04 LTS
node2                   Running           192.168.249.124  Ubuntu 20.04 LTS
```

# k0sをインストールする

最新のk0sをインストールするコマンドをそれぞれのVMで実行する

```
> multipass exec node1 -- bash -c "curl -sSLf get.k0s.sh | sudo sh"
> multipass exec node2 -- bash -c "curl -sSLf get.k0s.sh | sudo sh"
```

```
> multipass exec node1 -- k0s version
v0.9.1
> multipass exec node2 -- k0s version
v0.9.1
```

# k0sの設定

node1に入ってk0sの設定を作成する。

```
> multipass shell node1
```

```
(node1) $ k0s default-config > k0s.yaml
```

spec: api: sans: のIPが重複してたので一つ削除
master nodeを冗長化する場合やロードバランサーを使用する場合は、sansを追記したり書き換えたりする。

ここで作成した設定ファイルを `/etc/k0s/` に配置する。

```
(node1) $ sudo mkdir /etc/k0s
(node1) $ sudo mv k0s.yaml /etc/k0s/
```

# クラスターを初期化する

k0sはただの実行ファイルしか提供してないためsystemdをつかってデーモン化する。
以下のようなファイルを作成する。

```k0s.service
[Unit]
Description="k0s server"
After=network-online.target
Wants=network-online.target
 
[Service]
Type=simple
ExecStart=/usr/bin/k0s server -c /etc/k0s/k0s.yaml --enable-worker
Restart=always
```

ファイル作成後 `/etc/systemd/system` に配置する。

```
(node1) $ sudo mv k0s.service /etc/systemd/system/
```

配置したらsystemctlでサービスを起動する。

```
(node1) $ sudo systemctl start k0s.service
```

ログを見たいときはjournalctl

```
(node1) $ sudo journalctl -u k0s.service -f
```

# クラスタにアクセスする

node1に入ってアクセスできる場所にadmin.confを置いておく

```
(node1) $ sudo cat /var/lib/k0s/pki/admin.conf > k0s.conf
```

ログアウトしてホストマシンに先ほど置いた設定ファイルを出力する。

```
> multipass exec node1 sudo cat k0s.conf > k0s.conf
```

出力後にvimかなんかで開いてserverのlocalhostになっているところを、node1のIPアドレスに設定する。

```
clusters:
- cluster:
    server: https://192.168.249.123:6443
```

KUBECONFIGの環境変数に出力したファイルパスを指定する。
powershellだと環境変数にファイル名を指定するのがめんどくさいので以下のスクリプトを作った。
誰かいい方法教えてください。

```config.ps1
Param( $env )

if (!$env) {
  echo "invalid argument"
  echo "example: $ ./config.ps1 <config name>"
  exit 1
}

$scriptPath = $MyInvocation.MyCommand.Path
$dirName = Split-Path $scriptPath

echo "setup $env"
$config=Join-Path $dirName $env
$ENV:KUBECONFIG=$config
```

k0s.confと同じパスに配置して以下を実行。

```
> .\config.ps1 .\k0s.conf
```

実行後にkubectl get xxx して疎通していることを確認する。

```
> kubectl get node
NAME    STATUS   ROLES    AGE   VERSION
node1   Ready    <none>   20m   v1.20.1-k0s1
```

podがすべてRunningになっていることを確認する。

```
> kubectl get pods -A
NAMESPACE     NAME                                       READY   STATUS    RESTARTS   AGE
kube-system   calico-kube-controllers-5f6546844f-rcs4r   1/1     Running   0          21m
kube-system   calico-node-zdjr9                          1/1     Running   0          21m
kube-system   coredns-5c98d7d4d8-cht2h                   1/1     Running   0          21m
kube-system   konnectivity-agent-bnlf8                   1/1     Running   0          21m
kube-system   kube-proxy-f7t5m                           1/1     Running   0          21m
kube-system   metrics-server-7d4bcb75dd-65ps6            1/1     Running   0          21m
```

CNIまで一発で動くのはうれしい。

# workerノードを追加する

node2をworkerノードとして追加する。

node1にログインして以下を実行

```
(node1) $ sudo k0s token create --role=worker
```

出力結果をコピーする

以下のようなファイルを作成してTOKENを保持する。
node2にログインして以下実行。

```k0s.env
TOKEN=<コピーした文字列>
```

作成したファイルを `/etc/k0s` に配置する。

```
(node2) $ sudo mkdir /etc/k0s
(node2) $ sudo mv k0s.env /etc/k0s/
```

systemdを使ってデーモン化する。
以下のようなファイルを作成

```k0s.service
[Unit]
Description="k0s worker"
After=network-online.target
Wants=network-online.target
 
[Service]
Type=simple
ExecStart=/usr/bin/k0s worker ${TOKEN}
Restart=always
EnvironmentFile=/etc/k0s/k0s.env
```

`/etc/systemd/system/` に配置してサービスを起動

ファイル作成後 `/etc/systemd/system` に配置する。

```
(node2) $ sudo mv k0s.service /etc/systemd/system/
```

```
(node2) $ sudo systemctl start k0s.service
```

すべてのnodesがReadyになり、podsが動いてることを確認

```
> kubectl get nodes
NAME    STATUS   ROLES    AGE     VERSION
node1   Ready    <none>   6m54s   v1.20.1-k0s1
node2   Ready    <none>   44s     v1.20.1-k0s1
```

```
> kubectl get pods -A
NAMESPACE     NAME                                       READY   STATUS    RESTARTS   AGE
kube-system   calico-kube-controllers-5f6546844f-rcs4r   1/1     Running   0          45m
kube-system   calico-node-swxx8                          1/1     Running   0          13m
kube-system   calico-node-zdjr9                          1/1     Running   0          45m
kube-system   coredns-5c98d7d4d8-cht2h                   1/1     Running   0          45m
kube-system   konnectivity-agent-5x79c                   1/1     Running   0          12m
kube-system   konnectivity-agent-bnlf8                   1/1     Running   0          44m
kube-system   kube-proxy-f7t5m                           1/1     Running   0          45m
kube-system   kube-proxy-pq9sl                           1/1     Running   0          13m
kube-system   metrics-server-7d4bcb75dd-65ps6            1/1     Running   0          45m
```