上午好☀️☀️☀️️
本答案参考通义千问
你遇到的 kubeadm init 失败问题,主要表现为 API Server(kube-apiserver)无法正常启动或无法响应健康检查请求。日志中反复出现:
GET https://172.20.10.4:6443/healthz?timeout=10s in 0 milliseconds
这说明 API Server 服务没有运行 或 未正确监听 6443 端口。尽管你提到 kubelet 已经启动成功,并且 https://172.20.10.4:10250/healthz 是 OK 的,但 6443 端口是 kube-apiserver 的默认端口,它并未响应请求。
🔍 问题分析
1. kube-apiserver 没有启动
- 可能是因为配置错误、证书问题、或者容器未成功启动。
- 使用
systemctl status kube-apiserver 查看状态。 - 使用
docker ps 或 crictl ps 查看 kube-apiserver 容器是否在运行。
2. 证书问题
- 如果证书缺失或过期,会导致 API Server 启动失败。
- 检查
/etc/kubernetes/pki 下的证书文件是否存在。
3. 网络问题
- 虽然
10250 端口可以访问,但 6443 端口可能被防火墙阻止。 - 检查
iptables 或 firewalld 是否放行了 6443 端口。
4. 配置错误
init-default.yaml 中的配置可能存在错误,比如 IP 地址不匹配、集群名称不对等。
✅ 解决方案
一、检查 API Server 容器状态
# 查看 kube-apiserver 容器状态
docker ps -a | grep apiserver
# 或者使用 crictl(如果你使用 containerd)
crictl ps | grep apiserver
如果容器不存在或退出,查看其日志:
docker logs <container_id>
# 或者
crictl logs <container_id>
注意: 通常 kubeadm init 会通过 kubelet 启动一个静态 Pod 来运行 kube-apiserver,所以你可以检查 /etc/kubernetes/manifests/kube-apiserver.yaml 文件是否存在。
二、检查 API Server 配置文件
检查 /etc/kubernetes/manifests/kube-apiserver.yaml 文件内容,确认以下几点:
--advertise-address 是否设置为正确的 IP 地址(如 172.20.10.4)。--bind-address 是否设置为 0.0.0.0 或 172.20.10.4。--client-ca-file 和 --tls-cert-file 等证书路径是否正确。
示例配置片段如下:
spec:
containers:
- name: kube-apiserver
image: k8s.gcr.io/kube-apiserver:v1.24.2
args:
- --advertise-address=172.20.10.4
- --bind-address=0.0.0.0
- --client-ca-file=/etc/kubernetes/pki/ca.crt
- --tls-cert-file=/etc/kubernetes/pki/apiserver.crt
- --tls-private-key-file=/etc/kubernetes/pki/apiserver.key
ports:
- containerPort: 6443
三、检查证书文件
确保 /etc/kubernetes/pki/ 目录下包含以下文件:
- ca.crt
- apiserver.crt
- apiserver.key
- front-proxy-ca.crt
- front-proxy-client.crt
- front-proxy-client.key
如果缺少这些文件,可能是 kubeadm init 未完成或证书生成失败。
四、检查防火墙设置
确保 6443 端口开放:
# 检查当前防火墙规则
sudo iptables -L -n -v | grep 6443
# 如果使用 firewalld,添加规则
sudo firewall-cmd --permanent --add-port=6443/tcp
sudo firewall-cmd --reload
五、手动启动 API Server(调试用)
你可以尝试手动启动 kube-apiserver 容器来验证配置是否正确:
docker run -d \
--name kube-apiserver \
--net host \
--volume /etc/kubernetes/pki:/etc/kubernetes/pki \
--volume /var/lib/kubernetes:/var/lib/kubernetes \
k8s.gcr.io/kube-apiserver:v1.24.2 \
kube-apiserver \
--advertise-address=172.20.10.4 \
--bind-address=0.0.0.0 \
--client-ca-file=/etc/kubernetes/pki/ca.crt \
--tls-cert-file=/etc/kubernetes/pki/apiserver.crt \
--tls-private-key-file=/etc/kubernetes/pki/apiserver.key
注意: 这只是调试用,不建议直接用于生产环境。
六、重新初始化 Kubernetes
如果以上步骤都无法解决,建议清理并重新初始化:
# 清理所有 Kubernetes 组件
kubeadm reset --force
systemctl stop kubelet
rm -rf /etc/kubernetes/
rm -rf /var/lib/kubelet/
rm -rf /var/lib/etcd/
# 重新初始化
kubeadm init --config init-default.yaml --v=6
🧠 总结
| 步骤 | 说明 |
|------|------|
| 1 | 检查 kube-apiserver 容器状态和日志 |
| 2 | 检查配置文件 /etc/kubernetes/manifests/kube-apiserver.yaml |
| 3 | 检查证书文件是否完整 |
| 4 | 确保 6443 端口未被防火墙阻挡 |
| 5 | 手动启动 API Server(仅调试) |
| 6 | 清理并重新初始化 |
💡 建议
- 如果你是从头开始搭建 Kubernetes,建议使用
kubeadm init --config 指定配置文件,而不是直接使用 kubeadm init。 - 使用
--v=6 参数获取更详细的日志信息。 - 确保所有节点时间同步(使用 NTP 服务),否则证书验证可能会失败。
如有需要,我可以提供一份完整的 init-default.yaml 示例供你参考。