序言
不知到我脑子抽什么风了要来整K8s,又不知道出什么毛病了启动一直报错,整的我整个人都不好了。正常来说,我在网上找了不少这方面的文章,比如说:K8S的安装(Ubuntu 20.04)、Ubuntu下的K8s部署、阿里云Ubuntu系统部署K8s集群。大家的基本流程都差不多,当我感觉应该没啥问题的时候,问题出现了。
执行初始化命令报错
sudo kubeadm init \
--image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers \
--apiserver-advertise-address=116.62.206.201 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16 \
--v=6
I1025 15:12:20.807588 3267531 round_trippers.go:553] GET https://我的ip:6443/healthz?timeout=10s in 0 milliseconds
这个问题真的太怪了,我每一步都是按照教程来的,但就是出问题了,但出问题总得解决问题吧,于是我踏上了茫茫找问题之路。
找原因
这个问题我倒是找到了和我问题很相近的一位老哥的提问,但很可惜,没找到具体到底为什么(要么就是我没看懂)。然后经过多方辗转,我了解到6443是k8s的# kube-apiserver服务端口,以此为契机,我找到了这篇文章:重启linux后,k8s的kube-apiserver无法正常启动的问题,虽然讲得很有道理,他的判断是服务没有启动,所以要让它重新启动,于是又是重启又是删文件重新生成的。
结果最后一步尬住了,就是因为6443端口没启动,所以我要重新初始化kubeadm,但如果我要初始化kubeadm的话就必须先启动6443端口不然会报连接失败。
裂开了,真的裂开了。
但是我又想到会不会是apiserver需要手动启动,但没启动导致了这个问题呢,于是我找到了这篇文章:# 一次k8s未正常启动的排查-etcd文件损坏,这位老哥提出查看apiserver,但在初始化的过程中完全没有启动这个apiserver的流程,都是下载完之后直接执行初始化命令,难不成是在初始化的时候自行启动的apiserver?
怀着这个疑问,我查看了别人写的init流程分析:K8S 源码探秘 之 kubeadm init 执行流程分析,写得很好,但有一点很奇怪,在初始化预检的时候,第四步会去检查6443端口是否被占用,然后在安装前配置的第8步会与apiserver通信,期间压根没提apiserver什么事,也就是说如果apiserver提前启动的话检查6443端口发现被占用,初始化会失败,如果apiserver没有提前启动的话,后续与apiserver通信会失败?这么看来,可能性就只有一个了:apiserver是在初始化过程中启动的。
在这个结论的前提下,我重新看了etcd文件损坏那篇文章,在这之前,大家可以先看一下什么是etcd,简单来说就是一个分布式的、可靠的 key-value 存储系统,用于存储分布式系统中的关键数据,那篇文章中提到/var/lib/etcd/目录下snap文件丢失,检查发现我的这个目录下也没有snap文件,而且删掉etcd文件夹后重启kubelet生成了etcd文件夹但没有生成etcd文件,于是我的第一反应是不是权限不足无法写入?但修改了文件夹权限之后还是不行,又失败了。
但也不是完全没有进展,我突然发现日志内容变了:journalctl -xefu kubelet
Oct 25 16:30:09 izbp194ytlctx66a5ync21z kubelet[3271905]: E1025 16:30:09.151158 3271905 pod_workers.go:965] "Error syncing pod, skipping" err="failed to \"CreatePodSandbox\" for \"kube-scheduler-izbp194ytlctx66a5ync21z_kube-system(0b71292a42a2f3b04199cf1945eac5f9)\" with CreatePodSandboxError: \"Failed to create sandbox for pod \\\"kube-scheduler-izbp194ytlctx66a5ync21z_kube-system(0b71292a42a2f3b04199cf1945eac5f9)\\\": rpc error: code = Unknown desc = failed to get sandbox image \\\"k8s.gcr.io/pause:3.6\\\": failed to pull image \\\"k8s.gcr.io/pause:3.6\\\": failed to pull and unpack image \\\"k8s.gcr.io/pause:3.6\\\": failed to resolve reference \\\"k8s.gcr.io/pause:3.6\\\": failed to do request: Head \\\"https://k8s.gcr.io/v2/pause/manifests/3.6\\\": dial tcp 108.177.97.82:443: i/o timeout\"" pod="kube-system/kube-scheduler-izbp194ytlctx66a5ync21z" podUID=0b71292a42a2f3b04199cf1945eac5f9
获取镜像失败:"k8s.gcr.io/pause:3.6"。
使用docker images命令发现,我的pause版本是3.8
也就是说版本没对上。
查看kubelet版本:kubelet --version,发现版本号是:Kubernetes v1.25.2
而我下载的镜像包全是1.25.3
没什么好说的,因为我取的都是最新版本,没想到阿里云的镜像版本要低一个小版本,在意想不到的地方被背刺了呢。
但是话又说回来,我的版本号是通过kubeadm config images list命令获取的,为什么会出现版本号不一致的情况
这个暂且不追究,把pause对应版本加上再说。
但是事实证明,把镜像拉下来还是不行,该报错照样报错。
之后又尝试了很多种办法,包括:解决k8s 1.24 kubeadm init执行失败的问题、多个公网服务器搭建k8s集群,并且重新初始化服务:kubeadm reset,调整初始化参数,默认使用私网ip(删除init命令中的apiserver-advertise-address)
最后,皇天不负有心人,初始化成功了。
但可惜的是因为时间间隔拉太长了(折腾了整整2天),已经不知道具体是哪一步改动成功的(不过我猜想是因为网卡上没有绑定公网ip导致etcd服务找不到地址无法绑定),只好把整个过程都记录下来,整理的不是很好,望读者见谅吧。