Kubeadm init failed api server not healthy

I have same issue with cri-docker, API server not start. I see it have pull docker image for API server but not run

Hello, I hope it is not too late to post my solution here in 2025.03 when deploying k8s v1.32.
I use debian 12 with docker and containerd installed from official apt repository.
As I follow official tutorial to config my containerd to use systemd as cgroup driver https://kubernetes.io/docs/setup/production-environment/container-runtimes/#container-runtimes, my /etc/containerd/config.toml result like

version = 2

[plugins]
  [plugins."io.containerd.grpc.v1.cri"]
    [plugins."io.containerd.grpc.v1.cri".cni]
      bin_dir = "/usr/lib/cni"
      conf_dir = "/etc/cni/net.d"
    [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
      [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
        SystemdCgroup = true
  [plugins."io.containerd.internal.v1.opt"]
    path = "/var/lib/containerd/opt"

However it is not enough for K8S to create Pod for API server since default run time is not set, and kubeadm init command will stuck at waiting API server to become healthy. When you check contained log via

sudo journalctl -xeu containerd

You can find the following error

failed to create containerd container: create container failed validation: container.Runtime.Name must be set

Following the official containerd doc for config.toml https://github.com/jessfraz/cri-containerd/blob/master/docs/config.md, I realize to set run time properly by explicitly declaring default runtime and run time type in /etc/containerd/config.toml like following

version = 2

[plugins]
    [plugins."io.containerd.grpc.v1.cri"]
        [plugins."io.containerd.grpc.v1.cri".cni]
        bin_dir = "/usr/lib/cni"
        conf_dir = "/etc/cni/net.d"
    [plugins."io.containerd.grpc.v1.cri".containerd]
        default_runtime_name = "runc"
        [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
            runtime_type = "io.containerd.runc.v2"
            [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
                SystemdCgroup = true
    [plugins."io.containerd.internal.v1.opt"]
        path = "/var/lib/containerd/opt"

After restart containerd via

sudo systemctl restart containerd

The kubeadm init now can run correctly

update

In later phase for pod network configuration using calico v3.29, I found that calico will install the cni to /opt/cni directory, using the above config.toml will result in containerd error failed to find plugin \"loopback\" in path [/usr/lib/cni]" since the bin_dir in [plugins."io.containerd.grpc.v1.cri".cni] is not correct. I have to correct the config.toml as follows

version = 2

[plugins]
    [plugins."io.containerd.grpc.v1.cri"]
        [plugins."io.containerd.grpc.v1.cri".cni]
        bin_dir = "/opt/cni/bin"
        conf_dir = "/etc/cni/net.d"
    [plugins."io.containerd.grpc.v1.cri".containerd]
        default_runtime_name = "runc"
        [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
            runtime_type = "io.containerd.runc.v2"
            [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
                SystemdCgroup = true
    [plugins."io.containerd.internal.v1.opt"]
        path = "/var/lib/containerd/opt"

Then the cluster network will run correctly