前言

在管理 Kubernetes 集群的过程中,我们经常会遇到这样一种情况:在某台节点上发现某个进程资源占用量很高,却又不知道是哪个容器里的进程。有没有办法可以根据进程 PID 快速找到 Pod 名称呢?

解决

假设现在有一个 prometheus 进程的 PID14338

要获取容器的 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

可以看到该进程对应的容器 IDd6f24b62...,可以再优化一下上面的命令,直接获取容器 ID

$ CID=$(cat /proc/14338/cgroup | awk -F '/' '{print $5}')

$ echo ${CID:0:8}
d6f24b62

运行时为:containerd、crio

最后一步根据容器 ID 获取 Pod 名称,如果你的容器运行时是 containerdcrio,可以使用 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 名称的更多相关文章

  1. Kubernetes 教程:根据 PID 获取 Pod 名称

    原文链接:https://fuckcloudnative.io/posts/find-kubernetes-pod-info-from-process-id/ 在管理 Kubernetes 集群的过程 ...

  2. delphi根据进程PID获取程序所在路径的函数(用OpenProcess取得句柄,用GetModuleFileNameEx取得程序名)

    uses psapi; {根据进程PID获取程序所在路径的函数}function GetProcessExePath(PID: Cardinal): string;varpHandle: THandl ...

  3. 内核中通过进程PID获取进程的全部路径

    目录 一丶简介 二丶原理 1.原理 2.代码实现. 一丶简介 我们遇到的Dos路径.如果想转化为NT路径(也就是 C:\xxxx)类似的格式 需要自己实现. 具体原理如下: 二丶原理 1.原理 1.使 ...

  4. 内核中根据进程Pid获取卷的全目录

    目录 一丶简介 二丶原理 3.代码实现. 一丶简介 在内核中有时候想通过PID 获取进程的全路径以达到监控的作用 比如我们设置了进程回调.则可以根据PID看下进程的全路径. 二丶原理 原理就是在内核中 ...

  5. Bash Shell 获取进程 PID

    转载地址:http://weyo.me/pages/techs/linux-get-pid/ 导读 Linux 的交互式 Shell 与 Shell 脚本存在一定的差异,主要是由于后者存在一个独立的运 ...

  6. linux命令(26):Bash Shell 获取进程 PID

    转载地址:http://weyo.me/pages/techs/linux-get-pid/ 根据pid,kill该进程:http://www.cnblogs.com/lovychen/p/54113 ...

  7. Atitit,通过pid获取进程文件路径 java php  c#.net版本大总结

    Atitit,通过pid获取进程文件路径 java php  c#.net版本大总结 1. 通过PID获取进程路径的几种方法2 1.1. GetModuleFileNameEx 想获得进程可执行文件的 ...

  8. 014-交互式Shell和shell脚本获取进程 pid

    Linux 的交互式 Shell 与 Shell 脚本存在一定的差异,主要是由于后者存在一个独立的运行进程 1.交互式 Bash Shell 获取进程 pid 在已知进程名(name)的前提下,交互式 ...

  9. 通过PID获取进程路径的几种方法

    通过PID获取进程路径的几种方法 想获得进程可执行文件的路径最常用的方法是通过GetModuleFileNameEx函数获得可执行文件的模块路径这个函数从Windows NT 4.0开始到现在的Vis ...

  10. linux: 获取监听指定端口的进程PID

    在 linux 下经常需要杀死(重启)监听某端口的进程, 因此就写了一个小脚本, 通过 ss 命令获取监听制定端口的进程 PID, 然后通过 kill 命令结束掉进程: #!/bin/sh # set ...

随机推荐

  1. 如何控制bean的加载顺序?

    写在前面 springboot遵从约定大于配置的原则,极大程度的解决了配置繁琐的问题.在此基础上,又提供了spi机制,用spring.factories可以完成一个小组件的自动装配功能. 在一般业务场 ...

  2. Qt/C++音视频开发74-合并标签图形/生成yolo运算结果图形/文字和图形合并成一个/水印滤镜

    一.前言 在使用yolo做人工智能运算后,运算结果除了一个方框,还可能需要增加文字显示在对应方框上,以便标记是何种物体,比如显示是人还是动物,或者还有可能追踪人员,显示该人员的姓名.这种应用场景非常普 ...

  3. 记一次 .NET某电商医药网站 CPU爆高分析

    一:背景 1. 讲故事 准备明年把.NET高级调试的训练营的课程进行重构,采用案例引导式,而CPU爆高类有不少是程序员在写代码的时候不注意时间复杂度,在数据量稍微大一点的情况直接幻化成了死循环,时间复 ...

  4. react之Lazy和Suspense(懒加载)

    React.lazy React.lazy 函数能让你像渲染常规组件一样处理动态引入(的组件). 什么意思呢? 其实就是懒加载. 其原理就是利用es6 import()函数.这个import不是imp ...

  5. Kernel Memory 让 SK 记住更多内容

    Kernel Memory (KM) 是一种多模态 AI 服务,专注于通过自定义的连续数据混合管道高效索引数据集.它支持检索增强生成(RAG).合成记忆.提示工程以及自定义语义记忆处理.KM 支持自然 ...

  6. Ps cs4 -把GIF背景变透明-简单操作,还可以将视频转换GIF

    准备软件: 1.Ps cs4 2.QuickTime Player 7.74 开始: 1. 2.弹出文件选择框,但是发现不能选择GIF格式. 3.没关系,在文件名框输入*.*回车,就发现可以选择GIF ...

  7. idea社区版本创建springboot项目的三种方式

    文章目录一.前言一.方式1:spring 官方创建 springboot项目1.打开在线的 spring initializr2.选择项目的语言.版本.依赖等3. 解压源码包,并使用IDEA打开4.测 ...

  8. Nacos、Apollo、SpringCloud Config微服务配置中心对比

    1为什么需要配置中心 配置实时生效: 传统的静态配置方式要想修改某个配置只能修改之后重新发布应用,要实现动态性,可以选择使用数据库,通过定时轮询访问数据库来感知配置的变化.轮询频率低感知配置变化的延时 ...

  9. C语言中的窗口滑动技术

    学习文章:C语言中的窗口滑动技术 滑动窗口法 C语言中的窗口滑动技术 循环几乎是每个复杂问题的一部分.太多的循环/嵌套循环会增加所需的时间,从而增加程序的时间复杂性.窗口滑动技术是一种计算技术,用于减 ...

  10. Permutation Swaps

    Permutation Swaps 传送门 题目理解 第一个操作:把第i个数移到位置p[i](1<=i<=n) ​发现:这个操作其实就是循环移位,有Teleporter的经验在前,此操作可 ...