使用 kubeadm 启动 k8s 集群之后基础设施不停重启的问题


前言

闲着没事做打算玩一玩大名鼎鼎的 k8s,然后果不其然遇到了奇奇怪怪的问题。

containerd

k8s 需要一个容器化环境来跑各种东西,我自己的理解它用的应该是 docker。搜了一些教程发现,确实在这些教程里用的有 docker。所以对于另一些教程里我不认识的 containerd 就直接跳过了。结果部署之后,发现一开始用的好好的,用着用着 6443 端口就连不上了,用 htop 一看,kube-apiserver 的进程会死掉。当它重启之后,发现 kube-system 这个 pods 里的东西,一直在 CrashLoopBackOff。

我一直以为是我操作步骤有哪些不对,反复对照了教程里的说明,确认真的没错。虚拟机还重置了好几次,来重新创建集群,还是没用。但是 minikube 就是可以正常启动的。

最草的是本该主管这一切的 kubelet 没有任何日志输出,/var/log/sys 里也没有,systemdctl status kubelet 也没有输出。导致定位问题非常不方便。

还得是日志

无奈我只能把注意力放在崩掉的服务上来,我跑去翻 etcd 和 apiserver 的日志,发现里面有一段这样的输出:

Error while dialing: dial tcp 127.0.0.1:2379: connect: connection refused

这大概是在 apiserver 之前,别的啥服务掉了才会导致的吧?于是搜了一下这个输出,找到了一个跟我类似现象的。这位日本仁兄在博客里形容:「kubelet 再起動したら、時々復活してすぐ死ぬ奇跡の時間がある」。这不正是我的体验么?看下去发现,他是 containerd 的 cgroup 跟 k8s 设定的不一致。但我有确认过 docker info 里的输出,跟 k8s 一样都是 systemd,我不应该遇到这个问题才对。然后我就发现了官方文档里的这个内容

1.24 版本之后对于 k8s 来说不使用 docker,而是使用 containerd,所以准备环境的时候并不是跑个 docker 就可以了。

docker 的默认 Cgroup 是 systemd,但是 containerd 并不是,需要改一下默认的配置文件。我一开始不知道这个事情,以为可以直接用 docker,再三确认这玩意 Cgroup 没问题,结果跑起来之后,apiserver 和 scheduler 等 kube-system 的 pods 跑没一会儿就自己炸掉然后重启了。

然后我去看了一下我找到的一堆教程,果然使用 docker 的教程 k8s 版本都在 1.24 以下,甚至还有个在用 1.23 版本的教程。人家 k8s 1.20 就宣布了这个事情,特地用 1.23 版本难道是为了卡着能直接用 docker 的版本吗!