隧道连接问题
Microsoft Azure Kubernetes 服务(AKS)使用特定组件进行节点与控制平面之间的隧道安全通信。 隧道由控制平面端的服务器和群集节点端的客户端组成。 本文介绍如何排查和解决 AKS 中隧道连接相关的问题。
注意
以前,AKS 隧道组件是 tunnel-front
。 它现已迁移到 Konnectivity 服务,即上游 Kubernetes 组件。 有关此迁移的详细信息,请参阅 AKS 发行说明和更改日志。
先决条件
现象
收到类似于有关端口 10250 的以下示例的错误消息:
服务器错误:获取“https://< aks-node-name>:10250/containerLogs/namespace>/<pod-name/<<container-name>>”: dial tcp <aks-node-ip>:10250: i/o timeout
服务器错误:拨号后端错误:拨号 tcp <aks-node-ip>:10250:i/o 超时
Kubernetes API 服务器使用端口 10250 连接到节点的 kubelet 来检索日志。 如果阻止端口 10250,kubectl 日志和其他功能将仅适用于在计划隧道组件的节点上运行的 Pod。 有关详细信息,请参阅 Kubernetes 端口和协议:工作器节点。
由于无法建立服务器和客户端之间的隧道组件或连接,因此以下功能将无法按预期工作:
允许控制器 Webhook
日志检索功能(使用 kubectl logs 命令)
在容器中运行命令或进入容器(使用 kubectl exec 命令)
转发 Pod 的一个或多个本地端口(使用 kubectl 端口转发 命令)
原因 1:网络安全组(NSG)正在阻止端口 10250
注意
此原因适用于 AKS 群集中可能具有的任何隧道组件。
可以使用 Azure 网络安全组 (NSG) 来筛选 Azure 虚拟网络中传入和传出 Azure 资源的网络流量。 网络安全组包含允许或拒绝多种 Azure 资源类型之间的入站和出站网络流量的安全规则。 对于每个规则,你可以指定源和目标、端口和协议。 有关详细信息,请参阅网络安全组如何筛选网络流量。
如果 NSG 在虚拟网络级别阻止端口 10250,隧道功能(如日志和代码执行)将仅适用于在计划隧道 Pod 的节点上计划的 Pod。 其他 Pod 不起作用,因为它们的节点无法到达隧道,并且该隧道计划在其他节点上。 若要验证此状态,可以使用 netcat (nc
) 或 telnet 命令测试连接。 可以运行 az vmss run-command invoke 命令来执行连接测试,并验证它是否成功、超时或导致其他问题:
az vmss run-command invoke --resource-group <infra-or-MC-resource-group> \
--name <virtual-machine-scale-set-name> \
--command-id RunShellScript \
--instance-id <instance-id> \
--scripts "nc -v -w 2 <ip-of-node-that-schedules-the-tunnel-component> 10250" \
--output tsv \
--query 'value[0].message'
解决方案 1:添加 NSG 规则以允许访问端口 10250
如果使用 NSG,并且存在特定限制,请确保添加一个安全规则,以便在虚拟网络级别允许端口 10250 的流量。 以下Azure 门户图像显示了一个示例安全规则:
如果想要限制更严格,则只能在子网级别允许访问端口 10250。
注意
必须相应地调整“优先级”字段。 例如,如果你有拒绝多个端口(包括端口 10250)的规则,则图像中显示的规则应具有较低的优先级数字(较低数字具有更高的优先级)。 有关优先级的详细信息,请参阅安全规则。
如果在应用此解决方案后未看到任何行为更改,可以重新创建隧道组件 Pod。 删除这些 Pod 会导致重新创建它们。
原因 2:未复杂防火墙 (UFW) 工具阻止端口 10250
注意
这一原因适用于 AKS 群集中拥有的任何隧道组件。
不复杂的防火墙 (UFW) 是用于管理网络筛选防火墙的命令行程序。 AKS 节点使用 Ubuntu。 因此,默认情况下,UFW 安装在 AKS 节点上,但禁用 UFW。
默认情况下,如果启用了 UFW,它将阻止访问所有端口,包括端口 10250。 在这种情况下,不太可能使用安全外壳(SSH) 连接到 AKS 群集节点进行故障排除。 这是因为 UFW 也可能阻止端口 22。 若要进行故障排除,可以运行 az vmss run-command invoke 命令来调用检查 是否已启用 UFW 的 ufw 命令 :
az vmss run-command invoke --resource-group <infra-or-MC-resource-group> \
--name <virtual-machine-scale-set-name> \
--command-id RunShellScript \
--instance-id <instance-id> \
--scripts "ufw status" \
--output tsv \
--query 'value[0].message'
如果结果指示已启用 UFW,并且它不专门允许端口 10250,该怎么办? 在这种情况下,隧道功能(如日志和代码执行)不适用于在启用了 UFW 的节点上计划的 Pod。 若要解决此问题,请对 UFW 应用以下解决方案之一。
注意
如果在应用解决方案后未看到任何行为更改,可以重新创建隧道组件 Pod。 删除这些 Pod 将导致重新创建它们。
解决方案 2a:禁用不复杂防火墙
az vmss run-command invoke
运行以下命令以禁用 UFW:
az vmss run-command invoke --resource-group <infra-or-MC-resource-group> \
--name <virtual-machine-scale-set-name> \
--command-id RunShellScript \
--instance-id <instance-id> \
--scripts "ufw disable" \
--output tsv \
--query 'value[0].message'
解决方案 2b:配置未复杂防火墙以允许访问端口 10250
若要强制 UFW 允许访问端口 10250,请 az vmss run-command invoke
运行以下命令:
az vmss run-command invoke --resource-group <infra-or-MC-resource-group> \
--name <virtual-machine-scale-set-name> \
--command-id RunShellScript \
--instance-id <instance-id> \
--scripts "ufw allow 10250" \
--output tsv \
--query 'value[0].message'
原因 3:iptables 工具阻止端口 10250
注意
这一原因适用于 AKS 群集中拥有的任何隧道组件。
iptables 工具允许系统管理员配置 Linux 防火墙的 IP 数据包筛选器规则。 可以将规则配置为 iptables
阻止端口 10250 上的通信。
可以查看节点的规则,以检查端口 10250 是被阻止还是丢弃关联的数据包。 为此,请 iptables
运行以下命令:
iptables --list --line-numbers
在输出中,数据分组为多个 链,包括 INPUT
链。 每个链包含以下列标题下的一个规则表:
num
(规则编号)target
prot
(协议)opt
source
destination
INPUT
链是否包含目标所在的DROP
规则、协议和tcp
目标?tcp dpt:10250
如果这样做, iptables
则会阻止对目标端口 10250 的访问。
解决方案 3:删除阻止端口 10250 上的访问的 iptables 规则
运行以下命令之一以删除 iptables
阻止访问端口 10250 的规则:
iptables --delete INPUT --jump DROP --protocol tcp --source <ip-number> --destination-port 10250
iptables --delete INPUT <input-rule-number>
若要解决确切或潜在的方案,建议通过运行以下命令iptables --help
来检查 iptable。
原因 4:出口端口 1194 或 9000 未打开
注意
此原因仅适用于 tunnel-front
pod 和 aks-link
Pod。
是否有出口流量限制,例如来自 AKS 防火墙? 如果有,则需要端口 9000 才能启用 Pod 的正确功能 tunnel-front
。 同样,Pod 需要 aks-link
端口 1194。
Konnectivity 依赖于端口 443。 默认情况下,此端口处于打开状态。 因此,无需担心该端口上的连接问题。
解决方案 4:打开端口 9000
尽管 tunnel-front
已迁移到 Konnectivity 服务,但某些 AKS 群集仍使用 tunnel-front
,依赖于端口 9000。 确保虚拟设备或任何网络设备或软件允许访问端口 9000。 有关所需规则和依赖项的详细信息,请参阅 Azure 全局所需的网络规则。
原因 5:源网络地址转换 (SNAT) 端口耗尽
注意
这一原因适用于 AKS 群集中拥有的任何隧道组件。 但是,它不适用于 专用 AKS 群集。 源网络地址转换 (SNAT) 端口耗尽仅适用于公共通信。 对于专用 AKS 群集,API 服务器位于 AKS 虚拟网络或子网内。
如果 SNAT 端口耗尽(SNAT 端口失败),则节点无法连接到 API 服务器。 隧道容器位于 API 服务器端。 因此,不会建立隧道连接。
如果 SNAT 端口资源已用尽,则出站流将失败,直到现有流释放某些 SNAT 端口。 Azure 负载均衡器流关闭时回收 SNAT 端口。 它使用四分钟的空闲超时从空闲流中回收 SNAT 端口。
可以从 AKS 负载均衡器指标或服务诊断查看 SNAT 端口,如以下部分所述。 有关如何查看 SNAT 端口的详细信息,请参阅如何实现检查出站连接统计信息?。
AKS 负载均衡器指标
若要使用 AKS 负载均衡器指标查看 SNAT 端口,请执行以下步骤:
在Azure 门户中,搜索并选择 Kubernetes 服务。
在 Kubernetes 服务列表中,选择群集的名称。
在群集的菜单窗格中,找到 “设置” 标题,然后选择“ 属性”。
选择基础结构资源组下列出的名称。
选择 kubernetes 负载均衡器。
在负载均衡器的菜单窗格中,找到 “监视 ”标题,然后选择“ 指标”。
对于指标类型,请选择 “SNAT 连接计数”。
选择“应用拆分”。
将“拆分方式”设置为“连接状态”。
服务诊断
若要使用服务诊断查看 SNAT 端口,请执行以下步骤:
在Azure 门户中,搜索并选择 Kubernetes 服务。
在 Kubernetes 服务列表中,选择群集的名称。
在群集的菜单窗格中,选择“ 诊断”并解决问题。
选择 “连接问题”。
在 SNAT 连接和端口分配下,选择“查看详细信息”。
如有必要,请使用 “时间范围 ”按钮自定义时间范围。
解决方案 5a:确保应用程序正在使用连接池
此行为可能会发生,因为应用程序未重用现有连接。 建议不要为每个请求创建一个出站连接。 此类配置可能会导致连接耗尽。 检查应用程序代码是否遵循最佳做法和使用连接池。 大多数库都支持连接池。 因此,不必为每个请求创建新的出站连接。
解决方案 5b:调整分配的出站端口
如果应用程序内的所有内容都正常,则必须调整分配的出站端口。 有关出站端口分配的详细信息,请参阅 配置分配的出站端口。
解决方案 5c:创建群集时使用托管网络地址转换 (NAT) 网关
可以将新群集设置为使用托管网络地址转换(NAT)网关进行出站连接。 有关详细信息,请参阅 使用托管 NAT 网关创建 AKS 群集。
第三方联系人免责声明
Microsoft 会提供第三方联系信息来帮助你查找有关本主题的其他信息。 此联系信息可能会更改,恕不另行通知。 Microsoft 不保证第三方联系信息的准确性。
联系我们寻求帮助
如果你有任何疑问或需要帮助,请创建支持请求或联系 Azure 社区支持。 你还可以将产品反馈提交到 Azure 反馈社区。