网页 综合 更新时间 2026-11-14 02:15:55

对 kubeadm 进行故障排查 | Kubernetes

自动蜘蛛 kubernetes.io 正文约 3282 字
对 kubeadm 进行故障排查 | Kubernetes
此文档的更新日期比原文晚,因此其中的信息可能已过时。如果能阅读英文,请查看英文版本以获取最新信息: Troubleshooting kubeadm
与任何程序一样,你可能会在安装或者运行 kubeadm 时遇到错误。 本文列举了一些常见的故障场景,并提供可帮助你理解和解决这些问题的步骤。
如果你的问题未在下面列出,请执行以下步骤:
如果你认为问题是 kubeadm 的错误:
如果你对 kubeadm 的工作方式有疑问,可以在 Slack 上的 #kubeadm 频道提问, 或者在 StackOverflow 上提问。 请加入相关标签,例如 #kubernetes 和 #kubeadm,这样其他人可以帮助你。
自从 v1.18 后,如果集群中已存在同名 Node,kubeadm 将禁止 Node 加入集群。 这需要为 bootstrap-token 用户添加 RBAC 才能 GET Node 对象。
但这会导致一个问题,v1.18 的 kubeadm join 无法加入由 kubeadm v1.17 创建的集群。
使用 kubeadm v1.18 在控制平面节点上执行 kubeadm init phase bootstrap-token。 请注意,这也会启用 bootstrap-token 的其余权限。
或者,也可以使用 kubectl apply -f ... 手动应用以下 RBAC:
如果在运行 kubeadm init 命令时,遇到以下的警告
那么或许在你的节点上缺失 ebtables、ethtool 或者类似的可执行文件。 你可以使用以下命令安装它们:
如果你注意到 kubeadm init 在打印以下行后挂起:
如果容器运行时停止并且未删除 Kubernetes 所管理的容器,可能发生以下情况:
一个可行的解决方案是重新启动 Docker 服务,然后重新运行 kubeadm reset: 你也可以使用 crictl 来调试容器运行时的状态。 参见使用 CRICTL 调试 Kubernetes 节点。
在 kubeadm init 命令运行后,系统中不应该有 Pod 处于这类状态。
在 kubeadm init 命令执行完后,如果有 Pod 处于这些状态之一,请在 kubeadm 仓库提起一个 issue。coredns (或者 kube-dns) 应该处于 Pending 状态, 直到你部署了网络插件为止。
如果在部署完网络插件之后,有 Pod 处于 RunContainerError、CrashLoopBackOff 或 Error 状态之一,并且 coredns (或者 kube-dns)仍处于 Pending 状态, 那很可能是你安装的网络插件由于某种原因无法工作。你或许需要授予它更多的 RBAC 特权或使用较新的版本。请在 Pod Network 提供商的问题跟踪器中提交问题, 然后在此处分类问题。
这一行为是预期之中的,因为系统就是这么设计的。kubeadm 的网络供应商是中立的, 因此管理员应该选择安装 Pod 的网络插件。 你必须完成 Pod 的网络配置,然后才能完全部署 CoreDNS。 在网络被配置好之前,DNS 组件会一直处于 Pending 状态。
此 HostPort 和 HostIP 功能是否可用取决于你的 Pod 网络配置。请联系 Pod 网络插件的作者, 以确认 HostPort 和 HostIP 功能是否可用。
已验证 Calico、Canal 和 Flannel CNI 驱动程序支持 HostPort。
有关更多信息,请参考 CNI portmap 文档.
如果你的网络提供商不支持 portmap CNI 插件,你或许需要使用 NodePort 服务的功能或者使用 HostNetwork=true。
许多网络附加组件尚未启用 hairpin 模式 该模式允许 Pod 通过其服务 IP 进行访问。这是与 CNI 有关的问题。 请与网络附加组件提供商联系,以获取他们所提供的 hairpin 模式的最新状态。
如果你正在使用 VirtualBox (直接使用或者通过 Vagrant 使用),你需要 确保 hostname -i 返回一个可路由的 IP 地址。默认情况下,第一个接口连接不能路由的仅主机网络。 解决方法是修改 /etc/hosts,请参考示例 Vagrantfile。
验证 $HOME/.kube/config 文件是否包含有效证书, 并在必要时重新生成证书。在 kubeconfig 文件中的证书是 base64 编码的。 该 base64 --decode 命令可以用来解码证书,openssl x509 -text -noout 命令可以用于查看证书信息。
使用如下方法取消设置 KUBECONFIG 环境变量的值:
或者将其设置为默认的 KUBECONFIG 位置:
另一个方法是覆盖 kubeconfig 的现有用户 "管理员":
默认情况下,kubeadm 使用 /etc/kubernetes/kubelet.conf 中指定的 /var/lib/kubelet/pki/kubelet-client-current.pem 符号链接来配置 kubelet 自动轮换客户端证书。如果此轮换过程失败,你可能会在 kube-apiserver 日志中看到诸如 x509: certificate has expired or is not yet valid 之类的错误。要解决此问题,你必须执行以下步骤:
手动编辑 kubelet.conf 指向轮换的 kubelet 客户端证书,方法是将 client-certificate-data 和 client-key-data 替换为:
以下错误可能表明 Pod 网络中出现问题:
如果你正在 Vagrant 中使用 flannel 作为 Pod 网络,则必须指定 flannel 的默认接口名称。
Vagrant 通常为所有 VM 分配两个接口。第一个为所有主机分配了 IP 地址 10.0.2.15,用于获得 NATed 的外部流量。
这可能会导致 flannel 出现问题,它默认为主机上的第一个接口。这导致所有主机认为它们具有相同的公共 IP 地址。为防止这种情况,传递 --iface eth1 标志给 flannel 以便选择第二个接口。
在某些情况下 kubectl logs 和 kubectl run 命令或许会返回以下错误,即便除此之外集群一切功能正常:
这或许是由于 Kubernetes 使用的 IP 无法与看似相同的子网上的其他 IP 进行通信的缘故, 可能是由机器提供商的政策所导致的。
DigitalOcean 既分配一个共有 IP 给 eth0,也分配一个私有 IP 在内部用作其浮动 IP 功能的锚点, 然而 kubelet 将选择后者作为节点的 InternalIP 而不是公共 IP。
使用 ip addr show 命令代替 ifconfig 命令去检查这种情况,因为 ifconfig 命令 不会显示有问题的别名 IP 地址。或者指定的 DigitalOcean 的 API 端口允许你从 droplet 中 查询 anchor IP:
解决方法是通知 kubelet 使用哪个 --node-ip。当使用 DigitalOcean 时,可以是(分配给 eth0 的)公网 IP, 或者是(分配给 eth1 的)私网 IP。私网 IP 是可选的。 kubadm NodeRegistrationOptions 结构 的 KubeletExtraArgs 部分被用来处理这种情况。
如果有些节点运行的是旧版本的 Docker,同时启用了 SELinux,你或许会遇到 coredns Pod 无法启动的情况。 要解决此问题,你可以尝试以下选项之一:
访问原文 返回搜索 https://kubernetes.io/zh-cn/docs/setup/production-environment/tools/kubeadm/troubleshooting-kubeadm/
本页为82搜索生成的网页快照,内容来自站内索引;演示数据的原文链接仅作示例。