Ubuntu Server 22.04にKubernetes環境を構築する

# 目的
- Ubuntu Server 22.04にKubernetes環境を構築する
- 勉強のためにdockerのインストールに[便利スクリプト](https://get.docker.com)は使わない
- 知識の共有というよりは自分用のメモ

# 前提
- Ubuntu Server 22.04は必要最低限の構成でインストール済み
- ノード名は`ubuntu-k8s-master`


# 手順
## Dockerのインストール
### リポジトリの追加の事前準備
```
$ sudo apt update
$ sudo apt install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
```

### リポジトリのGPGキーを追加
```
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
```

### リポジトリの追加    
```
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
```

### Docker CEのインストール
Docker CEのCEはCommunity Editionの略で無償版。
対するのは有償版のDocker EEとなりEnterprise Editionの略。
```
$ sudo apt update
$ sudo apt install -y docker-ce docker-compose-plugin
$ docker --version
Docker version 20.10.16, build aa7e414
```

### ユーザをdockerグループに追加
```
$ sudo usermod -aG docker $USER
```

## kubernetes（kubeadm / kubelet / kubectl）のインストール

### GPGキーの追加
```
$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
```

### リポジトリの追加
```
$ sudo apt-add-repository "deb http://apt.kubernetes.io/ kubernetes-xenial main"
```

### kubeadm / kubelet / kubectlのインストール
```
$ sudo apt update
$ sudo apt install -y kubeadm kubelet kubectl
```

### swapを無効にする
kubernetes（kubeadm）の[インストール要件](https://kubernetes.io/ja/docs/setup/production-environment/tools/kubeadm/install-kubeadm/)として以下がある。
> - 次のいずれかが動作しているマシンが必要です
>   - Ubuntu 16.04+
>   - Debian 9+
>   - CentOS 7
>   - Red Hat Enterprise Linux (RHEL) 7
>   - Fedora 25+
>   - HypriotOS v1.0.1+
>   - Container Linux (tested with 1800.6.0)
> - 1台あたり2GB以上のメモリ(2GBの場合、アプリ用のスペースはほとんどありません)
> - 2コア以上のCPU
> - クラスター内のすべてのマシン間で通信可能なネットワーク(パブリックネットワークでもプライベートネットワークでも構いません)
> - ユニークなhostname、MACアドレス、とproduct_uuidが各ノードに必要です。詳細はここを参照してください。
> - マシン内の特定のポートが開いていること。詳細はここを参照してください。
> - Swapがオフであること。kubeletが正常に動作するためにはswapは必ずオフでなければなりません。

```
$ sudo swapoff -a
$ sudo cp -p /etc/fstab /etc/fstab_`date +%Y%m%d`
$ sudo vi /etc/fstab
```

`/swap.img     none    swap    sw      0       0`の行をコメントアウト

```
$ diff /etc/fstab /etc/fstab_`date +%Y%m%d`
12c12
< #/swap.img    none    swap    sw      0       0
---
> /swap.img     none    swap    sw      0       0
```

不要なswapファイルを削除
```
sudo rm /swap.img
```

## kubernetesのセットアップ
### containerd.ioの設定ファイルがバグっている（？）ので対応
```
$ sudo mv /etc/containerd/config.toml /etc/containerd/config.toml_`date +%Y%m%d`
$ sudo systemctl restart containerd
```

### 環境の初期セットアップ
```
$ sudo kubeadm init --pod-network-cidr=10.244.0.0/16
```
以下のメッセージが表示されれば初期セットアップ成功
```
Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

Alternatively, if you are the root user, you can run:

  export KUBECONFIG=/etc/kubernetes/admin.conf

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.1.232:6443 --token glcqkv.xyux2epb4nyk15m9 \
        --discovery-token-ca-cert-hash sha256:ba3549aebfb746098663f362c77d12f9cbf56d4126a4c4d8e1636326082162ca
```

### kubernetes clusterを一般ユーザで使うための設定
```
$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config
```

### kubernetesのネットワークプラグイン（flannel）のインストール
```
$ sudo sysctl net.bridge.bridge-nf-call-iptables=1
$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
```

### ノードの準備完了を確認
```
$ kubectl get nodes
```
以下のメッセージのようにSTATUSがReadyになれば準備完了（環境に依ると思われるが2分強かかる）
```
NAME                STATUS   ROLES           AGE     VERSION
ubuntu-k8s-master   Ready    control-plane   2m27s   v1.24.0
```

### ポッドの起動確認
```
kubectl get pods -A
```
以下のようにポッドが表示されればOK
```
NAMESPACE     NAME                                        READY   STATUS    RESTARTS   AGE
kube-system   coredns-6d4b75cb6d-b945m                    1/1     Running   0          3m40s
kube-system   coredns-6d4b75cb6d-tx77z                    1/1     Running   0          3m40s
kube-system   etcd-ubuntu-k8s-master                      1/1     Running   0          3m53s
kube-system   kube-apiserver-ubuntu-k8s-master            1/1     Running   0          3m53s
kube-system   kube-controller-manager-ubuntu-k8s-master   1/1     Running   0          3m53s
kube-system   kube-flannel-ds-rjtfp                       1/1     Running   0          2m25s
kube-system   kube-proxy-t78jq                            1/1     Running   0          3m41s
kube-system   kube-scheduler-ubuntu-k8s-master            1/1     Running   0          3m53s
```


# 今後の予定
- metrics serverを追加する
- prometheusを追加する
- クラスターにノードを追加する
- zabbixを動作させる