Kubernetes 故障排除

本页逐步讲解 Kubernetes 设置、网络和部署的几个常见问题。

提示

通过向文档存储库提出 PR 来建议常见问题解答项。

此页面细分为以下类别:

  1. 一般问题
  2. 常见网络错误
  3. 常见 Windows 错误
  4. 常见的 Kubernetes 主错误

一般问题

如何实现知道 Windows 上的 Kubernetes 是否已成功完成?

应会看到 kubelet、kube-proxy 以及(如果选择 Flannel 作为网络解决方案)在节点上运行的 flannel 托管主机代理进程。 除此之外,Windows 节点还应在 Kubernetes 群集中列为“就绪”。

是否可以配置为在后台运行所有这些操作?

从 Kubernetes 版本 1.11 开始,kubelet 和 kube-proxy 可以作为本机 Windows 服务运行。 还可以始终使用备用服务管理器(如 nssm.exe )在后台运行这些进程(flanneld、kubelet 和 kube-proxy)。

常见网络错误

负载均衡器在群集节点之间不一致地受到管道限制

在 Windows 上,kube-proxy 为群集中的每个 Kubernetes 服务创建 HNS 负载均衡器。 在(默认)kube-proxy 配置中,包含多个(通常为 100+)负载均衡器的群集中的节点可能会耗尽可用的临时 TCP 端口(a.k.a.动态端口范围),默认情况下涵盖端口 49152 到 65535。 这是因为每个(非 DSR)负载均衡器在每个节点上保留大量端口。 此问题可能通过 kube-proxy 中的错误来显示自身,例如:

Policy creation failed: hcnCreateLoadBalancer failed in Win32: The specified port already exists.

用户可以通过运行 CollectLogs.ps1 脚本并咨询 *portrange.txt 文件来识别此问题。

它还 CollectLogs.ps1 将模拟 HNS 分配逻辑,以在临时 TCP 端口范围内测试端口池分配可用性,并在其中 reservedports.txt报告成功/失败。 该脚本保留 10 个范围 64 个 TCP 临时端口(以模拟 HNS 行为),对预留成功和失败进行计数,然后释放分配的端口范围。 小于 10 的成功数表示临时池耗尽了可用空间。 还将生成 reservedports.txt大约可用的 64 块端口预留数的愤怒摘要。

若要解决此问题,可以执行几个步骤:

  1. 对于永久性解决方案,kube-proxy 负载均衡应设置为 DSR 模式。 DSR 模式完全实现,仅在 Windows Server 预览体验成员内部版本 18945 或更高版本上可用。
  2. 解决方法是,用户还可以使用命令(例如 netsh int ipv4 set dynamicportrange TCP <start_port> <port_count>)增加可用的临时端口的默认 Windows 配置。 警告: 重写默认动态端口范围可能会对依赖于非临时范围的可用 TCP 端口的主机上的其他进程/服务产生后果,因此应仔细选择此范围。
  3. 使用累积更新KB4551853(以及所有较新的累积更新)中包含的智能端口池共享来增强非 DSR 模式负载均衡器的可伸缩性增强功能。

HostPort 发布不起作用

若要使用 HostPort 功能,请确保 CNI 插件是 v0.8.6 或更高版本,并且 CNI 配置文件具有 portMappings 功能集:

"capabilities": {
    "portMappings":  true
}

我在 Win32 中看到错误,例如“hnsCall 在 Win32 中失败:驱动器中存在错误的磁盘”。

对 HNS 对象进行自定义修改或安装新Windows 更新时,可能会发生此错误,这些Windows 更新不会拆毁旧的 HNS 对象。 它指示以前在更新之前创建的 HNS 对象与当前安装的 HNS 版本不兼容。

在 Windows Server 2019(及更早版本)上,用户可以通过删除 HNS.data 文件来删除 HNS 对象

Stop-Service HNS
rm C:\ProgramData\Microsoft\Windows\HNS\HNS.data
Start-Service HNS

用户应能够直接删除任何不兼容的 HNS 终结点或网络:

hnsdiag list endpoints
hnsdiag delete endpoints <id>
hnsdiag list networks
hnsdiag delete networks <id>
Restart-Service HNS

Windows Server 版本 1903 上的用户可以转到以下注册表位置,并删除以网络名称开头的任何 NIC(例如 vxlan0cbr0):

\\Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\vmsmp\parameters\NicList

