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. 使用累积更新知识库(KB)4551853(以及所有较新的累积更新)中包含的智能端口池共享来增强非 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 访问可能会失败。 这是使用累积更新知识库(KB)4571748(或更高版本)解决的已知功能差距。 NodePort 访问将来自其他节点或外部客户端。

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

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

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

当参数未传递到 kube-proxyhostname-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 企业版 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 服务器的清单文件以检查装入点。