如何在运行Pod的节点上无需kubectl、不访问K8s远程库获取Pod名称与命名空间
从Kubernetes节点本地获取Pod元数据的方案
本地获取Pod名称、命名空间、完整配置的方法
所有方法均不需要调用Kubernetes apiserver,也不需要使用kubectl,完全在节点本地即可完成:
- 调用kubelet本地只读接口
kubelet默认在节点本地开启10255端口的只读HTTP服务,存储了当前节点所有运行中Pod的完整元数据,直接请求即可获取:
返回结果为JSON格式,包含每个Pod的名称、命名空间、Pod UUID、spec配置、运行状态等所有信息,可直接和你从cgroup路径中拿到的Pod UUID做匹配,需要YAML格式的话自行做格式转换即可。curl http://127.0.0.1:10255/pods - 调用本地容器运行时接口
所有Kubernetes启动的Pod和容器都会在本地容器运行时中存储标准元数据标签,直接用容器运行时命令即可查询:
若使用containerd作为运行时:
若使用docker作为运行时:# 列出所有Pod的UUID、名称、命名空间 crictl pods -o wide # 根据Pod UUID查询完整配置信息 crictl inspectp <你的Pod UUID># 根据Pod UUID查询对应容器的Pod名称、命名空间标签 docker inspect $(docker ps -q) --filter label=io.kubernetes.pod.uid=<你的Pod UUID> --format '{{.Config.Labels.io.kubernetes.pod.name}} {{.Config.Labels.io.kubernetes.pod.namespace}}' - 读取kubelet本地缓存目录
kubelet会将当前节点分配到的Pod元数据缓存到本地目录,路径格式为/var/lib/kubelet/pods/<你的Pod UUID>/,目录下可直接找到Pod的相关配置文件、挂载的Secret/ConfigMap内容。
为什么Pod元数据没有直接存储在cgroup路径中
该设计是Kubernetes出于可靠性和兼容性的考量:
- cgroup路径存在长度限制,Pod名称、命名空间为可变长度字符串,若直接放入路径很容易触发长度超限问题,导致Pod创建失败
- Pod名称、命名空间在集群层面不唯一,只有Pod UUID是全局唯一标识,用UUID作为cgroup路径的核心标识可完全避免重名冲突
- 避免元数据不一致问题:Pod的配置在运行中可能更新,而cgroup路径创建后无法修改,若在路径中存储静态元数据会出现数据不一致的情况
指标采集的落地建议
你完全可以在节点本地运行单进程完成全量指标采集,不需要外部后处理:采集进程定时从kubelet 10255端口拉取一次本节点Pod元数据,在内存中维护Pod UUID到名称、命名空间的映射关系,采集cgroup指标时直接用内存中的映射表匹配即可,该方案是目前所有主流K8s监控采集组件(Cadvisor、Datadog Agent、Prometheus Agent)的标准实现,额外开销极低。
内容的提问来源于stack exchange,提问作者xakepp35
相关产品推荐
相关产品推荐