Azure 上的 Flannel host-gw 部署上的容器无法访问 Internet

在 Azure 上的 host-gw 模式下部署 Flannel 时,数据包必须通过 Azure 物理主机 vSwitch。 用户应为分配给节点的每个子网编程 类型为“虚拟设备”的用户定义路由 。 这可以通过Azure 门户(请参阅此处的示例)或通过 az Azure CLI 完成。 下面是一个名为“MyRoute”的示例 UDR,它使用 az commands 作为 IP 10.0.0.4 的节点以及相应的 Pod 子网 10.244.0.0/24:

az network route-table create --resource-group <my_resource_group> --name BridgeRoute 
az network route-table route create  --resource-group <my_resource_group> --address-prefix 10.244.0.0/24 --route-table-name BridgeRoute  --name MyRoute --next-hop-type VirtualAppliance --next-hop-ip-address 10.0.0.4 

提示

如果要自行在其他云提供商的 Azure 或 IaaS VM 上部署 Kubernetes,也可以改用 overlay networking

我的 Windows Pod 无法 ping 外部资源

Windows Pod 目前没有为 ICMP 协议编程的出站规则。 但是,支持 TCP/UDP。 尝试演示与群集外部资源的连接时,请替换为 ping <IP> 相应的 curl <IP> 命令。

如果仍然遇到问题,很可能 cni.conf 中的网络配置值得一些额外的关注。 始终可以编辑此静态文件,配置将应用于任何新创建的 Kubernetes 资源。

为什么? Kubernetes 网络要求(请参阅 Kubernetes 模型)是让群集通信在内部没有 NAT 的情况下进行。 为了满足此要求,对于不希望发生出站 NAT 的所有通信,我们都有 ExceptionList 。 但是,这也意味着需要从 ExceptionList 中排除要查询的外部 IP。 只有这样,源自 Windows Pod 的流量才能正确接收来自外部世界的响应。 在这方面,ExceptionList cni.conf 应如下所示:

"ExceptionList": [
  "10.244.0.0/16",  # Cluster subnet
  "10.96.0.0/12",   # Service subnet
  "10.127.130.0/24" # Management (host) subnet
]

我的 Windows 节点无法访问 NodePort 服务

来自节点本身的本地 NodePort 访问可能会失败。 这是使用累积更新KB4571748(或更高版本)解决的已知功能差距。 NodePort 访问将来自其他节点或外部客户端。

在纵向缩减 Pod 后,Windows 节点停止路由

由于设计限制,需要在 Windows 节点上至少运行一个 Pod,以便 NodePort 转发正常工作。

一段时间后,容器的 vNIC 和 HNS 终结点将被删除

当参数未传递到 hostname-override,可能会导致此问题。 若要解决此问题,用户需要将主机名传递给 kube-proxy,如下所示:

C:\k\kube-proxy.exe --hostname-override=$(hostname)

在 Flannel (vxlan) 模式下,重新加入节点后,Pod 遇到连接问题

每当以前删除的节点重新加入群集时,flannelD 将尝试向节点分配新的 Pod 子网。 用户应删除以下路径中的旧 Pod 子网配置文件:

Remove-Item C:\k\SourceVip.json
Remove-Item C:\k\SourceVipRequest.json

启动 Kubernetes 后,Flanneld 停滞在“等待网络创建”中

应使用 Flannel v0.12.0 (及更高版本)解决此问题。 如果使用较旧版本的 Flanneld,则可能会出现已知的争用条件,以便未设置 flannel 网络的管理 IP。 解决方法是手动重新启动 FlannelD。

PS C:> [Environment]::SetEnvironmentVariable("NODE_NAME", "<Windows_Worker_Hostname>")
PS C:> C:\flannel\flanneld.exe --kubeconfig-file=c:\k\config --iface=<Windows_Worker_Node_IP> --ip-masq=1 --kube-subnet-mgr=1

由于缺少 /run/flannel/subnet.env,我的 Windows Pod 无法启动

这表示 Flannel 未正确启动。 可以尝试重启flanneld.exe,也可以将文件从 /run/flannel/subnet.env Kubernetes 主节点上 C:\run\flannel\subnet.env 手动复制到 Windows 工作器节点上,并将 FLANNEL_SUBNET 行修改为分配的子网。 例如,如果分配了节点子网 10.244.4.1/24:

