通过Docker进程pid获取容器id

    虽然Docker是通过namespace隔离技术实现容器间进程的隔离,但在运行Docker的主机中,Docker容器内的进程与主机内运行的进程是在同一个namespace(假设叫A)的。虽然在Docker容器内应用进程的父进程都是pid为1的那个进程(这些进程都是单独的namespace,这个namespace与前面提到的namespace不是同一个,此处假设为B),但在namespace A中Docker内容器实际的父进程都是Docker daemon,由于父进程具有对子进程管理的能力,而子进程不能影响到父进程也不能影响到其他namespace的进程,所以能实现进程隔离。

    由于Docker容器内的进程与主机内运行的进程是在同一个namespace,所以在主机中使用ps -ef命令可以查找出当前系统中运行的所有进程,这些进程包含了完整的与Docker有关的所有进程,在这个namespace中,这些进程的父进程(不管是父进程还是父父进程)都包含Docker daemon,因此可以从Docker容器某进程的pid开始,一直找到主机的init进程。

    有时我们需要根据docker容器进程的pid找到这个容器的容器id,这时通过Linux系统自带的基础命令是无法完成这一操作的。但要想通过pid获取容器id,办法还是有的。其中有两种可行的办法。

    第一种根据:docker inspect <CONTAINER ID>可以获取容器的pid,通过docker ps可以获取容器的容器id,因此可以将这两个命令结合在一起,利用下面的命令行就可以解决:

1
docker inspect -f  '``.`State`.`Pid` ``.`Id`'  $(docker  ps  -a -q) |  grep  <pid>

 image

    但是第一种有一个缺陷,那就是如果这个进程恰好是容器内进程的子进程,那么这个进程就不会再在主机的namespace中出现,因为只有容器的pid为1的进程才会在主机的namespace中出现。因此就必须使用第二种方法。

    第二种:在Docker Version 1.11后,增加了“containerd”,根据这个特性的实现方式可以直接通过此进程的父进程的cmdline找到它的容器id。这个方法的缺点就是不适用于Docker Version 1.11之前的版本。

    根据这两种特性,编写了一个Python脚本,用于发现:

    1.查找pid所对应的容器id,并打印容器的详细信息

    2.获取此进程的进程树和含有命令行的进程树

    脚本中还隐藏了一种根据进程推导出进程所占用端口号的函数。这个功能在此脚本中用处不大,但在别处有用处。

    由于脚本内容比较长,因此可以从Gitub上获取此脚本:https://github.com/DingGuodong/LinuxBashShellScriptForOps/tree/master/projects/LinuxSystemOps/SoftwareManagement/docker

运行效果图(如果看不清,请使用新标签页打开图片查看原图)如下:

Docker Server Version < 1.11

image

一个第一种方法失败的例子。

image

此时,就有必要借助第二种方法实现(如果看不清,请使用新标签页打开图片查看原图)

image 

题外话:

    关于init进程,“init进程是所有Linux进程的父进程”,这句话其实是错的!也许应该说init进程是所有Linux用户空间进程的父进程,pid 2 [kthreadd]是Linux系统内核空间进程的父进程。除了2以外,3、4、5等也是特殊进程pid,它们的父进程都不是init。除此之外,0也是一个特殊的进程,用于进程调度。

tag: 通过pid获得容器id,容器namespace,如何查找容器id

--end--




本文转自 urey_pp 51CTO博客,原文链接:http://blog.51cto.com/dgd2010/1864913,如需转载请自行联系原作者


优秀的个人博客,低调大师

微信关注我们

原文链接:https://yq.aliyun.com/articles/426895

转载内容版权归作者及来源网站所有!

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

相关文章

发表评论

资源下载

更多资源
Mario,低调大师唯一一个Java游戏作品

Mario,低调大师唯一一个Java游戏作品

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Apache Tomcat7、8、9(Java Web服务器)

Apache Tomcat7、8、9(Java Web服务器)

Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、Sun 和其他一些公司及个人共同开发而成。因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器。

Java Development Kit(Java开发工具)

Java Development Kit(Java开发工具)

JDK是 Java 语言的软件开发工具包,主要用于移动设备、嵌入式设备上的java应用程序。JDK是整个java开发的核心,它包含了JAVA的运行环境(JVM+Java系统类库)和JAVA工具。

Sublime Text 一个代码编辑器

Sublime Text 一个代码编辑器

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。