目錄
引言
1 基礎概念回顧
1.1 命名空間概述
1.2 命名空間的類型
2 PID命名空間詳解
2.1 PID命名空間的概念
2.2 PID命名空間的作用
2.3 PID命名空間的工作原理
2.3.1 PID命名空間的創建與銷毀
2.3.2 PID命名空間的層次結構
2.3.3 PID命名空間的進程ID映射
3 PID命名空間在Docker中的應用
3.1 Docker容器中的PID命名空間
3.2 PID命名空間與容器生命周期
3.3 PID命名空間與容器資源限制
4 PID命名空間的工作流程
5 PID命名空間的操作示例
6 總結
引言
在容器化技術中,Docker憑借其輕量級、高效隔離和快速部署等特性,成為了應用部署和管理的首選方案。而命名空間(Namespace)作為Docker實現資源隔離的核心技術之一,為容器提供了獨立的運行環境。其中,PID命名空間(PID Namespace)作為命名空間的一種,負責隔離進程ID,使得容器內的進程與宿主機及其他容器內的進程相互獨立。
1 基礎概念回顧
1.1 命名空間概述
命名空間是Linux內核提供的一種資源隔離機制,它允許將全局資源(如進程ID、用戶ID、網絡接口等)封裝在一個獨立的命名空間中,使得不同命名空間內的進程無法直接訪問或干擾其他命名空間內的資源。命名空間為容器提供了獨立的運行環境,使得容器內的進程就像運行在一個獨立的操作系統中一樣。
1.2 命名空間的類型
Linux內核提供了多種類型的命名空間,每種命名空間負責隔離不同類型的資源。常見的命名空間類型包括:
- Mount Namespace:隔離文件系統掛載點
- UTS Namespace:隔離主機名和域名
- IPC Namespace:隔離進程間通信資源(如消息隊列、共享內存等)
- PID Namespace:隔離進程ID
- Network Namespace:隔離網絡接口、IP地址、路由表等網絡資源
- User Namespace:隔離用戶ID和組ID
2 PID命名空間詳解
2.1 PID命名空間的概念
PID命名空間用于隔離進程ID,使得每個命名空間內的進程都有自己獨立的進程ID空間。在PID命名空間中,進程ID從1開始重新編號,因此不同命名空間內的進程可以有相同的進程ID。PID命名空間為 容器提供了獨立的進程管理環境,使得容器內的進程無法直接訪問或干擾宿主機或其他容器內的進程。
2.2 PID命名空間的作用
- 進程隔離:PID命名空間使得容器內的進程與宿主機及其他容器內的進程相互獨立,提高了系統的安全性
- 進程管理:在容器內,進程管理工具(如ps、top等)只能看到當前命名空間內的進程,無法看到其他命名空間內的進程
- 資源限制:通過PID命名空間,可以限制容器內可以運行的進程數量,防止容器內進程過多導致系統資源耗盡
2.3 PID命名空間的工作原理
2.3.1 PID命名空間的創建與銷毀
- 在Docker中,每個容器都會創建一個新的PID命名空間
- 當容器啟動時,Docker會調用Linux內核的clone()或unshare()系統調用,創建一個新的PID命名空間,并將容器內的初始進程(通常是/sbin/init或應用程序的入口進程)放入該命名空間中
- 當容器停止時,Docker會銷毀該PID命名空間,釋放相關資源
2.3.2 PID命名空間的層次結構
- PID命名空間具有層次結構,每個命名空間都有一個父命名空間
- 子命名空間內的進程可以看到父命名空間內的進程(但反之則不行),這種層次結構使得進程管理更加靈活
- 在Docker中,容器內的進程可以通過nsenter命令進入宿主機的PID命名空間,但宿主機上的進程無法直接進入容器的PID命名空間
2.3.3 PID命名空間的進程ID映射
- 在PID命名空間中,進程ID從1開始重新編號
- 為了實現進程ID在不同命名空間之間的映射,Linux內核維護了一個進程ID映射表
- 當進程在不同命名空間之間切換時,內核會根據映射表將進程ID轉換為目標命名空間中的進程ID
3 PID命名空間在Docker中的應用
3.1 Docker容器中的PID命名空間
- 在Docker容器中,每個容器都有一個獨立的PID命名空間
- 容器內的進程無法直接訪問宿主機或其他容器內的進程,實現了進程隔離
- 容器內的進程管理工具(如ps、top等)只能看到當前容器內的進程,無法看到其他容器或宿主機上的進程
3.2 PID命名空間與容器生命周期
- PID命名空間與容器的生命周期緊密相關
- 當容器啟動時,Docker會創建一個新的PID命名空間
- 當容器停止時,Docker會銷毀該PID命名空間
3.3 PID命名空間與容器資源限制
- 通過PID命名空間,Docker可以限制容器內可以運行的進程數量
- 可以通過--pids-limit參數設置容器內最大進程數,防止容器內進程過多導致系統資源耗盡
- 這種資源限制機制提高了系統的穩定性和可靠性
4 PID命名空間的工作流程