FLANNEL_NETWORK=10.244.0.0/16
FLANNEL_SUBNET=10.244.4.1/24
FLANNEL_MTU=1500
FLANNEL_IPMASQ=true

通常,还有另一个问题可能导致此错误需要首先调查。 建议 flanneld.exe 为你生成此文件。

在 vSphere 上运行的 Kubernetes 群集上,主机到 Pod 之间的连接中断

由于 vSphere 和 Flannel 都保留用于覆盖网络的端口 4789(默认 VXLAN 端口),因此数据包最终可能会被截获。 如果 vSphere 用于覆盖网络,则应将其配置为使用其他端口,以便释放 4789。

我的终结点/IP 正在泄漏

目前有 2 个已知问题可能导致终结点泄漏。

  1. 第一 个已知问题是 Kubernetes 版本 1.11 中的问题。 请避免使用 Kubernetes 版本 1.11.0 - 1.11.2。
  2. 导致终结点泄漏的第二 个已知问题是 终结点存储中的并发问题。 若要接收修补程序,必须使用 Docker EE 18.09 或更高版本。

由于“网络:无法分配范围”错误,我的 Pod 无法启动

这表示节点上的 IP 地址空间已用空。 若要清理任何 泄漏的终结点,请迁移受影响节点上的任何资源,并运行以下命令:

c:\k\stop.ps1
Get-HNSEndpoint | Remove-HNSEndpoint
Remove-Item -Recurse c:\var

我的 Windows 节点无法使用服务 IP 访问我的服务

这是 Windows 上当前网络堆栈的已知限制。 但是,Windows Pod可以访问服务 IP。

启动 Kubelet 时找不到网络适配器

Windows 网络堆栈需要一个虚拟适配器,以便 Kubernetes 网络正常工作。 如果以下命令未返回任何结果(在 admin shell 中),则 HNS 网络创建(Kubelet 正常运行的必要先决条件)已失败:

Get-HnsNetwork | ? Name -ieq "cbr0"
Get-HnsNetwork | ? Name -ieq "vxlan0"
Get-NetAdapter | ? Name -Like "vEthernet (Ethernet*"

通常,在主机的网络适配器不是“以太网”的情况下,有必要修改 start.ps1 脚本的 InterfaceName 参数。 否则,请参阅脚本的 start-kubelet.ps1 输出,查看虚拟网络创建过程中是否存在错误。

我仍然看到问题。 应采取何种操作?

网络或主机上可能存在其他限制,从而阻止节点之间的某些类型的通信。 请确保:

  • 已正确配置所选网络拓扑(l2bridgeoverlay
  • 允许来自 Pod 的流量
  • 如果要部署 Web 服务,则允许 HTTP 流量
  • 不同协议(即 ICMP 与 TCP/UDP)的数据包不会被删除

提示

对于其他自助资源,此处还提供了适用于 Windows 的 Kubernetes 网络故障排除指南。

常见 Windows 错误

我的 Kubernetes Pod 停滞在“ContainerCreating”

此问题可能有很多原因,但最常见的原因是暂停映像配置错误。 这是下一个问题的高级症状。

部署时,Docker 容器会继续重启

检查暂停映像是否与 OS 版本兼容。 Kubernetes 假定 OS 和容器都具有匹配的 OS 版本号。 如果使用 Windows 的实验性版本(如预览体验成员版本),则需要相应地调整映像。 有关映像,请参阅Microsoft的 Docker 存储库

常见的 Kubernetes 主错误

调试 Kubernetes 主节点分为三个主要类别(可能性顺序):

  • Kubernetes 系统容器出现问题。
  • 运行方式 kubelet 有问题。
  • 系统出现问题。

运行 kubectl get pods -n kube-system 以查看 Kubernetes 正在创建的 Pod;这可能提供一些有关特定 Pod 崩溃或无法正确启动的见解。 然后,运行 docker ps -a 以查看支持这些 Pod 的所有原始容器。 最后, docker logs [ID] 在疑似导致问题的容器上运行,以查看进程的原始输出。

无法连接到 API 服务器 https://[address]:[port]

此错误通常表示证书问题。 确保已正确生成配置文件,使其中的 IP 地址与主机的 IP 地址匹配,并且已将其复制到 API 服务器装载的目录。

查找此配置文件的不错位置包括:

  • ~/kube/kubelet/
  • $HOME/.kube/config
  • /etc/kubernetes/admin.conf

否则,请参阅 API 服务器的清单文件来检查装入点。