LightsailのAmazon Linux 2023でシングルノードのKubernetes

また検証で必要になったのでメモ、今回はLightsailのAmazon Linux 2023でやってみようかと。
Amazon Linux苦労するかと思ったが、多分史上最高に簡単だった。食わず嫌い良くないな。

今回試す構成は以下。
・AWS Lightsail、OSはAmazon Linux 2023(Amazon Linux 2023 2023.2.20231113.0)、2 CPUでメモリ2GBの$10のやつ、が1台。メモリ2GB(以上)は必須である。
・コンテナランタイムはcontainerd(v1.7.8)
・kubernetes v1.28をkubeadmで導入
・ネットワークドライバはflannel(v0.23.0)

# 1. コンテナランタイムを導入するまで

Lightsailのssh鍵を入手してsshクライアントで接続するところの手順は割愛。
`putty -i lightsail.ppk ec2-user@13.231.194.245`みたいなコマンドで接続。

OS側の準備はKubernetesの以下のドキュメントを参照しつつ実施する。日本語訳もあるのだが、masterノードとかの用語が生き残っていたりと、かなり古い。Kubernetesも落ち目である。
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/

Amazon Linux 2023良いなと思ったのは、selinuxがデフォルトpermissiveで、firewalldもデフォルトで動いていない点。クラウドだからこそというか、そこに痺れる。メモリスワップ無効化がちょっと面倒くさいが。

OSの準備手順は以下の通り。

```:
$ sudo -i
# dnf remove -y zram-generator-defaults
# swapoff -a
# cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
# sudo modprobe overlay
# sudo 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
# sudo sysctl --system
```

次にコンテナランタイムとしてcontainerdを導入する。
containerdの導入手順は以下URL。
https://github.com/containerd/containerd/blob/main/docs/getting-started.md#getting-started-with-containerd
https://github.com/containerd/containerd/releases
https://github.com/opencontainers/runc/releases
https://github.com/containernetworking/plugins/releases

```:
# wget https://github.com/containerd/containerd/releases/download/v1.7.8/containerd-1.7.8-linux-amd64.tar.gz
# tar Cxzvf /usr/local containerd-1.7.8-linux-amd64.tar.gz
# wget https://raw.githubusercontent.com/containerd/containerd/main/containerd.service
# cp containerd.service /etc/systemd/system/
# systemctl daemon-reload
# systemctl enable --now containerd
# wget https://github.com/opencontainers/runc/releases/download/v1.1.10/runc.amd64
# install -m 755 runc.amd64 /usr/local/sbin/runc
# wget https://github.com/containernetworking/plugins/releases/download/v1.3.0/cni-plugins-linux-amd64-v1.3.0.tgz
# mkdir -p /opt/cni/bin
# tar Cxzvf /opt/cni/bin cni-plugins-linux-amd64-v1.3.0.tgz
```

containerdを導入したら、cgroupドライバーを修正する。ここのドキュメントが弱く「config.tomlファイル無いやんけ何やねん」となるが、これは`containerd config default`で生成するものである。
https://kubernetes.io/docs/setup/production-environment/container-runtimes/#containerd

```:
# mkdir /etc/containerd
# containerd config default > /etc/containerd/config.toml
# sed -i /etc/containerd/config.toml -e "s/SystemdCgroup = false/SystemdCgroup = true/"
# systemctl restart containerd
```

# Kubernetesを導入するまで

containerdまで導入したら、kubeadm等をインストールして、Kubernetesクラスターを作る。
なおAmazon LinuxはRed Hat-based distributionsに該当し、yumコマンドを使う。
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/

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

kubeletが起動したら、kubeadm initを実行する。Lightsailの内部IPアドレスが172.～なので、Kubernetes側の内部IPアドレスは192.168.0.0/16にする。tcコマンドが無いと警告が出るが、特に気にする必要は無い。今回Workerノードを用意しないので要らないのだが、用意する場合は出力最後の`kubeadm join～`を手元に取っておく。