- Docker啟動容器:用戶通過Docker命令啟動一個容器
- 創建新的PID命名空間:Docker調用Linux內核的clone()或unshare()系統調用,創建一個新的PID命名空間
- 放入容器初始進程:將容器的初始進程(如/sbin/init或應用程序的入口進程)放入新創建的PID命名空間中
- 進程ID編號:容器內的進程啟動時,進程ID從1開始編號,與宿主機或其他容器內的進程ID相互獨立
- 進程訪問其他命名空間:如果容器內的進程需要訪問其他命名空間(如宿主機或其他容器的PID命名空間),可以通過nsenter等命令實現
- 在當前命名空間中運行:如果進程不需要訪問其他命名空間,則繼續在當前PID命名空間中運行
- PID命名空間保持獨立:在容器運行過程中,PID命名空間保持獨立,容器內的進程無法直接訪問或干擾其他命名空間內的進程
- 銷毀PID命名空間:當容器停止時,Docker會銷毀該PID命名空間,釋放相關資源
5 PID命名空間的操作示例
# 啟動一個Docker容器
[root@node1 ~]# docker run -it --name pid_name_demo ubuntu:20.04 bash
root@7034c8306cfb:/## 在容器內查看進程列表(只能看到容器內的進程)
root@7034c8306cfb:/# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.6 0.0 4100 2168 pts/0 Ss 06:17 0:00 bash
root 9 0.0 0.0 5884 1472 pts/0 R+ 06:17 0:00 ps aux
root@7034c8306cfb:/# # 在宿主機上查看所有進程(可以看到宿主機和所有容器的進程)
ps aux | grep pid_name_demo # 這里只是示例,實際無法直接通過進程名區分容器進程# 更準確的方法是使用docker top命令查看容器內進程
[root@node1 ~]# docker top pid_name_demo
UID PID PPID C STIME TTY TIME CMD
root 6157 6138 0 14:17 pts/0 00:00:00 bash
[root@node1 ~]# # 在容器內嘗試訪問宿主機的PID命名空間
# ps:以下命令僅用于演示,實際生產環境中應避免使用
[root@node1 ~]# docker exec -it --privileged pid_name_demo bash -c 'nsenter -t 1 -m -u -i -n -p ps aux'
nsenter: reassociate to namespace 'ns/ipc' failed: Operation not permitted
[root@node1 ~]#
# 上述命令嘗試進入宿主機的PID命名空間(PID為1通常是init進程),但缺乏權限# 退出容器
exit# 停止并刪除容器
docker stop pid_name_demo
docker rm pid_name_demo
6 總結
PID命名空間作為Docker實現資源隔離的核心技術之一,為容器提供了獨立的進程管理環境。通過PID命名空間,Docker實現了容器內進程與宿主機及其他容器內進程的隔離,提高了系統的安全性和穩定性。同時,PID命名空間還支持進程ID映射和層次結構,使得進程管理更加靈活。