Amazon EC2上にKubernetes(v1.23.1)を構築

#はじめに
・KaaSを用いずEC2のOS上からKubeadmを用いてスクラッチで構築した。

<img width="600" alt="top" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207381/5673c69e-abd9-36b5-209f-38cb6478130f.png">

####リソース構成
・Master NodeとWorker Nodeは同じVPC内で構築
・ディスクサイズは8G

|名前（hostname）  |役割  |IPアドレス  |
|---|---|---|
|kube-masater |Master Node |192.168.0.57|
|kube-worker1 |Worker Node |192.168.0.42|
|kube-worker2 |Worker Node |192.168.0.13|

####リソースバージョン
・K8sの要件でCPU2コア以上必要なのと[サポートOS](https://kubernetes.io/ja/docs/setup/production-environment/turnkey/aws/#%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88%E3%83%AC%E3%83%99%E3%83%AB)の指定があり以下とした。

|EC2  |OS  |Docker  |K8s  |
|---|---|---|---|
|t3.small |Centos 7.7 |v1.13.1 |v1.23.1 |

[参考:kubeadmのインストール](https://kubernetes.io/ja/docs/setup/production-environment/tools/kubeadm/install-kubeadm/)

####構成図

<img width="600" alt="top" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207381/e2fe7d63-7936-69ec-a201-95cfb6a85bff.png">

#手順
※AWSの手順は割愛

####準備（OS設定）
まずは、K8s導入の準備としてOS初期設定を行う。
OSバージョンを確認。

```bash
# cat /etc/redhat-release 
CentOS Linux release 7.7.1908 (Core)

# uname -r
3.10.0-1062.12.1.el7.x86_64
```

Master NodeのHost設定。

```bash
# hostnamectl set-hostname kube-master
```
hostファイルを修正

```bash
# vi /etc/hosts
192.168.0.57    kube-master
```

Worker　NodeについてもMaster Nodeと同様に実施。
こちらはMaster NodeのHost名も追加。

Worker Node1のHost設定

```bash
# hostnamectl set-hostname kube-node1
# vi /etc/hosts
192.168.0.42    kube-node1
192.168.0.57    kube-master
```

Worker Node2のHost設定

```bash
# hostnamectl set-hostname kube-node2
# vi /etc/hosts
192.168.0.13    kube-node2
192.168.0.57    kube-master
```

SELinuxの確認。
デフォルトで、Permissiveなのでそのままにする。無効化してもOK。

```bash
# getenforce 
Permissive
```

SWAPの確認。
t3.smallにSWAP領域はないので何もしない。ある場合は#swapoff -aで無効化する。

```bash
# free -m
              total        used        free      shared  buff/cache   available
Mem:           1799         656         104           2        1039         970
Swap:             0           0           0
```

####Docker設定
Dockerのインストール。

```bash
# yum install -y docker
```

サービス起動とOS起動時のサービス自動有効化。

```bash
# systemctl start docker && systemctl enable docker
```

Dockerのバージョン確認。

```bash
# docker info | grep -i version
  WARNING: You're not using the default seccomp profile
Server Version: 1.13.1
（以下略）
```

Kubernetes v1.21から、kubeadmの標準のcgroupのdriverがsystemdになったため、設定を確認。

```bash
# docker info | grep -i driver
  WARNING: You're not using the default seccomp profile
Storage Driver: overlay2
Logging Driver: journald
Cgroup Driver: systemd
```

####K8s設定

iptablesのパラメータ編集。
K8sのドキュメントにある通り、iptableでブリッジのトラフィックを表示させる設定を入れる。

```bash
cat <<EOF | tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
```

パラメータの設定反映。

```bash
# sysctl --system
```

K8sのyumレポジトリ登録。

```bash
# cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-\$basearch
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
EOF
```

K8sパッケージ群のインストール。

```bash
# yum -y install kubelet kubeadm kubectl
```

K8sサービスの起動設定。

```bash
# systemctl daemon-reload
# systemctl enable kubelet && systemctl start kubelet
```

バージョン確認。

```bash
# kubectl version
Client Version: version.Info{Major:"1", Minor:"23", GitVersion:"v1.23.1", GitCommit:"86ec240af8cbd1b60bcc4c03c20da9b98005b92e", GitTreeState:"clean", BuildDate:"2021-12-16T11:41:01Z", GoVersion:"go1.17.5", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"23", GitVersion:"v1.23.1", GitCommit:"86ec240af8cbd1b60bcc4c03c20da9b98005b92e", GitTreeState:"clean", BuildDate:"2021-12-16T11:34:54Z", GoVersion:"go1.17.5", Compiler:"gc", Platform:"linux/amd64"}
```

#####Master Node初期構築（kube-master）

今回、仮想ネットワークにflannelを用いる。
仮想ネットワークは「10.244.0.0/16」とし
マスターノードが使用するIPアドレスは「192.168.0.57」を指定する。

※Master Nodeのみ実施

```bash
# kubeadm init \
--pod-network-cidr=10.244.0.0/16 \
--apiserver-advertise-address=192.168.0.57
```

何回かエラーになったが、無事完了（汗

```bash
（略）
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy

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.0.57:6443 --token f85ges.sh7h0k3k4m3r2t9j \
        --discovery-token-ca-cert-hash sha256:95983cbdbe27480d61c7fa61fc1a3222b749fcf090a25f1ff4ff1526b6a861ce 
```

実行結果の案内に従い、クラスターを利用するためにconfigを設定

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

最後のkubeadm joinの内容は、Worker Node追加時に必要なので控えておく

>
kubeadm join 192.168.0.57:6443 --token f85ges.sh7h0k3k4m3r2t9j \
        --discovery-token-ca-cert-hash sha256:95983cbdbe27480d61c7fa61fc1a3222b749fcf090a25f1ff4ff1526b6a861ce 
>

Flannelのネットワークをインストール。

```bash
# kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
```

参考

https://github.com/flannel-io/flannel/blob/master/Documentation/kubernetes.md

Nodeの確認。STATUSがReadyになっていることを確認する。

```bash
# kubectl get nodes
NAME          STATUS   ROLES                  AGE   VERSION
kube-master   Ready    control-plane,master   10m   v1.23.1
```

#####Worker Node初期構築（kube-node1、kube-node2）

・Woker Nodeを追加

```bash
# kubeadm join 192.168.0.57:6443 --token f85ges.sh7h0k3k4m3r2t9j \
        --discovery-token-ca-cert-hash sha256:95983cbdbe27480d61c7fa61fc1a3222b749fcf090a25f1ff4ff1526b6a861ce
```

Nodeの状況確認。
master-nodeで実施。kube-node1,kube-node2が追加され、STATUSがReadyになっていることを確認する。

```bash
# kubectl get node -o wide
NAME          STATUS   ROLES                  AGE   VERSION   INTERNAL-IP    EXTERNAL-IP   OS-IMAGE                KERNEL-VERSION                CONTAINER-RUNTIME
kube-master   Ready    control-plane,master   21m   v1.23.1   192.168.0.57   <none>        CentOS Linux 7 (Core)   3.10.0-1062.12.1.el7.x86_64   docker://1.13.1
kube-node1    Ready    <none>                 21m   v1.23.1   192.168.0.42   <none>        CentOS Linux 7 (Core)   3.10.0-1062.12.1.el7.x86_64   docker://1.13.1
kube-node2    Ready    <none>                 21m   v1.23.1   192.168.0.13   <none>        CentOS Linux 7 (Core)   3.10.0-1062.12.1.el7.x86_64   docker://1.13.1
```


```bash
# kubectl get cs
Warning: v1 ComponentStatus is deprecated in v1.19+
NAME                 STATUS    MESSAGE                         ERROR
scheduler            Healthy   ok                              
etcd-0               Healthy   {"health":"true","reason":""}   
controller-manager   Healthy   ok   
```

クラスターへの接続を確認。

```bash
# kubectl cluster-info
Kubernetes control plane is running at https://192.168.0.57:6443
CoreDNS is running at https://192.168.0.57:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
```

####NameSpace

ここでは、NameSpaceを用いてリソースを隔離する。
まずは、現状の確認。

```bash
# kubectl get namespace
NAME                  STATUS   AGE
default               Active   41m
kube-node-lease       Active   41m
kube-public           Active   41m
kube-system           Active   41m
```

ここでは、NameSpaceにインスタンスIDを設定する。

```bash
# NS='i-02ee9d2a527948664'
# echo $NS
i-02ee9d2a527948664
# kubectl create namespace $NS
```

あらためて、NameSpaceを確認。

```bash
# kubectl get namespace
NAME                  STATUS   AGE
default               Active   41m
i-02ee9d2a527948664   Active   11s
kube-node-lease       Active   41m
kube-public           Active   41m
kube-system           Active   41m
```

コンテクストのNamespaceを設定した＄NSに変更する。

```bash
# kubectl config get-contexts
CURRENT   NAME                          CLUSTER      AUTHINFO           NAMESPACE
*         kubernetes-admin@kubernetes   kubernetes   kubernetes-admin   

# kubectl config set-context --current --namespace=$NS

# kubectl config get-contexts
CURRENT   NAME                          CLUSTER      AUTHINFO           NAMESPACE
*         kubernetes-admin@kubernetes   kubernetes   kubernetes-admin   i-02ee9d2a527948664
```

環境準備はここまで。


参考
https://qiita.com/rawr/items/b4446ef8314109a270ca
https://qiita.com/rururu_kenken/items/0a7434969ff2c28576eb
https://kubernetes.io/ja/docs/setup/production-environment/tools/kubeadm/install-kubeadm/