EC2(Amazon Linux 2023)にkubeadmでkubernetesクラスターを構築してみる(worker node編)

[EC2(Amazon Linux 2023)にkubeadmでkubernetesクラスターを構築してみる(master node編)](https://qiita.com/Yoyo-kikuchi/items/865163f0489b66a8a859)でcontrol planeが稼働するmaster nodeを作成したので、今回はアプリケーションを稼働させるworker nodeを作成しkubernetesクラスターに追加させ、nginxのpodをdeployして動作確認までしていきます。

※ master node編と重複する工程がありますが、この記事だけ閲覧した方向けにコマンドを再度記載させていただきます。(各工程の詳細説明は省略させてもらいますが。)

## 構築手順
1. containerdのインストール
1. runCの設定
1. CNIの設定
1. cgroupの設定
1. カーネルパラメータの設定(br_netfilterの有効化・iptablesの設定変更)
1. swapの無効化
1. kubelet／kubeadm／kubectlのインストール
1. tcコマンドのインストール
1. kubernetesクラスタへのWorker Nodeの追加
1. nginx podのdeploy

### 1. containerdのインストール
```bash
$ CONTAINERD_VERSION=1.7.11
$ wget -P /usr/local/src https://github.com/containerd/containerd/releases/download/v${CONTAINERD_VERSION}/containerd-${CONTAINERD_VERSION}-linux-amd64.tar.gz
$ tar -C /usr/local -xf /usr/local/src/containerd-${CONTAINERD_VERSION}-linux-amd64.tar.gz
$ wget -P /etc/systemd/system https://raw.githubusercontent.com/containerd/containerd/main/containerd.service
$ systemctl daemon-reload
$ systemctl enable --now containerd
```

### 2. runCの設定

```bash
$ RUNC_VERSION=1.1.10
$ wget -O /usr/local/sbin/runc https://github.com/opencontainers/runc/releases/download/v${RUNC_VERSION}/runc.amd64
$ chmod +x /usr/local/sbin/runc
```

### 3. CNIの設定

```bash
$ CNI_VERSION=1.4.0
$ wget -P /usr/local/src https://github.com/containernetworking/plugins/releases/download/v${CNI_VERSION}/cni-plugins-linux-amd64-v${CNI_VERSION}.tgz
$ mkdir -p /opt/cni/bin
$ tar -C /opt/cni/bin -xf /usr/local/src/cni-plugins-linux-amd64-v${CNI_VERSION}.tgz
```

### 4. cgroupの設定
```bash
$ mkdir /etc/containerd
$ containerd config default | sudo tee /etc/containerd/config.toml > /dev/null
$ cp -p /etc/containerd/config.toml /etc/containerd/config.toml_`date +%Y%m%d`
$ sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
$ diff /etc/containerd/config.toml /etc/containerd/config.toml_`date +%Y%m%d`
$ systemctl restart containerd
```

### 5. カーネルパラメータの設定(br_netfilterの有効化・iptablesの設定変更)
```bash
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

modprobe overlay
modprobe br_netfilter

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

sysctl --system
```

### 6. swapの無効化
[公式ドキュメント](https://v1-25.docs.kubernetes.io/ja/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#%E5%A7%8B%E3%82%81%E3%82%8B%E5%89%8D%E3%81%AB)に以下のように記載されている為OFFにします
> kubeletが正常に動作するためにはswapは必ずオフでなければなりません。

```bash
# スワップの使用状況をデバイスごとに表示する
$ swapon -s
# スワップを無効にする
$ swapoff -a
```

### 7. kubelet／kubeadm／kubectlのインストール

```bash
$ cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.27/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.27/rpm/repodata/repomd.xml.key
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
EOF

$ yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
$ systemctl enable --now kubelet
```

### 8. tcコマンドのインストール

```bash
dnf provides tc
dnf install iproute-tc
```

### 9. kubernetesクラスタへのWorker Nodeの追加
master node編で`kubeadm init`をした際にメモした情報を使います。 

```bash
$ kubeadm join <master nodeのIPアドレス>:6443 --token xxxxxx.xxxxxxxxxxxxxxxx --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# This node has joined the cluster:と表示されら成功です
```

- master nodeから`kubectl get nodes`を実行してworker nodeが存在するかを確認
```bash
$ kubectl get nodes
NAME            STATUS   ROLES           AGE   VERSION
master-node     Ready    control-plane   46m   v1.27.8
worker-node01   Ready    <none>          20s   v1.27.8
```

### 10. nginx podのdeploy
以下の内容を`nginx.yaml`を作成し記載します。

```yaml
apiVersion: v1
kind: Namespace
metadata:
  name: nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploymenti
  namespace: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-servicei
  namespace: nginx
  labels:
    app: nginx
spec:
  type: NodePort
  ports:
  - port: 8080
    targetPort: 80
    nodePort: 30080
    protocol: TCP
  selector:
    app: nginx
```
※ deplymentとserviceのapi versionは`kubectl api-resources | grep Service`, `kubectl api-resources | grep Deployment`で適時確認して下さい。

- マニフェストをApplyする

```bash
$ kubectl apply -f nginx.yaml
```
- podがworker nodeで稼働しているのを確認する
```bash
$ kubectl get pods -o wide -n nginx
NAME                                READY   STATUS    RESTARTS   AGE     IP           NODE            NOMINATED NODE   READINESS GATES
nginx-deploymenti-cbdccf466-4fwb4   1/1     Running   0          4m54s   10.244.1.3   worker-node01   <none>           <none>
nginx-deploymenti-cbdccf466-5pxrw   1/1     Running   0          4m54s   10.244.1.2   worker-node01   <none>           <none>
```

#### ALBを作成してnginxの動作を確認する
worker nodeはprivate-subnetに構築したのでALBを構築してインターネットからアクセスします。

- target groupの作成
serviceでnodePortは`30080`を指定しているのでTarget-groupのプロトコルポートは`30080`を指定します。
![Screen Shot 2023-12-15 at 22.05.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96623/b2a26f1d-40e3-fafc-10b5-4781bb6a4823.png)

- ALBの作成
検証なのでHTTPのみで作成したTarget-Groupにルーティングします。

![Screen Shot 2023-12-15 at 22.16.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96623/25409b10-5686-6bed-24d6-4bb5ae2c6278.png)

- ブラウザーからアクセスしてnginxの画面が表示されるかを確認
ALBの詳細Tabにある**DNS名**をブラウザーに貼り付けて以下の画面が表示されたら成功です。

![Screen Shot 2023-12-15 at 22.04.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96623/fd9fcf48-3586-d68c-840a-f71e0a616d66.png)

## 終わりに
master node編とworker node編の2回に分けてkubeadmでkubernetesクラスターを作成していきました。
次回はクラスターversion upを記事にできたらと思います。