Kubernetes:根据进程 Pid 获取 Pod 名称
前言
在管理 Kubernetes 集群的过程中,我们经常会遇到这样一种情况:在某台节点上发现某个进程资源占用量很高,却又不知道是哪个容器里的进程。有没有办法可以根据进程 PID 快速找到 Pod 名称呢?
解决
假设现在有一个 prometheus 进程的 PID 是 14338:
要获取容器的 ID,可以查看 PID 对应的 cgroup 信息:
cat /proc/14338/cgroup
11:blkio:/kubepods/burstable/pod8e018a8e-4aaa-4ac6-986a-1a5133a4bcf1/d6f24b62ea28e9e67f7bc06f98de083cc49454f353389cd396f5d3ac6448f19c
10:cpuset:/kubepods/burstable/pod8e018a8e-4aaa-4ac6-986a-1a5133a4bcf1/d6f24b62ea28e9e67f7bc06f98de083cc49454f353389cd396f5d3ac6448f19c
9:freezer:/kubepods/burstable/pod8e018a8e-4aaa-4ac6-986a-1a5133a4bcf1/d6f24b62ea28e9e67f7bc06f98de083cc49454f353389cd396f5d3ac6448f19c
8:hugetlb:/kubepods/burstable/pod8e018a8e-4aaa-4ac6-986a-1a5133a4bcf1/d6f24b62ea28e9e67f7bc06f98de083cc49454f353389cd396f5d3ac6448f19c
7:perf_event:/kubepods/burstable/pod8e018a8e-4aaa-4ac6-986a-1a5133a4bcf1/d6f24b62ea28e9e67f7bc06f98de083cc49454f353389cd396f5d3ac6448f19c
6:cpuacct,cpu:/kubepods/burstable/pod8e018a8e-4aaa-4ac6-986a-1a5133a4bcf1/d6f24b62ea28e9e67f7bc06f98de083cc49454f353389cd396f5d3ac6448f19c
5:pids:/kubepods/burstable/pod8e018a8e-4aaa-4ac6-986a-1a5133a4bcf1/d6f24b62ea28e9e67f7bc06f98de083cc49454f353389cd396f5d3ac6448f19c
4:devices:/kubepods/burstable/pod8e018a8e-4aaa-4ac6-986a-1a5133a4bcf1/d6f24b62ea28e9e67f7bc06f98de083cc49454f353389cd396f5d3ac6448f19c
3:net_prio,net_cls:/kubepods/burstable/pod8e018a8e-4aaa-4ac6-986a-1a5133a4bcf1/d6f24b62ea28e9e67f7bc06f98de083cc49454f353389cd396f5d3ac6448f19c
2:memory:/kubepods/burstable/pod8e018a8e-4aaa-4ac6-986a-1a5133a4bcf1/d6f24b62ea28e9e67f7bc06f98de083cc49454f353389cd396f5d3ac6448f19c
1:name=systemd:/kubepods/burstable/pod8e018a8e-4aaa-4ac6-986a-1a5133a4bcf1/d6f24b62ea28e9e67f7bc06f98de083cc49454f353389cd396f5d3ac6448f19c
可以看到该进程对应的容器 ID 为 d6f24b62...,可以再优化一下上面的命令,直接获取容器 ID:
$ CID=$(cat /proc/14338/cgroup | awk -F '/' '{print $5}')
$ echo ${CID:0:8}
d6f24b62
运行时为:containerd、crio
最后一步根据容器 ID 获取 Pod 名称,如果你的容器运行时是 containerd 或 crio,可以使用 crictl 来获取容器信息:
# 使用 Go template 或 jq 都能获取 Pod 名称,看个人喜好。
# Go Template
$ crictl inspect -o go-template --template='{{index .status.labels "io.kubernetes.pod.name"}}' d6f24b62
prometheus-k8s-0
# jq
$ crictl inspect d6f24b62|jq '.status.labels["io.kubernetes.pod.name"]'
"prometheus-k8s-0"
运行时为:Docker
如果你的容器运行时是 Docker,可以使用命令行工具 docker 来获取,方法和上面类似。
$ docker inspect d6f24b62 | jq '.[0].Config.Labels."io.kubernetes.pod.name"'
"prometheus-k8s-0"
一种特殊情况的处理,上面的方法适用于大多数场景。但有可能你的 cat /proc/14338/cgroup 输出的结果是这样的:
$ cat /proc/14338/cgroup
11:blkio:/kubepods/burstable/pod8e018a8e-4aaa-4ac6-986a-1a5133a4bcf1/docker-d6f24b62ea28e9e67f7bc06f98de083cc49454f353389cd396f5d3ac6448f19c
10:cpuset:/kubepods/burstable/pod8e018a8e-4aaa-4ac6-986a-1a5133a4bcf1/docker-d6f24b62ea28e9e67f7bc06f98de083cc49454f353389cd396f5d3ac6448f19c
9:freezer:/kubepods/burstable/pod8e018a8e-4aaa-4ac6-986a-1a5133a4bcf1/docker-d6f24b62ea28e9e67f7bc06f98de083cc49454f353389cd396f5d3ac6448f19c
......
这时你就需要将上面取容器 ID 的方法稍做修改:
$ cat /proc/d6f24b62/cgroup | awk -F '/' '{print $5}'|sed 's/docker-//g'
11:blkio:/kubepods/burstable/pod8e018a8e-4aaa-4ac6-986a-1a5133a4bcf1/d6f24b62ea28e9e67f7bc06f98de083cc49454f353389cd396f5d3ac6448f19c
10:cpuset:/kubepods/burstable/pod8e018a8e-4aaa-4ac6-986a-1a5133a4bcf1/d6f24b62ea28e9e67f7bc06f98de083cc49454f353389cd396f5d3ac6448f19c
9:freezer:/kubepods/burstable/pod8e018a8e-4aaa-4ac6-986a-1a5133a4bcf1/d6f24b62ea28e9e67f7bc06f98de083cc49454f353389cd396f5d3ac6448f19c
go script 脚本
package main
import (
"fmt"
"github.com/bitfield/script"
"log"
"os"
)
func main() {
if len(os.Args) < 2 {
log.Fatal("请传递一个 PID 作为参数")
}
pid := os.Args[1]
data, err := script.File(fmt.Sprintf("/proc/%s/cgroup", pid)).Exec("awk -F '/' '{print $5}'").String()
if err != nil {
panic(err)
}
cid := data[7:19]
podName, err := script.Exec(fmt.Sprintf("docker inspect %s", cid)).JQ(".[0].Config.Labels.\"io.kubernetes.pod.name\"").String()
if err != nil {
panic(err)
}
fmt.Println(podName)
podNameSpace, err := script.Exec(fmt.Sprintf("docker inspect %s", cid)).JQ(".[0].Config.Labels.\"io.kubernetes.pod.namespace\"").String()
if err != nil {
panic(err)
}
fmt.Println(podNameSpace)
}
根据 Pid 获取 K8s Pod 名称,Shell 脚本
$ vim pod_name_info.sh
#!/usr/bin/env bash
Check_jq() {
which jq &> /dev/null
if [ $? != 0 ];then
echo -e "\033[32;32m 系统没有安装 jq 命令,请参考下面命令安装! \033[0m \n"
echo -e "\033[32;32m Centos 或者 RedHat 请使用命令 yum install jq -y 安装 \033[0m"
echo -e "\033[32;32m Ubuntu 或者 Debian 请使用命令 apt-get install jq -y 安装 \033[0m"
exit 1
fi
}
Pod_name_info() {
CID=`cat /proc/${pid}/cgroup | head -1 | awk -F '/' '{print $5}'`
CID=$(echo ${CID:0:8})
docker inspect $CID | jq '.[0].Config.Labels."io.kubernetes.pod.name"'
}
pid=$1
Check_jq
Pod_name_info
上面 Shell 脚本需要服务器上安装 jq 命令,因为脚本依赖 jq 来处理 json 格式。
简单介绍下 jq
jq 是一款命令行下处理 JSON 数据的工具。其可以接受标准输入,命令管道或者文件中的 JSON 数据,经过一系列的过滤器(filters)和表达式的转后形成我们需要的数据结构并将结果输出到标准输出中。jq 的这种特性使我们可以很容易地在 Shell 脚本中调用它。
运行方式
# 通过 Pid 获取 Pod 名称
$ ./pod_name_info.sh Pid

