ArchLinux上でkubeadmを使用したKubernetsクラスタを構築

# 構成
ホスト、ゲスト全てArchLinuxです。

``` :構成図
Host(MeYururi-Desktop)
  | <- bridge でぶら下がっています。
  +- Guest KVM( arch-mn01 )
  +- Guest KVM( arch-wn01 )
```

| hostname | IP Address |
|:-:|:-:|
| MeYururi-Desktop | 192.168.3.103 |
| arch-mn01 | 192.168.3.181 |
| arch-wn01 | 192.168.3.182 |

``` :uname
kizuka@MeYururi-Desktop ~ <- ホスト
❯ uname -a
Linux MeYururi-Desktop 5.10.13-arch1-2 #1 SMP PREEMPT Sat, 06 Feb 2021 11:07:29 +0000 x86_64 GNU/Linux

[root@arch-mn01]# uname -a <- ゲスト
Linux arch-mn01 5.10.14-arch1-1 #1 SMP PREEMPT Sun, 07 Feb 2021 22:42:17 +0000 x86_64 GNU/Linux

[root@arch-wn01]# uname -a <- ゲスト
Linux arch-wn01 5.10.14-arch1-1 #1 SMP PREEMPT Sun, 07 Feb 2021 22:42:17 +0000 x86_64 GNU/Linux
```

マスター1台、ワーカー1台の構成を目指します。

``` :nodes
[root@arch-mn01 ~]# kubectl get nodes
NAME        STATUS   ROLES    AGE   VERSION
arch-mn01   Ready    master   9h    v1.19.4
arch-wn01   Ready    <none>   9h    v1.19.4
```

