通過Docker程序pid獲取容器id

2021-09-21 20:54:37 字數 2017 閱讀 8249

雖然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 可以獲取容器的pid,通過docker ps可以獲取容器的容器id,因此可以將這兩個命令結合在一起,利用下面的命令列就可以解決: 1

但是第一種有乙個缺陷,那就是如果這個程序恰好是容器內程序的子程序,那麼這個程序就不會再在主機的namespace**現,因為只有容器的pid為1的程序才會在主機的namespace**現。因此就必須使用第二種方法。

第二種:在docker version 1.11後,增加了「containerd」,根據這個特性的實現方式可以直接通過此程序的父程序的cmdline找到它的容器id。這個方法的缺點就是不適用於docker version 1.11之前的版本。

根據這兩種特性,編寫了乙個python指令碼,用於發現:

1.查詢pid所對應的容器id,並列印容器的詳細資訊

2.獲取此程序的程序樹和含有命令列的程序樹

指令碼中還隱藏了一種根據程序推導出程序所占用埠號的函式。這個功能在此指令碼中用處不大,但在別處有用處。

由於指令碼內容比較長,因此可以從gitub上獲取此指令碼:

執行效果圖(如果看不清,請使用新標籤頁開啟檢視原圖)如下:

乙個第一種方法失敗的例子。

此時,就有必要借助第二種方法實現(如果看不清,請使用新標籤頁開啟檢視原圖)。

題外話:

關於init程序,「init程序是所有linux程序的父程序」,這句話其實是錯的!也許應該說init程序是所有linux使用者空間程序的父程序,pid 2 [kthreadd]是linux系統核心空間程序的父程序。除了2以外,3、4、5等也是特殊程序pid,它們的父程序都不是init。除此之外,0也是乙個特殊的程序,用於程序排程。

tag: 通過pid獲得容器id,容器namespace,如何查詢容器id

--end--

iOS獲取程序PID資訊

ios下獲取系統所有程序pid資訊,有需要的朋友可以參考下。在ios下獲取系統所有的程序pid 資訊 需要用到c部分的 以下 在xcode6 arc下執行測試通過 補充 必須包含的標頭檔案 include include include 返回所有正在執行的程序的 id,name,占用cpu,執行時間...

bash shell獲取程序的pid

前幾天在寫乙個指令碼時在獲取程序的pid時出現了一點點意外,當時的情境大概是這樣的 跑乙個任務a,然後任務b要監控a的狀態,一旦a結束,b也要結束。當初第一反應就是獲取b的pid然後判斷a是否在執行,如果沒有則kill掉b。可是當初就是不成功 用的是 於是迫於任務緊急換了一種笨方法 讓b的執行時間稍...

Linux 下獲取程序PID

linux查詢pid有多種方式,可通過遍歷 proc目錄下程序執行資訊及shell ps命令 1.遍歷 proc目錄 linux下每個執行的程序都會在 proc目錄下建立該程序pid目錄,proc pid 目錄下有 status,cmdline等描述程序執行引數,狀態等資訊.執行可能沒有命令列引數,...