📝自分用のメモ
コンテナランタイムを選択する
kubeadmでは以下のコンテナランタイムを選択することができる。
- Docker
- containerd
- cri-o
Dockerが手軽そうだが、Docker内蔵のcontainerdをkubeadmが優先的に選択してしまい、かつ、Docker提供のcontainerdではCRIが無効になっていたり*1CNIがインストールされていなかったりするのでものすごくハマる。 おすすめはcri-oで、手順のとおりにインストールすれば全くはまらないので初kubeadmならおすすめ。
おすすめと書きながら今回はブログのネタになると思ったのでcontainerdを選択した。
containerdのインストール
「containerd docker install」とかで検索するとDocker社提供のリポジトリからパッケージをインストールしろっと出てくるが、これは罠である。 前述した通り、Docker内蔵のcontainerdにはkubeadmで使う上では問題がありおすすめしない。 containerdの公式リポジトリにインストール手順が載っているのこれを参考にするとよい。
以下は必要なコマンドのみ抜粋したもの。
CONTAINERD_VERSION=1.7.3 RUNC_VERSION=1.1.8 CNI_VERSION=1.3.0 sudo mkdir -p /usr/local/src sudo wget -P /usr/local/src https://github.com/containerd/containerd/releases/download/v${CONTAINERD_VERSION}/containerd-${CONTAINERD_VERSION}-linux-amd64.tar.gz sudo tar -C /usr/local -xf /usr/local/src/containerd-${CONTAINERD_VERSION}-linux-amd64.tar.gz sudo wget -P /etc/systemd/system https://raw.githubusercontent.com/containerd/containerd/main/containerd.service sudo systemctl daemon-reload sudo systemctl enable --now containerd sudo wget -O /usr/local/sbin/runc https://github.com/opencontainers/runc/releases/download/v${RUNC_VERSION}/runc.amd64 sudo chmod +x /usr/local/sbin/runc sudo wget -P /usr/local/src https://github.com/containernetworking/plugins/releases/download/v${CNI_VERSION}/cni-plugins-linux-amd64-v${CNI_VERSION}.tgz sudo mkdir -p /opt/cni/bin sudo tar -C /opt/cni/bin -xf /usr/local/src/cni-plugins-linux-amd64-v${CNI_VERSION}.tgz
次にsystemdバックエンドなcgroupを有効にする(kubeadmではこれがデフォルトになっているので)。
sudo mkdir /etc/containerd containerd config default | sudo tee /etc/containerd/config.toml > /dev/null sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml sudo systemctl restart containerd
カーネルモジュールの読み込み
以下を参考にコンテナからのネットワークアクセスを許可するためのカーネルパラメータを設定する。
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf overlay br_netfilter EOF sudo modprobe overlay sudo modprobe br_netfilter # sysctl params required by setup, params persist across reboots 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 # Apply sysctl params without reboot sudo sysctl --system
swapの無効化
swapの無効化がkubeletでは奨励されているので変更する。
swapon -s sudo swapoff -a sudo sed -i '/swap/d' /etc/fstab
kubeadmのインストール
ここまでで事前準備ができたのでkubeadmをインストールする。
sudo apt-get update sudo apt-get install -y apt-transport-https ca-certificates curl curl -fsSL https://dl.k8s.io/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-archive-keyring.gpg echo "deb [signed-by=/etc/apt/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list sudo apt-get update sudo apt-get install -y kubelet kubeadm kubectl sudo apt-mark hold kubelet kubeadm kubectl
kubeletのデプロイ
kubeletをデプロイする。 デフォルトでは何もオプションを指定する必要がないが、今回はpodに使用されるネットワークレンジを172.16.0.0/16に変えたいので--pod-network-ciderを指定する*2。
kubeadm init --pod-network-cidr 172.16.0.0/16
コマンドを実行しうまくデプロイされると以下のように表示される。
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 XXXXX:6443 --token YYYYYY \ --discovery-token-ca-cert-hash sha256:ZZZZZ
引き続きCNIのセットアップにkubectlを使う必要があるので、メッセージに従いkubeconfigを設定しておく。
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コマンドをメモしておくとワーカーノードを追加するときに利用できるが、kubectl tokenコマンドで再取得できるのでスルーしてもよい。
Calicoを使用したCNIのセットアップ
kubeletをデプロイしただけでばクラスタとしては動作せずCNIをセットアップしなければならない。 CNIとして選択できるミドルウェアはいくつか存在するがここではCalicoを選択する。 Calicoの手順に従いまずはOperatorをインストールする。
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/tigera-operator.yaml
次にはカスタムリソース定義のマニフェストをダウンロードする。 ダウンロードしたマニフェストをそのまま使うことができるが、今回は前述の手順でpodネットワークを変更しているのでその変更を適用し、kubectlを使いマニフェストを読み込ませる。
curl https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/custom-resources.yaml -O sed -i 's,192.168.0.0/16,172.16.0.0/16,g' custom-resources.yaml kubectl apply -f custom-resources.yaml
calico-systemネームスペースのpodがすべてRunningになればセットアップは完了している。
watch -n1 kubectl get pods -n calico-system
ワーカーノードの追加
ワーカーノードの追加手順は、コントロールプレーンの追加とほとんど同じである。 違いはkubeadm initをするかkubeadm joinするかである。
まずはワーカーノードにkubeadmをインストールする手順まで行う。 kubeadmのインストールが終わったら次にワーカーノードをコントロールプレーンにジョインさせる。 ジョインするためのコマンドはコントロールプレーンでkubeadm initを実行した後に表示されていたので、それを貼り付ければよい。 仮にメモしておかなくても以下のコマンドで再度発行することができる。
$ sudo kubeadm token create --print-join-command kubeadm join XXXXX:6443 --token YYYYY --discovery-token-ca-cert-hash sha256:ZZZZZ
kubeadm join~
の部分をコピーしてワーカーノードに張り付ける。
kubeadm join XXXXX:6443 --token YYYYY --discovery-token-ca-cert-hash sha256:ZZZZZ
正常に完了すると以下のように表示される。
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.
メッセージにあるとおりコントロールプレーンでkubectl get nodesを実行するとワーカーノードが追加されているのがわかる。 追加した直後はNotReadyだが、少し待つとReadyになると思われる。 なお、CNIのセットアップはコントロールプレーンで行っているので、ワーカーノードが追加されたタイミングで自動でワーカーノードにもCNIがセットアップされる。
$ kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-master Ready control-plane 19m v1.27.4 k8s-worker NotReady <none> 8s v1.27.4 # ↓数分後 $ kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-master Ready control-plane 22m v1.27.4 k8s-worker Ready <none> 3m3s v1.27.4
トラブルシューティング
kubeadm initがこけた
メッセージが出ると思うのでそれに従って対応すれば困ることはないと思う。 それでも直らない場合は公式ドキュメントのトラブルシューティングガイドを読むと良い。
CNIの初期化が失敗するなど
とりあえず、kubeletのログを見る。
sudo journalctl -fu kubelet
こけているk8sリソースを見つけてログを見てみる。
kubectl get all -A
calicoのコントローラのログを見る。
kubectl -n calico-system logs -f deployment.apps/calico-kube-controllers
よくわからなればkubeadm resetしてみる。 それでも直らなかった再起動…。
クラスタをリセットする
セットアップをやり直したいとかうまく動かないというときに実行する。
sudo kubeadm reset sudo iptables -F sudo iptables -F -t nat sudo iptables -F -t mangle sudo iptables -X sudo rm -r /etc/cni/net.d
ワーカーノードの場合は以下のコマンドをコントロールプレーンで実行する。
kubectl delete node <ワーカーノード名>