# 手順
OSのインストールはArchWikiを参照しながら実施。([インストールガイド](https://wiki.archlinux.jp/index.php/%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%82%AC%E3%82%A4%E3%83%89))
本記事では、インストールガイドに書いてある内容は省きます。

## ネットワーク
bridgeを作成します。
今回は、systemd-networkdを用いてインターフェイスの設定を行います。
詳細はArchWikiを参照。([systemd-networkd](https://wiki.archlinux.jp/index.php/Systemd-networkd))

### 物理インターフェイスをbr0(ブリッジインターフェイス)に関連付け

```:/etc/systemd/network/20-wired.network
[Match]
Name=enp0s31f6 # 手元の環境に合わせて読み替えてください

[Network]
Bridge=br0
```
### ブリッジインターフェイスを作成

```:/etc/systemd/network/30-bridge.netdev
[NetDev]
Name=br0
Kind=bridge
```
### ブリッジインターフェイスの設定

```:/etc/systemd/network/30-bridge.network
[Match]
Name=br0

[Network]
Address=192.168.3.103/24
Gateway=192.168.3.1
DNS=192.168.3.1
```
設定ファイルを作成後、systemd-networkdを再起動。

```:systemctl
systemctl restart systemd-networkd
```

## ゲストマシンの作成
ホスト側の用意が完了したので、ゲストマシンの作成を行います。
今回はlibvirtを使用し、KVMで2台仮想マシンを用意します。
こちらもArchWikiを参照。([libvirt](https://wiki.archlinux.org/index.php/Libvirt))

### QEMUイメージ作成
容量は割と雑に決めたので、後で痛い目を見る可能性あり。

```:qemu-img
qemu-img create -f qcow2 /var/lib/libvirt/images/arch-cn.qcow2 64G
qemu-img create -f qcow2 /var/lib/libvirt/images/arch-wn.qcow2 64G
```

### VM作成
スペックは割と雑に決めたのｄ(ry
コンソール周りでつまずいたので、参考になるリンクを貼っておきます。([シリアルコンソールを使って Arch Linux をインストール](https://wiki.archlinux.jp/index.php/%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%AB%E3%82%B3%E3%83%B3%E3%82%BD%E3%83%BC%E3%83%AB#.E3.82.B7.E3.83.AA.E3.82.A2.E3.83.AB.E3.82.B3.E3.83.B3.E3.82.BD.E3.83.BC.E3.83.AB.E3.82.92.E4.BD.BF.E3.81.A3.E3.81.A6_Arch_Linux_.E3.82.92.E3.82.A4.E3.83.B3.E3.82.B9.E3.83.88.E3.83.BC.E3.83.AB))

```:master-node
❯ sudo virt-install \
--name arch-mn01 \
--memory 4096 \
--vcpus 2 \
--cpu host \
--os-variant archlinux \
--network bridge=br0 \
--graphics none \
--arch=x86_64 \
--disk /var/lib/libvirt/images/arch-mn.qcow2 \
--cdrom /var/lib/libvirt/iso/arch.iso \
--virt-type kvm
```

```:worker-node
❯ sudo virt-install \
--name arch-wn01 \
--memory 4096 \
--vcpus 2 \
--cpu host \
--os-variant archlinux \
--network bridge=br0 \
--graphics none \
--arch=x86_64 \
--disk /var/lib/libvirt/images/arch-wn.qcow2 \
--cdrom /var/lib/libvirt/iso/arch.iso \
--virt-type kvm
```

### つまずきのメモ
上にも書きましたがコンソールでつまずきました。

```
# virt-install実行後すぐTABキーを押し末尾にconsole=ttyS0をつけることで解消
>.linux /arch/boot/x86_64/vmlinuz-linux･archisobasedir=arch archisolabel=ARCH_202012 initrd=/arch/boot/intel-ucode.img,/arch/boot/amd-ucode.img,/arch/boot/x86_64/initramfs-linux.img console=ttyS0
```
また、再起動後も同様にコンソールが出てこず、virsh consoleの画面で入力ができませんでした。
対処として参考になったリンクを記載しておきます。

([起動時のデフォルトターゲットを変更する](https://wiki.archlinux.jp/index.php/Systemd#.E8.B5.B7.E5.8B.95.E6.99.82.E3.81.AE.E3.83.87.E3.83.95.E3.82.A9.E3.83.AB.E3.83.88.E3.82.BF.E3.83.BC.E3.82.B2.E3.83.83.E3.83.88.E3.82.92.E5.A4.89.E6.9B.B4.E3.81.99.E3.82.8B))
([gettyを起動したらどうか？](https://bbs.archlinux.org/viewtopic.php?pid=1842211#p1842211))

```:/etc/default/grub
:
GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3"
GRUB_CMDLINE_LINUX="console=tty0 console=ttyS0"
:
# Uncomment to use basic console
GRUB_TERMINAL_INPUT="serial console"

# Uncomment to disable graphical terminal
GRUB_TERMINAL_OUTPUT="serial console"
```

```
[root@archiso /]# systemctl set-default multi-user.target
[root@archiso /]# systemctl enable getty@tty0
[root@archiso /]# systemctl enable getty@ttyS0
```

## Kubernetesクラスタの構築
ここまででやっとVMが作成できたので、ここからKubernetesを導入します。

### kubeadm, kubelet, kubectlの導入
```:kube~導入
# master, workerの両方で実施
[root@arch-mn01 ~]# pacman -S kubeadm kubelet kubectl

[root@arch-wn01 ~]# pacman -S kubeadm kubelet kubectl
```

### dockerの開始
```:systemctl
# master, workerの両方で実施
[root@arch-mn01 ~]# systemctl enable docker; systemctl start docker

[root@arch-wn01 ~]# systemctl enable docker; systemctl start docker
```

### kubeadmの実行
Master側のNodeでkubeadm initを実行します。
今回はCNIにCalico使用するので以下のコマンドになります。

```:kubeadm
kubeadm init --apiserver-advertise-address=192.168.3.181 --pod-network-cidr=192.168.0.0/16
:
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
```

おそらくversion周りでWARNINGが出ています。が、今回は無視します。

Worker側のNodeでkubeadm joinします。(tokenや鍵はinitの出力を参考する)

```:kubeadm
kubeadm join 192.168.3.181:6443 --token xxxx.xxxxxxx     --discovery-token-ca-cert-hash sha256:~~~
```

この時点でkubectl get nodesに2台表示されます。
ただ、ネットワークの設定をしていないため、STATUSはNotReadyになっています。

### Calicoの導入
公式の手順を参考にします。([Quickstart for Calico on Kubernetes](https://docs.projectcalico.org/getting-started/kubernetes/quickstart))

```:apply
kubectl apply -f https://docs.projectcalico.org/manifests/tigera-operator.yaml
kubectl apply -f https://docs.projectcalico.org/manifests/custom-resources.yaml
```

calico-system上に色々立ち上がるので、podがRunningになるのを待ちます。

```:watch
watch kubectl get pods -n calico-system
```
ここでつまずきました。
watchで見ていても、calico-kube-controllersがrunningになりませんでした。

以下、私の対処法になります。

```:journalctl
journalctl -xeu kubelet
:
  }: failed to find plugin "calico" in path [/etc/lib/cni]
:
```

どうやらそんなものないよと言われています。
確認すると/opt/bin/cni/の下にcalico, calico-ipamがありました。
これらをcpコマンドで/etc/lib/cni配下にコピーしたところ、事象が解消。

```:calico-system
[root@arch-mn01 ~]# kubectl get pods -n calico-system
NAME                                      READY   STATUS    RESTARTS   AGE
calico-kube-controllers-56689cf96-mmzb6   1/1     Running   0          10h
calico-node-bjv52                         1/1     Running   0          10h
calico-node-f7w8m                         1/1     Running   0          10h
calico-typha-76bb6bd8df-cs6l2             1/1     Running   0          10h
calico-typha-76bb6bd8df-kr4dn             1/1     Running   0          10h
```

```nodes
[root@arch-mn01 ~]# kubectl get nodes
NAME        STATUS   ROLES    AGE   VERSION
arch-mn01   Ready    master   11h   v1.19.4
arch-wn01   Ready    <none>   11h   v1.19.4
```

これにてクラスタ構築完了です。

# 感想
virt-installでかなり時間を取られ、consoleの設定にたどり着くのに1日かかったのが一番疲れました。
以前、CentOSで構築したときとは違う気づきもあり楽しかったです。
記事内では省いた手順についても時間があれば追記したいなと考えています。

今後は実際に組んだクラスタ上で色々pod立ち上げたり遊び倒したいと思います。