在 AKS 群集中排查内存饱和问题
本文讨论解决内存饱和问题的方法。 如果至少一个应用程序或进程需要比容器主机可以提供的内存多,或者主机耗尽其可用内存,则会发生内存饱和。
先决条件
现象
下表概述了内存饱和的常见症状。
症状 |
说明 |
不可计划 Pod |
如果节点接近其设置内存限制,则无法计划其他 Pod。 |
Pod 逐出 |
如果节点内存不足,kubelet 可以逐出 Pod。 尽管控制平面尝试在具有资源的其他节点上重新计划被逐出的 Pod,但不能保证其他节点有足够的内存来运行这些 Pod。 |
节点未就绪 |
内存饱和可能导致 kubelet 无 containerd 响应,最终导致节点就绪性问题。 |
内存不足 (OOM) 终止 |
如果 Pod 逐出无法阻止节点问题,则会出现 OOM 问题。 |
故障排除清单
若要减少内存饱和度,请使用有效的监视工具并应用最佳做法。
步骤 1:识别内存饱和的节点
使用以下任一方法标识内存饱和的节点:
Container Insights 是 AKS 中的一项功能,用于监视容器工作负荷性能。 有关详细信息,请参阅为 Azure Kubernetes 服务 (AKS) 群集启用容器见解。
在Azure 门户上,搜索并选择 Kubernetes 服务。
在 Kubernetes 服务列表中,选择群集的名称。
在群集的导航窗格中,找到 “监视 ”标题,然后选择“ 见解”。
设置适当的 时间范围 值。
选择“节点”选项卡。
在“指标”列表中,选择“内存工作集”(从 Allocatable 计算)。
在百分位选择器中,将示例设置为 “最大”,然后选择 “最大百分比 ”列标签两次。 此操作按所用内存的最大百分比(从高到低)对表节点进行排序。
由于第一个节点的内存使用率最高,因此请选择该节点来调查节点上运行的 Pod 的内存使用情况。
注意
Pod 的 CPU 或内存使用量百分比取决于为容器指定的 CPU 请求。 它不表示节点的 CPU 或内存使用量的百分比。 因此,请查看实际的 CPU 或内存使用率,而不是 Pod CPU 或内存使用量的百分比。
此过程在控制台中使用 kubectl 命令。 它仅显示节点的当前状态。
通过运行 kubectl top node 命令获取节点的内存使用情况:
kubectl top node
此命令的输出类似于以下文本:
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
aks-agentpool-30486455-vmss000003 239m 12% 3148Mi 69%
aks-agentpool-30486455-vmss000005 326m 17% 2143Mi 46%
aks-testmemory-30616462-vmss000000 66m 3% 1532Mi 28%
aks-testmemory-30616462-vmss000001 90m 4% 1689Mi 31%
aks-testmemory-30616462-vmss000002 74m 3% 1715Mi 31%
通过运行 kubectl 获取 pod 和 kubectl top pods 命令,获取节点上运行的 Pod 及其内存使用情况的列表:
kubectl get pods --all-namespaces --output wide \
| grep <node-name> \
| awk '{print $1" "$2}' \
| xargs -n2 kubectl top pods --namespace \
| awk 'NR==1 || NR%2==0' \
| sort -k3n \
| column -t
注意
在此代码片段中,将节点名称>替换为<实际的节点名称。
代码片段的输出类似于以下文本:
NAME CPU(cores) MEMORY(bytes)
coredns-autoscaler-5655d66f64-9fp2k 1m 7Mi
shippingservice-7946db7679-qzplg 6m 15Mi
azure-ip-masq-agent-tb8xv 1m 16Mi
cloud-node-manager-wggqd 1m 16Mi
kube-proxy-c244z 1m 22Mi
coredns-59b6bf8b4f-5zg5s 3m 24Mi
coredns-59b6bf8b4f-5x62d 3m 25Mi
currencyservice-7977f668dc-rvbwm 12m 32Mi
csi-azurefile-node-9fcx8 2m 38Mi
metrics-server-5f8d84558d-frsq4 4m 42Mi
metrics-server-5f8d84558d-rc5nj 4m 43Mi
csi-azuredisk-node-9fh7h 2m 46Mi
adservice-795589cf6f-xs66r 4m 87Mi
ama-metrics-node-54sfj 16m 249Mi
ama-logs-rs-6db98d6dff-vj4xw 13m 259Mi
ama-logs-w5bmd 12m 403Mi
通过运行 kubectl 描述节点 命令查看节点上每个 Pod 的请求和限制:
kubectl describe node <node-name>
此命令的输出类似于以下文本:
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits Age
--------- ---- ------------ ---------- --------------- ------------- ---
default adservice-795589cf6f-dgrx7 200m (10%) 300m (15%) 180Mi (3%) 300Mi (6%) 49m
default cartservice-6d994d9676-tcr6m 200m (10%) 300m (15%) 64Mi (1%) 128Mi (2%) 49m
default frontend-848d9f9dc9-x712b 100m (5%) 200m (10%) 64Mi (1%) 128Mi (2%) 49m
default loadgenerator-5c9656f8d6-7vmjr 300m (15%) 500m (26%) 256Mi (5%) 512Mi (11%) 38m
default redis-cart-799c85c644-vzpjl 70m (3%) 125m (6%) 200Mi (4%) 256Mi (5%) 49m
kube-system ama-logs-zs4qf 150m (7%) 1 (52%) 550Mi (12%) 1774Mi (38%) 16h
kube-system azure-ip-masq-agent-rqqpn 100m (5%) 500m (26%) 50Mi (1%) 250Mi (5%) 16h
kube-system cloud-node-manager-nbnrq 50m (2%) 0 (0%) 50Mi (1%) 512Mi (11%) 16h
kube-system coredns-59b6bf8b4f-m2prf 100m (5%) 3 (157%) 70Mi (1%) 500Mi (10%) 16h
kube-system csi-azuredisk-node-h445m 30m (1%) 0 (0%) 60Mi (1%) 400Mi (8%) 16h
kube-system csi-azurefile-node-489cp 30m (1%) 0 (0%) 60Mi (1%) 600Mi (13%) 16h
kube-system konnectivity-agent-665c7dfdb8-25p2f 20m (1%) 1 (52%) 20Mi (1%) 1Gi (22%) 15h
kube-system kube-proxy-v9gp4 100m (5%) 0 (0%) 0 (0%) 0 (0%) 16h
Allocated resources:
...
注意
节点的 CPU 或内存使用量百分比基于节点上的可分配资源,而不是实际的节点容量。
确定使用高内存的 Pod 后,可以识别在 Pod 上运行的应用程序。
步骤 2:查看避免内存饱和的最佳做法
请查看下表,了解如何实现避免内存饱和的最佳做法。
最佳做法 |
说明 |
使用内存 请求和限制 |
Kubernetes 提供了用于指定容器的最小内存大小(请求)和最大内存大小(限制)的选项。 通过在 Pod 上配置限制,可以避免节点上的内存压力。 请确保正在运行的所有 Pod 的聚合限制不超过节点的可用内存。 这种情况称为 过度使用。 Kubernetes 计划程序根据 通过服务质量 (QoS)设置请求和限制分配资源。 如果没有适当的限制,计划程序可能会在单个节点上规划过多的 Pod。 这最终可能会关闭节点。 此外,当 kubelet 逐出 Pod 时,它会优先处理内存使用量超过其定义的请求的 Pod。 建议将内存请求设置为接近实际使用情况。 |
启用水平 Pod 自动缩放程序 |
通过缩放群集,可以跨多个 Pod 均衡请求,以防止内存饱和。 此方法可以减少特定节点上的内存占用。 |
使用 反关联标记 |
对于内存不受设计限制的方案,可以使用节点选择器和相关性或反相关性标记,它们可将工作负载隔离到特定节点。 通过使用反相关性标记,可以阻止其他工作负载在这些节点上计划 Pod。 这可以减少内存饱和问题。 |
选择 更高的 SKU VM |
具有更多随机访问内存 (RAM) 的虚拟机 (VM) 更适合处理高内存使用率。 若要使用此选项,必须创建新的节点池,封锁节点(使其不可计划),并清空现有节点池。 |
隔离 系统和用户工作负荷 |
建议在用户节点池上运行应用程序。 此配置可确保你可以将特定于 Kubernetes 的 Pod 隔离到系统节点池中,并保持群集性能。 |
第三方信息免责声明
本文中提到的第三方产品由 Microsoft 以外的其他公司提供。 Microsoft 对这些产品的性能和可靠性不作任何明示或默示担保。
第三方联系人免责声明
Microsoft 会提供第三方联系信息来帮助你查找有关本主题的其他信息。 此联系信息可能会更改,恕不另行通知。 Microsoft 不保证第三方联系信息的准确性。
如果你有任何疑问或需要帮助,请创建支持请求或联系 Azure 社区支持。 你还可以将产品反馈提交到 Azure 反馈社区。