与任何程序一样,您可能会在安装或者运行 kubeadm 时遇到错误。 本文列举了一些常见的故障场景,并提供可帮助您理解和解决这些问题的步骤。
如果您的问题未在下面列出,请执行以下步骤:
如果您认为问题是 kubeadm 的错误:
如果您对 kubeadm 的工作方式有疑问,可以在 Slack 上的 #kubeadm 频道提问,
或者在 StackOverflow 上提问。
请加入相关标签,例如 #kubernetes 和 #kubeadm,这样其他人可以帮助您。
ebtables 或者其他类似的可执行文件RunContainerError、CrashLoopBackOff 或者 Error 状态coredns (或 kube-dns)停滞在 Pending 状态HostPort 服务无法工作coredns pods 有 CrashLoopBackOff 或者 Error 状态--component-extra-args 标志内的参数ebtables 或者其他类似的可执行文件如果在运行 kubeadm init 命令时,遇到以下的警告
[preflight] WARNING: ebtables not found in system path
[preflight] WARNING: ethtool not found in system path那么或许在您的节点上缺失 ebtables、ethtool 或者类似的可执行文件。
您可以使用以下命令安装它们:
apt install ebtables ethtool 命令。yum install ebtables ethtool 命令。如果您注意到 kubeadm init 在打印以下行后挂起:
[apiclient] Created API client, waiting for the control plane to become ready这可能是由许多问题引起的。最常见的是:
kubelet 的默认 cgroup 驱动程序配置不同于 Docker 使用的配置。
检查系统日志文件 (例如 /var/log/message) 或检查 journalctl -u kubelet 的输出。 如果您看见以下内容:
error: failed to run Kubelet: failed to create kubelet:
misconfiguration: kubelet cgroup driver: "systemd" is different from docker cgroup driver: "cgroupfs"有两种常见方法可解决 cgroup 驱动程序问题:
按照 此处 的说明再次安装 Docker。
更改 kubelet 配置以手动匹配 Docker cgroup 驱动程序,您可以参考 在主节点上配置 kubelet 要使用的 cgroup 驱动程序
docker ps 命令来检查以及 docker logs 命令来检视每个容器的运行日志。如果 Docker 停止并且不删除 Kubernetes 所管理的所有容器,可能发生以下情况:
sudo kubeadm reset
[preflight] Running pre-flight checks
[reset] Stopping the kubelet service
[reset] Unmounting mounted directories in "/var/lib/kubelet"
[reset] Removing kubernetes-managed containers
(block)一个可行的解决方案是重新启动 Docker 服务,然后重新运行 kubeadm reset:
sudo systemctl restart docker.service
sudo kubeadm reset检查 docker 的日志也可能有用:
journalctl -ul dockerRunContainerError、CrashLoopBackOff 或者 Error 状态在 kubeadm init 命令运行后,系统中不应该有 pods 处于这类状态。
kubeadm init 命令执行完后,如果有 pods 处于这些状态之一,请在 kubeadm
仓库提起一个 issue。coredns (或者 kube-dns) 应该处于 Pending 状态,
直到您部署了网络解决方案为止。RunContainerError、CrashLoopBackOff
或 Error 状态之一,并且coredns (或者 kube-dns)仍处于 Pending 状态,
那很可能是您安装的网络解决方案由于某种原因无法工作。您或许需要授予它更多的
RBAC 特权或使用较新的版本。请在 Pod Network 提供商的问题跟踪器中提交问题,
然后在此处分类问题。systemd 来启动 dockerd 和重启 docker 时,
删除 MountFlags=slave 选项。
您可以在 /usr/lib/systemd/system/docker.service 中看到 MountFlags。
MountFlags 可能会干扰 Kubernetes 挂载的卷, 并使 Pods 处于 CrashLoopBackOff 状态。
当 Kubernetes 不能找到 var/run/secrets/kubernetes.io/serviceaccount 文件时会发生错误。coredns (或 kube-dns)停滞在 Pending 状态这一行为是 预期之中 的,因为系统就是这么设计的。
kubeadm 的网络供应商是中立的,因此管理员应该选择 安装 pod 的网络解决方案。
您必须完成 Pod 的网络配置,然后才能完全部署 CoreDNS。
在网络被配置好之前,DNS 组件会一直处于 Pending 状态。
HostPort 服务无法工作此 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。
以下错误指出证书可能不匹配。
# kubectl get pods
Unable to connect to the server: x509: certificate signed by unknown authority (possibly because of "crypto/rsa: verification error" while trying to verify candidate authority certificate "kubernetes")$HOME/.kube/config 文件是否包含有效证书,并
在必要时重新生成证书。在 kubeconfig 文件中的证书是 base64 编码的。
该 base64 -d 命令可以用来解码证书,openssl x509 -text -noout 命令
可以用于查看证书信息。使用如下方法取消设置 KUBECONFIG 环境变量的值:
unset KUBECONFIG或者将其设置为默认的 KUBECONFIG 位置:
export KUBECONFIG=/etc/kubernetes/admin.conf另一个方法是覆盖 kubeconfig 的现有用户 “管理员” :
mv $HOME/.kube $HOME/.kube.bak
mkdir $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config以下错误可能表明 Pod 网络中出现问题:
Error from server (NotFound): the server could not find the requested resourceVagrant 通常为所有 VM 分配两个接口。第一个为所有主机分配了 IP 地址 10.0.2.15,用于获得 NATed 的外部流量。
这可能会导致 flannel 出现问题,它默认为主机上的第一个接口。这导致所有主机认为它们具有
相同的公共 IP 地址。为防止这种情况,传递 --iface eth1 标志给 flannel 以便选择第二个接口。
在某些情况下 kubectl logs 和 kubectl run 命令或许会返回以下错误,即便除此之外集群一切功能正常:
Error from server: Get https://10.19.0.41:10250/containerLogs/default/mysql-ddc65b868-glc5m/mysql: dial tcp 10.19.0.41:10250: getsockopt: no route to hosteth0,也分配一个私有 IP 在内部用作其浮动 IP 功能的锚点,
然而 kubelet 将选择后者作为节点的 InternalIP 而不是公共 IP使用 ip addr show 命令代替 ifconfig 命令去检查这种情况,因为 ifconfig 命令
不会显示有问题的别名 IP 地址。或者指定的 Digital Ocean 的 API 端口允许从 droplet 中
查询 anchor IP:
curl http://169.254.169.254/metadata/v1/interfaces/public/0/anchor_ipv4/address解决方法是通知 kubelet 使用哪个 --node-ip。当使用 Digital Ocean 时,可以是公网IP(分配给 eth0的),
或者是私网IP(分配给 eth1 的)。私网 IP 是可选的。
这个 KubeletExtraArgs section of the kubeadm NodeRegistrationOptions structure 被用来处理这种情况。
然后重启 kubelet:
systemctl daemon-reload
systemctl restart kubeletcoredns pods 有 CrashLoopBackOff 或者 Error 状态如果有些节点运行的是旧版本的 Docker,同时启用了 SELinux,您或许会遇到 coredns pods 无法启动的情况。
要解决此问题,您可以尝试以下选项之一:
升级到 Docker 的较新版本。
修改 coredns 部署以设置 allowPrivilegeEscalation 为 true:
kubectl -n kube-system get deployment coredns -o yaml | \
sed 's/allowPrivilegeEscalation: false/allowPrivilegeEscalation: true/g' | \
kubectl apply -f -CoreDNS 处于 CrashLoopBackOff 时的另一个原因是当 Kubernetes 中部署的 CoreDNS Pod 检测
到环路时。有许多解决方法
可以避免在每次 CoreDNS 监测到循环并退出时,Kubernetes 尝试重启 CoreDNS Pod 的情况。
警告:警告:禁用 SELinux 或设置
allowPrivilegeEscalation为true可能会损害集群的安全性。
如果您遇到以下错误:
rpc error: code = 2 desc = oci runtime error: exec failed: container_linux.go:247: starting container process caused "process_linux.go:110: decoding init error from pipe caused \"read parent: connection reset by peer\""
如果您使用 Docker 1.13.1.84 运行 CentOS 7 就会出现这种问题。 此版本的 Docker 会阻止 kubelet 在 etcd 容器中执行。
为解决此问题,请选择以下选项之一:
回滚到早期版本的 Docker,例如 1.13.1-75
yum downgrade docker-1.13.1-75.git8633870.el7.centos.x86_64 docker-client-1.13.1-75.git8633870.el7.centos.x86_64 docker-common-1.13.1-75.git8633870.el7.centos.x86_64
安装较新的推荐版本之一,例如 18.06:
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install docker-ce-18.06.1.ce-3.el7.x86_64--component-extra-args 标志内的参数kubeadm init 标志例如 --component-extra-args 允许您将自定义参数传递给像 kube-apiserver 这样的控制平面组件。然而,由于解析 (mapStringString) 的基础类型值,此机制将受到限制。
如果您决定传递一个支持多个逗号分隔值(例如 --apiserver-extra-args "enable-admission-plugins=LimitRanger,NamespaceExists")参数,将出现 flag: malformed pair, expect string=string 错误。
发生这种问题是因为参数列表 --apiserver-extra-args 预期的是 key=value 形式,而这里的 NamespacesExists 被误认为是缺少取值的键名。
一种解决方法是尝试分离 key=value 对,像这样:
--apiserver-extra-args "enable-admission-plugins=LimitRanger,enable-admission-plugins=NamespaceExists"
但这将导致键 enable-admission-plugins 仅有值 NamespaceExists。
已知的解决方法是使用 kubeadm 配置文件。
在云环境场景中,可能出现在云控制管理器完成节点地址初始化之前,kube-proxy 就被调度到新节点了。 这会导致 kube-proxy 无法正确获取节点的 IP 地址,并对管理负载平衡器的代理功能产生连锁反应。
在 kube-proxy Pod 中可以看到以下错误:
server.go:610] Failed to retrieve node IP: host IP unknown; known addresses: []
proxier.go:340] invalid nodeIP, initializing kube-proxy with 127.0.0.1 as nodeIP
一种已知的解决方案是修补 kube-proxy DaemonSet,以允许在控制平面节点上调度它,而不管它们的条件如何,将其与其他节点保持隔离,直到它们的初始保护条件消除:
kubectl -n kube-system patch ds kube-proxy -p='{ "spec": { "template": { "spec": { "tolerations": [ { "key": "CriticalAddonsOnly", "operator": "Exists" }, { "effect": "NoSchedule", "key": "node-role.kubernetes.io/master" } ] } } } }'
此问题的跟踪 在这里。
注意:这个 问题 仅适用于操控 kubeadm 数据类型的工具(例如,YAML 配置文件)。它将在 kubeadm API v1beta2 修复。
默认情况下,kubeadm 将 role.kubernetes.io/master:NoSchedule 污点应用于控制平面节点。
如果您希望 kubeadm 不污染控制平面节点,并将 InitConfiguration.NodeRegistration.Taints 设置成空切片,则应在编组时省略该字段。
如果省略该字段,则 kubeadm 将应用默认污点。
至少有两种解决方法:
使用 role.kubernetes.io/master:PreferNoSchedule 污点代替空切片。
除非其他节点具有容量,否则将在主节点上调度 Pods。
在 kubeadm init 退出后删除污点:
kubectl taint nodes NODE_NAME role.kubernetes.io/master:NoSchedule-此页是否对您有帮助?
感谢反馈。如果您有一个关于如何使用 Kubernetes 的特定的、需要答案的问题,可以访问 Stack Overflow. 在 GitHub 仓库上登记新的问题 报告问题 或者 提出改进建议.