问题

因为业务原因会把 log 写入到 pod 里,同时控制台也会打印一份,而我们的日志搜集都是统一使用 filebeat 从主机层面进行收集控制台日志,pod 里的日志是无用的,也没有挂载外部存储,为了避免 pod 日志膨胀把 node 节点磁盘打满,于是做了个 pod 磁盘占用的 Grafana 大盘,但是过程中发现有些集群没有这个指标。

发现问题

在 Grafana 中,根据公式

1
sum by( pod ) (container_fs_usage_bytes{k8s="$k8s", env="$env", project="$project", pod != "" })

来查询,部分集群无数据,有些集群有数据,但是只有 node 节点,pod 标签的值是空的。

image.png

没有 pod 标签,只能根据 instance 进行聚合。

排查问题

先到 Prometheus 进行查询数据:
image.png
可以看到数据里面确实没有 pod 标签,自然也取不到 pod 级别的磁盘使用情况。

然后使用 kubectl 查看原始数据:

1
2
3
4
kubectl get --raw \
'/api/v1/nodes/cn-beijing.172.25.3.175/proxy/metrics/cadvisor' \
| grep '^container_fs_usage_bytes' \
| head -50

得到的结果是:
image.png

可以看到原始的数据就没有 pod 信息,而 Grafana 正常的集群,查到的 pod 标签就有值,比如下面(腾讯云 TKE):

image.png

原因

根因是因为 container_fs_usage_bytes 这个指标,在 docker 运行时环境下, docker plugin 有 diskUsage 的实现,但是 containerd plugin 没有,所以不能使用,而腾讯云 TKE 可以,是因为腾讯对 containerd 做了入侵,而阿里云、华为云和社区是对齐的。

社区版的相关 issues:https://github.com/google/cadvisor/issues/3495

解决

可以换一个接口来取数据,使用:

1
2
3
4
5
6
7
8
9
10
kubectl get --raw '/api/v1/nodes/cn-beijing.172.24.1.54/proxy/stats/summary'

# 或者直接请求kubelet接口,需要携带证书
curl -k https://172.24.1.54:10250/stats/summary \
--cert /etc/kubernetes/pki/apiserver-kubelet-client.crt \
--key /etc/kubernetes/pki/apiserver-kubelet-client.key

# 或者使用 ServiceAccount Bearer Token 访问
curl -k -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
https://172.24.1.54:10250/stats/summary

放到业务上使用,可以自行开发一个 exporter,然后将数据接入即可(随便找个 AI 写一个就行)。