🦔

KubernetesクラスタのシステムコンポーネントPodがCrashLoopBackOffになったのでトラブルシュートした

2025/02/20に公開

1. 背景

Kubernetesの学習のため公式ドキュメントを参考に、Raspberry Pi4にKubernetesをインストールしてクラスタを構成しました。しかし、構成した直後にシステムコンポーネントのetcdやkube-apiserverなどがCrashLoopBackOffし続けて、うまく起動しない事象が発生しました。。。
解決にかなり時間がかかってしまったので、同じ轍を踏む人が増えないように投稿したいと思います。

悲しみの状態
NAMESPACE     NAME                                READY   STATUS             RESTARTS         AGE
kube-system   coredns-668d6bf9bc-4d4d9            0/1     Pending            0                113s
kube-system   coredns-668d6bf9bc-f44js            0/1     Pending            0                113s
kube-system   etcd-ubuntu-01                      1/1     Running            23 (56s ago)     2m17s
kube-system   kube-apiserver-ubuntu-01            1/1     Running            23 (2m32s ago)   2m17s
kube-system   kube-controller-manager-ubuntu-01   1/1     Running            3 (46s ago)      2m18s
kube-system   kube-proxy-p5zcb                    0/1     CrashLoopBackOff   1 (5s ago)       113s
kube-system   kube-scheduler-ubuntu-01            1/1     Running            28 (41s ago)     2m17s

2. 環境

kubelet v1.32.2
kubeadm v1.32.2
kubectl v1.32.2

3. 結論

正しいコンテナランタイムをインストールしましょう。
公式ドキュメントをちゃんと読もう。

4. なぜこうなったのか

コンテナといえばDocker Engineでしょ、とdockerだけをインストールしてkubeadm initしていました。
しかし、kubernetes v1.20からDockerランタイムが非推奨になっており、v1.24ではDockerと対話するため組み込みコンポーネントであるdockershimが削除されていたようでした。

参考: https://kubernetes.io/ja/docs/tasks/administer-cluster/migrating-from-dockershim/check-if-dockershim-removal-affects-you/

現在の推奨コンテナランタイムはcontainerdであり、以下のいずれかの対応が必要でした。

containerdランタイムをインストールする
docker用のCRI (Container Runtime Interface)であるcri-dockerdをインストールする

②はこちらのブログの方がとても分かりやすく解説してくれているので、以下は①の方法で対応したものを記載したいと思います。

5. ①をやってみた

参考

公式の作業マニュアルがあります。Kubernetesは公式ドキュメントがしっかりしているので、ちゃんと読めばよかった。。。
https://kubernetes.io/ja/docs/setup/production-environment/container-runtimes/#container-runtimes

5.1. containerdインストール

5.1.1. インストール

資材をダウンロードしてきて、/usr/local/に解凍します。
今回はv1.7.25を利用しました。

$ wget https://github.com/containerd/containerd/releases/download/v1.7.25/containerd-1.7.25-linux-arm64.tar.gz
$ sudo tar zxvf containerd-1.7.25-linux-arm64.tar.gz -C /usr/local/

5.1.2. 起動

containerdをサービスとしてsystemdで起動します。
自動起動の設定もしておきます。

$ sudo wget https://raw.githubusercontent.com/containerd/containerd/main/containerd.service \
    -O /etc/systemd/system/containerd.service
$ sudo systemctl daemon-reload

$ sudo systemctl start containerd
$ sudo systemctl enable containerd

5.1.3. containerd設定ファイルの編集

デフォルトのconfigファイルを/etc/containerd/config/tomlに吐きます。

$ sudo containerd config default | sudo tee /etc/containerd/config.toml

そして、viなどのエディタで以下の設定をします。

/etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
  ...
  [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
    SystemdCgroup = true #デフォルトはfalse

5.2. runcインストール

5.1.1. インストール

資材をダウンロードし、インストールします。
v1.2.5を利用しました。

$ wget https://github.com/opencontainers/runc/releases/download/v1.2.5/runc.arm64
$ sudo install -m 755 runc.arm64 /usr/local/sbin/runc

5.3. CNIプラグインインストール

資材をダウンロードし、/opt/cni/binに解凍します。
v1.6.2を使用しました。

$ wget https://github.com/containernetworking/plugins/releases/download/v1.6.2/cni-plugins-linux-arm64-v1.6.2.tgz
$ sudo mkdir -p /opt/cni/bin
$ sudo tar Cxzvf /opt/cni/bin cni-plugins-linux-arm64-v1.6.2.tgz

5.4. kubeadm init

5.4.1. サービスの再起動

すべてインストールが完了したら、一応kubeletcontainerdを再起動しました。

sudo systemctl restart kubelet
sudo systemctl restart containerd

そして、containerdのcri-socketを指定してkubeadm initします。

$ sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --cri-socket=unix:///run/containerd/containerd.sock

...
...

$ kubelet get pods -n kube-system
NAMESPACE     NAME                           READY   STATUS    RESTARTS   AGE
kube-system   coredns-668d6bf9bc-dggl6       0/1     Pending   0          72s
kube-system   coredns-668d6bf9bc-ml88m       0/1     Pending   0          72s
kube-system   etcd-ras4                      1/1     Running   6          80s
kube-system   kube-apiserver-ras4            1/1     Running   6          75s
kube-system   kube-controller-manager-ras4   1/1     Running   7          75s
kube-system   kube-proxy-59d4c               1/1     Running   0          73s
kube-system   kube-scheduler-ras4            1/1     Running   8          80s

やったぜ。

5.5. flannelインストール

ネットワークアドオンをインストールしないとcorednsが起動しないため、今回はflannelをインストールしました。

$ curl -LO https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
$ kubectl apply -f kube-flannel.yml

kube-flannel-dnsのpodが起動して少し経つと、corednsのpodたちも起動してくれます。

$ kubectl get pod -A
NAMESPACE      NAME                           READY   STATUS    RESTARTS   AGE
kube-flannel   kube-flannel-ds-x4zkm          1/1     Running   0          84m
kube-system    coredns-668d6bf9bc-dggl6       1/1     Running   0          88m
kube-system    coredns-668d6bf9bc-ml88m       1/1     Running   0          88m
kube-system    etcd-ras4                      1/1     Running   6          88m
kube-system    kube-apiserver-ras4            1/1     Running   6          88m
kube-system    kube-controller-manager-ras4   1/1     Running   7          88m
kube-system    kube-proxy-59d4c               1/1     Running   0          88m
kube-system    kube-scheduler-ras4            1/1     Running   8          88m

6. まとめ

kubernetesクラスタ構築時にハマってしまった点と解決方法についてまとめました。
Raspberry Piを利用したのもあり、ハードウェア側の問題(電源不足やメモリ不足)も疑ってしまい、公式マニュアルを疎かにしたことで解決に時間がかかってしまいました。

まだまだ足りないですが、コンテナランタイムやCRIなどの周辺コンポーネントについての理解が少し深まったので、これから環境をガンガン試しながら勉強していきたいと思います...!!

また今回詳細に書かなかった②の方法も、Windows Hyper-V上のUbuntu仮想マシンで動作確認ができました。k8sはcontainerdの利用を推奨しているということでプロダクション環境でdockerdを使う機会はあまりないかもしれませんが、良い経験になりました。

Discussion