```:
# kubeadm init --pod-network-cidr=192.168.0.0/16
(出力結果)
Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 172.26.15.202:6443 --token t0roiz.klgeb1t2eio494up \
        --discovery-token-ca-cert-hash sha256:3579401727d150598adeba7a333c9111479a688f00cad589a40a9c5d1c7f4cb2
```

KUBECONFIGを設定し、CPノードでのユーザーPod実行を許可し、coredns以外のPodが起動してくるのを待つ。

```:
# export KUBECONFIG=/etc/kubernetes/admin.conf
# kubectl taint nodes --all node-role.kubernetes.io/control-plane-
# kubectl get pod -A
(以下のようにPodが起動してくるのを待つ)
[root@ip-172-26-15-202 ~]# kubectl get pod -A
NAMESPACE     NAME                                                                       READY   STATUS    RESTARTS   AGE
kube-system   coredns-5dd5756b68-bxmn6               0/1     Pending   0          12m
kube-system   coredns-5dd5756b68-kngv7               0/1     Pending   0          12m
kube-system   etcd-ip-172-26-15-202.ap...            1/1     Running   0          13m
kube-system   kube-apiserver-ip-172-26...            1/1     Running   0          13m
kube-system   kube-controller-manager-...            1/1     Running   0          13m
kube-system   kube-proxy-8968n                       1/1     Running   0          12m
kube-system   kube-scheduler-ip-172-26...            1/1     Running   0          13m
```

起動したら、ネットワークドライバ（今回はflannel）を導入する。念のため、flannelのバージョンはlatestではなく0.23.0。導入後、flannelとcorednsが起動するのを確認する。
https://github.com/flannel-io/flannel#deploying-flannel-manually
https://github.com/flannel-io/flannel/releases

```:
# wget https://github.com/flannel-io/flannel/releases/download/v0.23.0/kube-flannel.yml
# sed -i kube-flannel.yml -e "s/10.244.0.0/192.168.0.0/"
# kubectl create -f kube-flannel.yml
# kubectl get pod -A
(以下のようにPodが起動するのを確認)
[root@ip-172-26-15-202 ~]# kubectl get pod -A
NAMESPACE      NAME                                                                       READY   STATUS    RESTARTS   AGE
kube-flannel   kube-flannel-ds-lt2jl                1/1     Running   0          25s
kube-system    coredns-5dd5756b68-bxmn6             1/1     Running   0          25m
kube-system    coredns-5dd5756b68-kngv7             1/1     Running   0          25m
kube-system    etcd-ip-172-26-15-202.ap...          1/1     Running   0          25m
kube-system    kube-apiserver-ip-172-26...          1/1     Running   0          25m
kube-system    kube-controller-manager-...          1/1     Running   0          25m
kube-system    kube-proxy-8968n                     1/1     Running   0          25m
kube-system    kube-scheduler-ip-172-26...          1/1     Running   0          25m
```

以上、なのだが、この後Podを起動してNodePort経由でサービス接続して、とやりたい場合はLightsailの「ネットワーキング」>「IPv4 ファイヤウォール」とかを直す必要がある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146381/75befc55-2575-3c77-eaba-80923607c4e6.png)

また、今回ネットワークドライバがFlannelだが、NetworkPolicyが必要でCalicoを使うならファイアウォールでIPIP通信を許可する必要がありそうだ。
https://qiita.com/syo0901/items/f9e5dfeba05679712458

# その他
今回検証したいのは別のことなので良いのだが、Amazon Linux 2023の、今回使用したバージョンのLinux Kernelは6.1。User Namespacesの検証には6.3が必要なので足りない。6.3と言えば、先日構築したFedora 38がLinux Kernel 6.3だった。
https://kubernetes.io/blog/2023/09/13/userns-alpha/#node-system-requirements

以下はAmazon Linux 2023での`uname -r`実行結果。

```:
[root@ip-172-26-15-202 ~]# uname -r
6.1.61-85.141.amzn2023.x86_64
```