top node、free、grafana 数据对不上

1. top 节点资源使用率超过 100%

kubectl top node

NAME            CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
master-1        995m         16%    13760Mi         118%
master-2        827m         13%    10672Mi         92%
master-3        889m         14%    10244Mi         88%

这是由于在计算使用率时,默认使用的是可分配的资源,排除了 Kubelet 保留的部分。在 kubectl 源码中可以看到:

for _, n := range nodes {
  if !o.ShowCapacity {
    availableResources[n.Name] = n.Status.Allocatable
  } else {
    availableResources[n.Name] = n.Status.Capacity
  }
}

如果需要查看节点总的资源使用情况,可添加 --show-capacity 参数:

kubectl top node --show-capacity

NAME            CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
master-1        1161m        14%    13822Mi         87%
master-2        998m         12%    10640Mi         67%
master-3        877m         10%    10298Mi         65%

实际上 Allocatable 和 Capacity 在节点对象上可以直接看到:

kubectl get node master-1  -oyaml

...
status:
  allocatable:
    cpu: "6"
    ephemeral-storage: "284333649859"
    hugepages-1Gi: "0"
    hugepages-2Mi: "0"
    memory: 11877928Ki
    pods: "110"
  capacity:
    cpu: "8"
    ephemeral-storage: 308521756Ki
    hugepages-1Gi: "0"
    hugepages-2Mi: "0"
    memory: 16174632Ki
    pods: "110"

在 Kubelet 的配置文件 /var/lib/kubelet/config.yaml 或者启动命令参数 --system-reserved=cpu=1,memory=2Gi --kube-reserved=cpu=1,memory=2Gi 可以查看具体的资源预留额度。详情可以参考 https://kubernetes.io/zh-cn/docs/tasks/administer-cluster/reserve-compute-resources/ 。

Allocatable = Capacity - Reserved - Evicted Threshold(驱逐容忍度),其中 Evicted Threshold 根据不同资源,通常为一个很小的数值或比例。

2. top node 与 Grafana 数据不一致

2.1 free 与 node_memory_Mem 同源

使用 free 查看节点资源使用情况如下:

free -h
              total        used        free      shared  buff/cache   available
Mem:          503Gi        62Gi       243Gi        12Gi       198Gi       426Gi
Swap:            0B          0B          0B

Grafana 节点资源使用情况如下:

图片

