隧道连接问题

Microsoft Azure Kubernetes 服务 (AKS) 使用特定组件在节点和控制平面之间进行隧道安全通信。 隧道由控制平面端的服务器和群集节点端的客户端组成。 本文讨论如何排查和解决与 AKS 中的隧道连接相关的问题。

Azure 托管的 AKS 底层、客户管理的 Azure 虚拟网络和子网以及从 API 到隧道 Pod 的隧道示意图。

注意

默认情况下,根据区域,隧道组件为 tunnel-front。 更新到运行时间服务级别协议 (SLA) 功能时,tunnel-front已替换为使用 OpenVPNaks-link隧道组件。 AKS 正在迁移到 Konnectivity。 这是一个 Kubernetes 上游 组件,它同时tunnel-front替换 和 aks-link。 有关迁移到 Konnectivity 作为隧道组件的详细信息,请参阅 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 命令在容器中运行命令或进入容器 ()

  • 使用 kubectl port-forward 命令转发 pod 的一个或多个本地端口 ()

原因 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 门户图显示了一个安全规则示例:

Azure 门户中“添加入站安全规则”窗格的屏幕截图。新安全规则的“目标端口范围”框设置为 10250。

如果想要更严格,可以仅允许在子网级别访问端口 10250。

注意

  • 必须相应地调整 “优先级” 字段。 例如,如果规则拒绝多个端口 (包括端口 10250) ,则图像中显示的规则应具有较低的优先级编号 (较小的数字具有更高的优先级) 。 有关 优先级的详细信息,请参阅 安全规则

  • 如果在应用此解决方案后未看到任何行为更改,可以重新创建隧道组件 Pod。 删除这些 Pod 会导致重新创建它们。

原因 2:防火墙 (UFW) 工具阻止端口 10250

注意

此原因适用于 AKS 群集中的任何隧道组件。

无复杂防火墙 (UFW) 是用于管理 netfilter 防火墙的 命令行程序。 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 上应用以下解决方案之一。

重要

在使用此工具进行任何更改之前,请查看 AKS 支持策略 (特别是 节点维护和访问) ,以防止群集进入不支持的方案。

注意

如果在应用解决方案后未看到任何行为更改,可以重新创建隧道组件 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链是否包含目标为 、协议为 DROPtcp、目标为 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 命令检查 iptables 手册

重要

在使用此工具进行任何更改之前,请查看 AKS 支持策略 (特别是 节点维护和访问) ,以防止群集进入不支持的方案。

原因 4:出口端口 1194 或 9000 未打开

注意

此原因仅适用于 tunnel-frontaks-link Pod。

是否有任何出口流量限制,例如来自 AKS 防火墙? 如果有,则需要端口 9000 才能启用 Pod 的正确功能 tunnel-front 。 同样,Pod 需要 aks-link 端口 1194。

Konnectivity 依赖于端口 443。 默认情况下,此端口处于打开状态。 因此,不必担心该端口的连接问题。

解决方案 4:打开端口 1194 或 9000

确保虚拟设备允许访问端口 1194 或端口 9000。 有关所需规则和依赖项的详细信息,请参阅 Azure 全局必需网络规则

原因 5:源网络地址转换 (SNAT) 端口耗尽

注意

此原因适用于 AKS 群集中的任何隧道组件。 但是,它不适用于 专用 AKS 群集。 源网络地址转换 (SNAT) 端口耗尽只能用于公共通信。 对于专用 AKS 群集,API 服务器位于 AKS 虚拟网络或子网内。

如果 SNAT 端口耗尽 (失败的 SNAT 端口) ,则节点无法连接到 API 服务器。 隧道容器位于 API 服务器端。 因此,不会建立隧道连接。

如果 SNAT 端口资源耗尽,出站流将失败,直到现有流释放一些 SNAT 端口。 Azure 负载均衡器在流关闭时回收 SNAT 端口。 它使用 4 分钟的空闲超时从空闲流中回收 SNAT 端口。

可以从 AKS 负载均衡器指标或服务诊断查看 SNAT 端口,如以下部分所述。 有关如何查看 SNAT 端口的详细信息,请参阅如何实现 检查出站连接统计信息?

AKS 负载均衡器指标

若要使用 AKS 负载均衡器指标查看 SNAT 端口,请执行以下步骤:

  1. Azure 门户中,搜索并选择“Kubernetes 服务”。

  2. 在 Kubernetes 服务列表中,选择群集的名称。

  3. 在群集的菜单窗格中,找到 “设置” 标题,然后选择“ 属性”。

  4. 选择“ 基础结构资源组”下列出的名称。

  5. 选择 kubernetes 负载均衡器。

  6. 在负载均衡器的菜单窗格中,找到 “监视 ”标题,然后选择“ 指标”。

  7. 对于指标类型,请选择“ SNAT 连接计数”。

  8. 选择“ 应用拆分”。

  9. “拆分依据 ”设置为 “连接状态”。

服务诊断

若要使用服务诊断查看 SNAT 端口,请执行以下步骤:

  1. Azure 门户中,搜索并选择“Kubernetes 服务”。

  2. 在 Kubernetes 服务列表中,选择群集的名称。

  3. 在群集的菜单窗格中,选择“ 诊断并解决问题”。

  4. 选择“ 连接问题”。

  5. “SNAT 连接和端口分配”下,选择“ 查看详细信息”。

  6. 如有必要,请使用“ 时间范围 ”按钮自定义时间范围。

解决方案 5a:确保应用程序正在使用连接池

出现此行为的原因可能是应用程序未重用现有连接。 建议不要为每个请求创建一个出站连接。 此类配置可能会导致连接耗尽。 检查应用程序代码是否遵循最佳做法和使用连接池。 大多数库都支持连接池。 因此,不必为每个请求创建新的出站连接。

解决方案 5b:调整分配的出站端口

如果应用程序内一切正常,则必须调整分配的出站端口。 有关出站端口分配的详细信息,请参阅 配置分配的出站端口

解决方案 5c:在创建群集时使用托管网络地址转换 (NAT) 网关

可以将新群集设置为使用托管网络地址转换 (NAT) 网关进行出站连接。 有关详细信息,请参阅 使用托管 NAT 网关创建 AKS 群集

第三方联系人免责声明

Microsoft 提供第三方联系信息,帮助你查找有关本主题的其他信息。 该联系信息如有更改,恕不另行通知。 Microsoft 不保证第三方联系信息的准确性。

联系我们寻求帮助

如果你有任何疑问或需要帮助,请创建支持请求联系 Azure 社区支持。 还可以向 Azure 反馈社区提交产品反馈。