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:输入/输出超时
服务器错误:获取“https://<aks-node-name>:10250/containerLogs/<namespace>/<pod-name>/<container-name>”:服务器向 HTTPS 客户端返回了 HTTP 响应。
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 或 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 将导致它们被重新创建。
解决方案 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
命令来检查 iptables 手册。
原因 4:出口端口 1194 或 9000 未打开
备注
此原因仅适用于 tunnel-front
和 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 群集。
原因6:随着群集增长而引起的 Konnectivity 代理性能问题
随着群集的增长,Konnectivity 代理的性能可能会因网络流量增加、请求或资源约束增加而降级。
备注
此原因仅适用于 Konnectivity-agent
pod。
解决方案 6:用于 Konnectivity 代理的群集比例自动缩放程序(Cluster Proportional Autoscaler)
为了管理大型群集中的可伸缩性挑战,我们为 Konnectivity 代理实现群集比例自动缩放程序。 此方法符合行业标准和最佳做法。 它可确保最佳的资源使用率和增强的性能。
为何进行了此更改 以前,Konnectivity 代理具有固定的副本计数,在群集增长时可能会造成瓶颈。 通过实现群集比例自动缩放程序,我们使副本计数能够根据节点缩放规则动态调整,以提供最佳性能和资源使用情况。
群集比例自动缩放程序的工作原理 群集比例自动缩放程序使用阶梯配置来根据群集大小确定 Konnectivity 代理的副本数量。 阶梯配置在 kube-system 命名空间中的 konnectivity-agent-autoscaler configmap 中定义。 下面是阶梯配置的示例:
nodesToReplicas": [
[1, 2],
[100, 3],
[250, 4],
[500, 5],
[1000, 6],
[5000, 10]
]
此配置可确保副本数量与群集中的节点数适当缩放,以提供最佳资源分配和改进的网络可靠性。
如何使用群集比例自动缩放程序? 可以通过更新 kube-system 命名空间中的 konnectivity-agent-autoscaler configmap 来替代默认值。 下面是用于更新 configmap 的示例命令:
kubectl edit configmap <pod-name> -n kube-system
此命令将在编辑器中打开 configmap,使你能够进行必要的更改。
应检查的内容
必须监控节点上的内存不足(OOM)终止事件,因为群集比例自动扩展程序配置不当可能会导致 Konnectivity 代理的内存分配不足。 出现这种配置错误的原因如下:
内存使用率高: 随着群集的增长,Konnectivity 代理的内存使用量可能会显著增加。 这种情况可能会增加,尤其是在高峰负载期间或处理大量连接时。 如果群集成比例自动缩放程序配置未适当缩放副本,则代理可能会耗尽内存。
修复了资源限制: 如果 Konnectivity 代理的资源请求和限制设置得太低,则它们可能没有足够的内存来处理工作负荷,从而导致 OOM 终止。 配置错误的群集成比例自动缩放程序设置可能会因为没有提供足够的副本来分配负载,导致此问题加剧。
群集大小和工作负荷可变性: Konnectivity 代理所需的 CPU 和内存可能会因群集和工作负荷的大小而异。 如果群集比例自动缩放程序阶梯配置大小不正确,并且自适应调整群集使用模式的大小,则可能会导致内存过度使用和 OOM 终止。
若要识别和排查 OOM 终止问题,请执行以下步骤:
- 检查节点上的 OOM 终止:使用以下命令检查节点上的 OOM 终止:
kubectl get events --all-namespaces | grep -i 'oomkill'
- 检查节点资源使用情况:验证节点上的资源使用情况,以确保它们未耗尽内存:
kubectl top nodes
- 查看 Pod 资源请求和限制:确保 Konnectivity 代理 Pod 具有适当的资源请求和限制,以防止 OOM 终止:
kubectl get pod <pod-name> -n kube-system -o yaml | grep -A5 "resources:"
- 调整资源请求和限制:如有必要,通过编辑部署文件来修改 Konnectivity 代理 Pod 的资源请求和限制。
kubectl edit deployment konnectivity-agent -n kube-system
第三方联系人免责声明
Microsoft 会提供第三方联系信息来帮助你查找有关本主题的其他信息。 此联系信息可能会更改,恕不另行通知。 Microsoft 不保证第三方联系信息的准确性。
联系我们寻求帮助
如果你有任何疑问或需要帮助,请创建支持请求或联系 Azure 社区支持。 你还可以将产品反馈提交到 Azure 反馈社区。