根据 Pod 名称获取 Pid,Shell脚本
$ vim pod_pid_info.sh
#!/usr/bin/env bash
Check_jq() {
which jq &> /dev/null
if [ $? != 0 ];then
echo -e "\033[32;32m 系统没有安装 jq 命令,请参考下面命令安装! \033[0m \n"
echo -e "\033[32;32m Centos 或者 RedHat 请使用命令 yum install jq -y 安装 \033[0m"
echo -e "\033[32;32m Ubuntu 或者 Debian 请使用命令 apt-get install jq -y 安装 \033[0m"
exit 1
fi
}
Pid_info() {
docker_storage_location=`docker info | grep 'Docker Root Dir' | awk '{print $NF}'`
for docker_short_id in `docker ps | grep ${pod_name} | grep -v pause | awk '{print $1}'`
do
docker_long_id=`docker inspect ${docker_short_id} | jq ".[0].Id" | tr -d '"'`
cat ${docker_storage_location}/containers/${docker_long_id}/config.v2.json | jq ".State.Pid"
done
}
pod_name=$1
Check_jq
Pid_info
运行方式
# 通过 Pod名称 获取 Pid
$ ./pod_pid_info.sh Pod名称

巨人的肩膀
https://www.hi-linux.com/posts/1620.html
https://mp.weixin.qq.com/s/77v46oIraV22acC8eYqC5A
https://mp.weixin.qq.com/s/HF5rzr5fULiMWq1NPe780g
Kubernetes:根据进程 Pid 获取 Pod 名称的更多相关文章
- Kubernetes 教程:根据 PID 获取 Pod 名称
原文链接:https://fuckcloudnative.io/posts/find-kubernetes-pod-info-from-process-id/ 在管理 Kubernetes 集群的过程 ...
- delphi根据进程PID获取程序所在路径的函数(用OpenProcess取得句柄,用GetModuleFileNameEx取得程序名)
uses psapi; {根据进程PID获取程序所在路径的函数}function GetProcessExePath(PID: Cardinal): string;varpHandle: THandl ...
- 内核中通过进程PID获取进程的全部路径
目录 一丶简介 二丶原理 1.原理 2.代码实现. 一丶简介 我们遇到的Dos路径.如果想转化为NT路径(也就是 C:\xxxx)类似的格式 需要自己实现. 具体原理如下: 二丶原理 1.原理 1.使 ...
- 内核中根据进程Pid获取卷的全目录
目录 一丶简介 二丶原理 3.代码实现. 一丶简介 在内核中有时候想通过PID 获取进程的全路径以达到监控的作用 比如我们设置了进程回调.则可以根据PID看下进程的全路径. 二丶原理 原理就是在内核中 ...
- Bash Shell 获取进程 PID
转载地址:http://weyo.me/pages/techs/linux-get-pid/ 导读 Linux 的交互式 Shell 与 Shell 脚本存在一定的差异,主要是由于后者存在一个独立的运 ...
- linux命令(26):Bash Shell 获取进程 PID
转载地址:http://weyo.me/pages/techs/linux-get-pid/ 根据pid,kill该进程:http://www.cnblogs.com/lovychen/p/54113 ...
- Atitit,通过pid获取进程文件路径 java php c#.net版本大总结
Atitit,通过pid获取进程文件路径 java php c#.net版本大总结 1. 通过PID获取进程路径的几种方法2 1.1. GetModuleFileNameEx 想获得进程可执行文件的 ...
- 014-交互式Shell和shell脚本获取进程 pid
Linux 的交互式 Shell 与 Shell 脚本存在一定的差异,主要是由于后者存在一个独立的运行进程 1.交互式 Bash Shell 获取进程 pid 在已知进程名(name)的前提下,交互式 ...
- 通过PID获取进程路径的几种方法
通过PID获取进程路径的几种方法 想获得进程可执行文件的路径最常用的方法是通过GetModuleFileNameEx函数获得可执行文件的模块路径这个函数从Windows NT 4.0开始到现在的Vis ...
- linux: 获取监听指定端口的进程PID
在 linux 下经常需要杀死(重启)监听某端口的进程, 因此就写了一个小脚本, 通过 ss 命令获取监听制定端口的进程 PID, 然后通过 kill 命令结束掉进程: #!/bin/sh # set ...
随机推荐
- 解决pip命令报错及Python环境配置指南:从安装到优化
1. 错误日志 当我在 Linux 机器(使用 Debian 或 Ubuntu 或衍生发行版)上运行 pip install xyz 时,会出现这样的错误: error: externally-man ...
- 学习破解一个Android程序
首先编写一个android测试程序 功能:校验用户名和注册码,成功则弹出注册成功提示 以下仅给出关键部分的代码 res/layout/activity_main.xml <?xml versio ...
- Datawhale 2025冬令营“嬛嬛,我来啦!”😘
Datawhale2025冬令营 Datawhale 2025 AI冬令营链接:https://www.datawhale.cn/activity/110/21/76?rankingPage=1 赠送 ...
- 在jooq的POJO类中使用Lombok的Data注解
jooq生成pojo类的配置根据官方给的如下: https://www.jooq.org/doc/3.14/manual/getting-started/tutorials/jooq-in-7-ste ...
- SQL统计数据之总结
一.查询SQL SELECT t1.规则编号 AS 编码, t1.规则描述 AS 名称, SUM( CASE WHEN t3.DATA_SOURCES = '00' THEN 1 ELSE 0 END ...
- mybatis中的数据源和连接池
1.核心配置文件中配置数据库相关属性 <?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE con ...
- DataV Note:让数据自己讲故事
您是否常常因为面对那些充满各类指标的汇报报告而感到困扰?我们或许能帮到您! 「我们是一家国内的服装公司,财年结束了,公司的销售团队需要对公司的销售数据进行分析,以指导下个财年的作战方向」 「我是浙 ...
- Q:linux(群晖)修改网卡速率
问题:群晖速度莫名其妙变成了1MB/s左右,查看网络状态 网卡配置变成 全双工10Mb/s 解决方法 首先开启ssh登录权限 1.控制面板 – 终端机和SNMP里,开启SSH功能. 2.通过ssh连接 ...
- 使用iceberg-使用Iceberg数据湖需要注意的点
一.资料准备 1.mysql地址选择 因为阿里云只读节点binlog保留时间短,需要用读写集群地址.可以登录阿里云控制台查看地址是只读还是读写,不清楚的话可以找dba要读写地址. 二.Iceberg概 ...
- 使用Docker编译安装运行Doris
一.编译源码 (1)拉取编译镜像docker pull apache/incubator-doris:build-env-1.2 (2)Mac电脑上拉取源码git clone https://gith ...