kubeadmでAmazon Linux2にKubernetes1.18

[kubeadmでAmazon Linux2にKubernetes1.17を入れる場合はこちら](https://qiita.com/rururu_kenken/items/2e924eb085fe4bc2edd4)
[kubeadmでAmazon Linux2にKubernetes1.16を入れる場合はこちら](https://qiita.com/rururu_kenken/items/25ce39901c7cf264a839)
[kubeadmでAmazon Linux2にKubernetes1.15を入れる場合はこちら](https://qiita.com/rururu_kenken/items/298b2f09450a2ecc35fb)

**Master Node**

|    EC2　　 |    OS         | Kubernetes | Docker    | ホスト名  |
|:----------:|:-------------:|:----------:|:---------:|:---------:|
| t3.small　| Amazon Linux2  | 1.18.0     |19.03.6-ce |k8s-master|

2CPU、メモリ2GB以下の場合、kubeadm init実行時にエラーになります。
ディスクサイズはデフォルトの8G
Master NodeとWorker Nodeは同じVPC
Master NodeのIPアドレスは172.31.31.214

**Worker Node**

|    EC2　　 |    OS         | Kubernetes | Docker    | ホスト名  |
|:----------:|:-------------:|:----------:|:---------:|:---------:|
| t3.small   | Amazon Linux2 | 1.18.0     |19.03.6-ce |k8s-worker|

ディスクサイズは8G
Master NodeとWorker Nodeは同じVPC
Worker NodeのIPアドレスは172.31.31.203

## SELinux設定確認

```sh
getenforce

# 無効になっている
Disabled
```

## ホスト名の設定

```sh
sudo hostnamectl set-hostname k8s-master
```

## hostファイル編集

```sh
sudo vi /etc/hosts
```

以下の設定を追加

```:/etc/hosts
172.31.31.214 k8s-master
172.31.31.203 k8s-worker
```

## swap確認

```sh
free

# ないので何もしない。ある場合は「swapoff -a」
              total        used        free      shared  buff/cache   available
Mem:        2002032       71720     1567924         384      362388     1786060
Swap:             0           0           0
```

## Dockerインストール・設定

```sh
sudo yum install -y docker

# dockerサービス起動 / 自動起動有効化
sudo systemctl start docker && sudo systemctl enable docker

sudo docker info | grep -i version

# 実行結果
 Server Version: 19.03.6-ce
 containerd version: ff48f57fc83a8c44cf4ad5d672424a98ba37ded6
 runc version: dc9208a3303feef5b3839f4323d9beb36df0a9dd
 init version: fec3683
 Kernel Version: 4.14.171-136.231.amzn2.x86_64

# ログインしているユーザーをdockerグループに追加
sudo usermod -a -G docker $USER

# 確認コマンド
cat /etc/group | grep docker

# 実行結果
docker:x:993:ec2-user

# ログアウトして、すぐに再ログイン
exit

# cgroupdriverをsystemdに設定など
sudo tee /etc/docker/daemon.json <<EOF
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2",
  "storage-opts": [
    "overlay2.override_kernel_check=true"
  ]
}
EOF

sudo mkdir -p /etc/systemd/system/docker.service.d
sudo systemctl daemon-reload
sudo systemctl restart docker

# 設定確認
docker info | grep -i driver

# 実行結果
 Storage Driver: overlay2
 Logging Driver: json-file
 Cgroup Driver: systemd
```
## その他の設定

```sh
# sysctlでネットワークをブリッジできるようする
sudo tee /etc/sysctl.d/k8s.conf <<EOF
net.bridge.bridge-nf-call-iptables  = 1
net.ipv4.ip_forward                 = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF

# カーネルパラメータを手動で反映
sudo sysctl --system
```

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

「repo_gpgcheck=1」は「repo_gpgcheck=0」にする
[Got "repomd.xml signature could not be verified for kubernetes" error when installing Kubernetes from yum repo on Amazon Linux 2 #60134](https://github.com/kubernetes/kubernetes/issues/60134)

```sh
sudo sh -c "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=0
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF
"

sudo yum install -y kubelet-1.18.0-0.x86_64 kubeadm-1.18.0-0.x86_64 kubectl-1.18.0-0.x86_64 --disableexcludes=kubernetes
```

## kubelet 起動

```sh
sudo systemctl enable kubelet && sudo systemctl start kubelet
```

## Master の初期化

```sh
# WARNING でるのでtcインストール
# [preflight] Running pre-flight checks
#	[WARNING FileExisting-tc]: tc not found in system path
sudo yum install -y tc

# Calicoを使うので「--pod-network-cidr 192.168.0.0/16」を指定
sudo kubeadm init --pod-network-cidr 192.168.0.0/16 
```

トークンには有効期限があり、通常は24時間で利用できなくなる。
トークンが失効した場合や分からなくなった場合、マスターノードで「kubeadm token create --print-join-command」コマンドを実行するとトークンが再生成されて表示される。

## kubectl 接続設定

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

```sh
kubectl get cs

# 実行結果
NAME                 STATUS    MESSAGE             ERROR
scheduler            Healthy   ok                  
controller-manager   Healthy   ok                  
etcd-0               Healthy   {"health":"true"} 

kubectl get pod -A

# 実行結果
NAMESPACE     NAME                                 READY   STATUS    RESTARTS   AGE
kube-system   coredns-66bff467f8-9v26n             0/1     Pending   0          102s
kube-system   coredns-66bff467f8-tf8vz             0/1     Pending   0          102s
kube-system   etcd-k8s-master                      1/1     Running   0          118s
kube-system   kube-apiserver-k8s-master            1/1     Running   0          118s
kube-system   kube-controller-manager-k8s-master   1/1     Running   0          118s
kube-system   kube-proxy-w764p                     1/1     Running   0          102s
kube-system   kube-scheduler-k8s-master            1/1     Running   0          118s
```

## Calico

```sh
kubectl apply -f https://docs.projectcalico.org/v3.13/manifests/calico.yaml

kubectl get pod -A

# 実行結果
NAMESPACE     NAME                                       READY   STATUS    RESTARTS   AGE
kube-system   calico-kube-controllers-5b8b769fcd-b5w75   1/1     Running   0          40s
kube-system   calico-node-7x8x8                          1/1     Running   0          40s
kube-system   coredns-66bff467f8-9v26n                   1/1     Running   0          2m53s
kube-system   coredns-66bff467f8-tf8vz                   1/1     Running   0          2m53s
kube-system   etcd-k8s-master                            1/1     Running   0          3m9s
kube-system   kube-apiserver-k8s-master                  1/1     Running   0          3m9s
kube-system   kube-controller-manager-k8s-master         1/1     Running   0          3m9s
kube-system   kube-proxy-w764p                           1/1     Running   0          2m53s
kube-system   kube-scheduler-k8s-master                  1/1     Running   0          3m9s
```

```sh
kubectl get node

# 実行結果
NAME         STATUS   ROLES    AGE     VERSION
k8s-master   Ready    master   3m53s   v1.18.0
```

# Worker Node

## 以下はMaster Nodeの手順を参照

SELinux設定確認
ホスト名の設定・・・sudo hostnamectl set-hostname k8s-worker
hostファイル編集
swap確認
Dockerインストール・設定
その他設定
kubelet、kubeadm、kubectlインストール
kubelet 起動

## クラスタに参加

```sh
# WARNING でるのでtcインストール
sudo yum install -y tc

# 「kubeadm token create --print-join-command」はMaster Nodeで実行
kubeadm token create --print-join-command

# 長いので「・・・」で省略
sudo kubeadm join マスターノードのIPアドレス:6443 --token ・・・
```

トークンには有効期限があり、通常は24時間で利用できなくなる。
トークンが失効した場合や分からなくなった場合、マスターノードで「kubeadm token create --print-join-command」コマンドを実行するとトークンが再生成されて表示される。

# Master Node

## kubectl コマンドで Node と Pod の状態を確認

```sh
kubectl get node

# 実行結果
NAME         STATUS   ROLES    AGE   VERSION
k8s-master   Ready    master   32m   v1.18.0
k8s-worker   Ready    <none>   21s   v1.18.0
```

## Redisデプロイ・動作確認

```sh
vi redis.yaml
```

```redis.yaml
apiVersion: v1
kind: Service
metadata:
  name: redis-svc
spec:
  ports:
    - port: 6379
      targetPort: 6379
  selector:
    app: redis
  clusterIP: None
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: redis.config
data:
  redis.conf: |
    requirepass password
    bind 0.0.0.0
---
apiVersion: apps/v1
kind: Deployment
metadata:
  # Deploymentの名前。Namespace内ではユニークである必要があります
  name: redis
spec:
  selector:
    matchLabels:
      app: redis
  # レプリカ数の指定
  replicas: 1
  # Podのテンプレート(PodTemplate)
  template:
    metadata:
      labels:
        # ラベル指定は必須
        app: redis
    spec:
      containers:
        - name: redis
          image: redis:5.0.8
          command: 
            - "redis-server"
            - "/redis-master/redis.conf"
          ports:
            - name: redis
              containerPort: 6379
          volumeMounts:
            - name: data
              mountPath: /redis-master-data
            - name: config
              mountPath: /redis-master
      volumes:
        - name: data
          emptyDir: {}
        - name: config
          configMap:
            name: redis.config
```

```shell-session
kubectl apply -f redis.yaml
kubectl run -it redis-cli --rm --image redis:5.0.8 --restart=Never -- bash
If you don't see a command prompt, try pressing enter.
root@redis-cli:/data# redis-cli -c -h redis-svc -p 6379 -a password
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
redis-svc:6379> set a 1
OK
redis-svc:6379> get a
"1"
redis-svc:6379> exit
root@redis-cli:/data# exit
```

## Master 以外のノードに Role 設定

```sh
kubectl label node k8s-worker node-role.kubernetes.io/worker=

kubectl get node

# 実行結果
NAME         STATUS   ROLES    AGE     VERSION
k8s-master   Ready    master   35m     v1.18.0
k8s-worker   Ready    worker   3m51s   v1.18.0
```

## 参考URL

[kubeadmのインストール](https://kubernetes.io/ja/docs/setup/independent/install-kubeadm/)