オンプレミスにkubernetes(v1.16.3)を構築してみた！

# 記事の内容
kubernetes1.16.3をオンプレミスにどのように構築したらいいのかをまとめた。
公式ドキュメントを参照しながら作業を実施したが、ハマりポイントがいくつもあった為、まとめておく。
ちなみに私はこの資料をまとめるまでに２つの環境を構築した。

# 結論
私も色々なサイトを参考にセットアップを行ったが、うまくいかず、結局は、以下のkubernetes公式サイトのインストール手順を参考にすることが、良いということがわかった。
[公式サイト-kubeadmのインストール](https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/)

# 注意ポイント
docker及びkubeletにてCgroup Driverがsystemdとなっていることを注意する
systemdとなっていないとkubernetesの動作が不安定となる

# 今回の環境
- VMware Player 上に　OS Centos 7.6 x 3台(仮想OS)
- 仮想OSのコア数は２以上（kubeadmのインストールでエラーになります）
- メモリは2GB以上
- filesystemはext4

# 手順
## ベースセットアップ
### selinuxを無効化する
[CentOS7 SELinuxの無効化手順](https://qiita.com/mattsun/items/470581ff34f87c7eb21d)

### swapの無効化する
以下の行をコメントアウトして再起動する

```text:/etc/fstab
#/dev/mapper/centos_kbmaster-swap swap                    swap    defaults        0 0 
```

swapが0になっていればOK

```
$ free 
              total        used        free      shared  buff/cache   available
Mem:        1870516      101396     1508780        8684      260340     1609780
Swap:             0           0           0
```

### hostsファイルの編集
kbmaster,node1,node2のホストを登録する
ipv6の::1 はコメントアウトする

```text:/etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
#::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.111.200 kbmaster
192.168.111.201 node1
192.168.111.202 node2                  
```

### モジュールをアップデート
```
# yum update
```

### ファイアウォールサービスの停止
```
# systemctl stop firewalld;systemctl disable firewalld
```

### MACアドレスがすべてのノードで一意であることを確認する
```
# ip link
```
### product_uuidがすべてのノードで一意であることを確認する
```
# cat /sys/class/dmi/id/product_uuid
```

### iptablesツールがnftablesバックエンドを使用しないようにする
```console 
# update-alternatives --set iptables /usr/sbin/iptables-legacy
```


## dockerをインストール
dockerのインストールを行うversionはkubernetes推奨の18.06.2とする
dockerのインストールは[こちら](https://qiita.com/ButtonPJ/items/e19df03e6467d11d1ac2)を参考にしてください。

### daemonのセットアップ
```
# cat > /etc/docker/daemon.json <<EOF
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay"
}
EOF
# mkdir -p /etc/systemd/system/docker.service.d
```

### docker再起動
```
systemctl daemon-reload
systemctl restart docker
```

### docker infoの確認
Storage Driverが`overlay`
Cgroup Driverが`systemd`
となっていることを以下のコマンドで確認します。

```
$ sudo docker info
Storage Driver: overlay
Cgroup Driver: systemd
```

### kubelet kubeadm kubectlのインストール

```
# cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
exclude=kube*
EOF
```

```
# yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
```

```
# cat <<EOF >  /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
# sysctl --system
```

```
# systemctl enable kubelet
# systemctl start kubelet
```

### kubernetes環境を初期化（マスタのみ実行）
```
# kubeadm init --kubernetes-version=1.16.3 --pod-network-cidr=172.17.0.0/16
```

初期化が成功すると、Nodeにしたいサーバ上で実行するコマンドが表示される
このコマンドを実行するとkubernetesのノードとして認識される

```text
kubeadm join 192.168.111.200:6443 --token XXXXXXXXXXXXXXXXXXXXXXXXXX \
    --discovery-token-ca-cert-hash sha256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
```

### Node構築（ノードのみ実行）
``` 
# kubeadm join 192.168.111.200:6443 --token XXXXXXXXXXXXXXXXXXXXXXXXXX \
    --discovery-token-ca-cert-hash sha256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
[preflight] Running pre-flight checks
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'
[kubelet-start] Downloading configuration for the kubelet from the "kubelet-config-1.15" ConfigMap in the kube-system namespace
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Activating the kubelet service
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...

This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.

Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
```

## kubernetes管理ユーザ（一般）の作成
```
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
```

## kubeletがsystemdで管理されていることを確認する
docker同様にcgroupfsとsystemdをそれぞれ使用するとシステムが不安定となるので対処しておく

# cat /var/lib/kubelet/kubeadm-flags.env
KUBELET_KUBEADM_ARGS="--cgroup-driver=systemd --network-plugin=cni --pod-infra-container-image=k8s.gcr.io/pause:3.1"

## クラスタ内ネットワーク用にFlannelをセットアップ(マスタのみ実行）
```
$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/2140ac876ef134e0ed5af15c65e414cf26827915/Documentation/kube-flannel.yml
```
各ノードのSTATUSが`Ready`になっていることを確認する

```
$ kubectl get nodes
NAME       STATUS   ROLES    AGE   VERSION
kbmaster   Ready    master   90m   v1.16.3
node1      Ready    <none>   68m   v1.16.3
node2      Ready    <none>   65m   v1.16.3
```
# 参考にしたサイト
[公式サイト-kubeadmのインストール](https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/)

https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/#tear-down
https://docs.docker.com/install/linux/docker-ce/centos/