使用的 PromQL 为:

  • 总内存, node_memory_MemTotal_bytes{instance=~\"$node\"}

  • 已用, node_memory_MemTotal_bytes{instance=~\"$node\"} - node_memory_MemAvailable_bytes{instance=~\"$node\"}

从数值上看,free 与 Grafana 数据基本一致。

因为 Grafana 使用的 Node Exporter 采集的 node_memory_Mem 这些指标来自主机的 /proc/meminfo 与 free -h 的数据同源。

2.2 kubectl top 使用的是 metrics-server 采集的指标

kubectl top 查看节点资源使用情况

kubectl top node my-node-name
NAME           CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
my-node-name   4809m        8%     132883Mi        25%

模拟 top 命令向 metrics-server 请求数据:

kubectl get --raw /apis/metrics.k8s.io/v1beta1/nodes/my-node-name

{
    "kind": "NodeMetrics",
    "window": "10.292s",
    "usage": {
        "cpu": "5094380203n",
        "memory": "136278224Ki"
    }
}

这里的内存使用量约 130 Gi,130 / 503 = 25.8% 与 kubectl top node 基本一致。

2.3 metrics-server 的数据来自 Kubelet

从 metrics-server 的源码可以看到,其在请求 Kubelet 的数据。

func (kc *kubeletClient) GetMetrics(ctx context.Context, node *corev1.Node) (*storage.MetricsBatch, error) {
 port := kc.defaultPort
 path := "/metrics/resource"
 nodeStatusPort := int(node.Status.DaemonEndpoints.KubeletEndpoint.Port)
 if kc.useNodeStatusPort && nodeStatusPort != 0 {
  port = nodeStatusPort
 }
 if metricsPath := node.Annotations[AnnotationResourceMetricsPath]; metricsPath != "" {
  path = metricsPath
 }
 addr, err := kc.addrResolver.NodeAddress(node)
 if err != nil {
  return nil, err
 }
 url := url.URL{
  Scheme: kc.scheme,
  Host:   net.JoinHostPort(addr, strconv.Itoa(port)),
  Path:   path,
 }
 return kc.getMetrics(ctx, url.String(), node.Name)
}

模拟 metrics-server 向 Kubelet 请求数据

kubectl get --raw /api/v1/nodes/my-node-name/proxy/metrics/resource |grep node_

# HELP node_cpu_usage_seconds_total [ALPHA] Cumulative cpu time consumed by the node in core-seconds
# TYPE node_cpu_usage_seconds_total counter
node_cpu_usage_seconds_total 1.2683530100816046e+08 1721957059813
# HELP node_memory_working_set_bytes [ALPHA] Current working set of the node in bytes
# TYPE node_memory_working_set_bytes gauge
node_memory_working_set_bytes 1.39524251648e+11 1721957059813

符合预期,请求 metrics-server 与 Kubelet API 提供的监控数据相同。

2.4 node_memory_working_set_bytes 指标有什么不同

  • top 使用的是 node_memory_working_set_bytes,是 Kubelet 提供的指标

包括当前正在使用的内存,活跃的缓存,不包括可以被立即回收的缓存、缓冲区,主要是非活跃的文件缓存,其数据来源于 /sys/fs/cgroup

  • Grafana 使用的是 node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes,是 Node Exporter 提供的指标

包括当前正在使用的内存,但不包括缓存,其数据来源于 /proc/meminfo

前面可以看到 top 看到的内存使用量大约为 130 Gi,而 Grafana 看到的内存使用量大约是 77 Gi,相差 53 Gi 内存存储的就是一些不能立即被回收的缓存。但由于这两种方式的数据源不同,无法对 53 Gi 进行更详细的分析。

2.5 Kubelet limit 使用的是 container_memory_working_set_bytes

对于 Pod 来说,通过 top 和 Grafana 看到的内存使用量可能是相同的,因为,大部分 Grafana 面板绘制 Pod 内存使用量用的是 container_memory_working_set_bytes,这与 top 的计算方式是一致的。

这里需要重点关注的是 Kubelet 会以哪个指标驱逐 Pod? 答案是,container_memory_working_set_bytes 。

container_memory_working_set_bytes 更能代表容器的真实内存使用量。

下面这张图体现的是 container_memory_working_set_bytes (大约 18GiB) 与 container_memory_usage_bytes (大约 33GiB) 的区别。

图片

3. 总结

本文采集数据的主机内核版本为 5.4.0-48-generic,主要内容如下:

  • 因为 Kubelet 预留资源,top node 资源使用率可能超过 100%,使用 --show-capacity 可以看到总的资源使用情况

  • 常用的节点资源使用率 (node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes)/ node_memory_MemTotal_bytes ,因为忽略了活跃的缓存资源,所以使用率会比 top node 看到的低一些。上面例子大约是 Grafana 15% 使用率,top node 28% 的区别

  • Kubelet 对 Pod 驱逐使用的是 container_memory_working_set_bytes,与 top pod 看到的内存使用量相同

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Node-RED 是一个流程编排工具,用于将各种硬件设备、API和在线服务连接起来进行数据流的可视化和控制。它可通过可视化节点编排和拖拽方式的操作方便地构建数据流应用程序。 Grafana 是一个开源的数据可视化工具,它提供强大的图表和仪表盘功能,可以连接到各种不同数据源获取数据,并用图表展示这些数据,帮助用户更好地理解和分析数据Node-RED 提供了一个功能强大且易于使用的插件,可以实现与 Grafana 的集成。通过这个插件,我们可以将 Node-RED 的数据流输出连接到 Grafana,使得数据能够被 Grafana 动态地显示和更新。 要将 Node-RED 显示在 Grafana 上,首先我们需要确保已经正确安装了 Node-RED 和 Grafana。然后,在 Node-RED 中创建一个数据流,并将所需的数据处理和转换节点连接到数据源。接下来,在 Node-RED 的插件库中找到 Grafana 的插件,并将其添加到节点流中。 配置 Grafana 插件,输入 Grafana 的相关信息,如 Grafana 的主机地址、端口号以及凭证等。保存设置后,我们可以将输出连接到 Grafana,将数据传输到 Grafana 的图表和仪表盘上进行展示。 还可以根据需要,通过 Node-RED 的节点编排和数据处理功能,对数据进行进一步的操作、筛选和转换,以便在 Grafana 中更好地展示。 通过以上步骤,我们可以实现 Node-RED 与 Grafana 的集成,将 Node-RED 的数据流显示在 Grafana 上,从而实现数据的可视化和分析。这种集成方式不仅简单易用,还能实现实时动态的数据展示,帮助用户更好地理解和利用数据
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值