命名空间——进程ID(pid)

命名空间——进程ID(pid)

一、PID命名空间的核心:“进程编号的平行世界”

PID命名空间的本质是让不同命名空间的进程拥有独立的PID编号体系,就像多个“平行世界”——每个世界里的进程编号(PID)可以重复,但彼此互不可见。

关键特性:
  1. 进程有两个PID
    一个进程在自己的命名空间内有一个“局部PID”(比如命名空间内的PID=1),在主机全局命名空间内还有一个“全局PID”(比如主机上的PID=1234)。
    举例:容器内的bash进程,在容器的PID命名空间里是PID=1,但在主机上看可能是PID=5678

  2. 嵌套结构
    PID命名空间可以像俄罗斯套娃一样嵌套。比如“父命名空间”创建“子命名空间”,子命名空间的进程能看到父命名空间的进程,但父命名空间看不到子命名空间的进程(除非显式配置)。

  3. PID=1的特殊性
    每个PID命名空间的第一个进程会被分配PID=1,它的角色类似系统的init进程:

    • 负责回收该命名空间内的“僵尸进程”(如果它退出,内核会强制终止命名空间内所有进程);
    • 这就是为什么在容器中直接杀掉PID=1的进程,整个容器会立即退出(你可以试试docker exec进入容器后执行kill 1,容器会直接停止)。

二、实战:sudo unshare -fp --mount-proc 到底做了什么?

这个命令是创建并进入新PID命名空间的标准操作,我们一步步拆解:

1. sudo:获取权限

PID命名空间的创建需要root权限(普通用户受限制),所以用sudo提权。

2. -f--fork):安全创建新进程

unshare默认会让“当前进程”进入新命名空间,但这样可能影响当前shell。-f会先fork一个新进程,让新进程进入新命名空间,当前shell不受影响(更安全)。

3. -p--pid):创建新的PID命名空间

这是核心:告诉内核为新进程创建一个全新的PID命名空间。新命名空间内的进程将拥有独立的PID编号,看不到外部命名空间的进程。

4. --mount-proc:重新挂载/proc文件系统(最关键的一步!)

/proc是Linux的“进程信息虚拟文件系统”,里面的/proc/[PID]目录对应每个进程的详细信息。但/proc默认展示的是“当前进程所在命名空间”的进程信息。

如果不重新挂载/proc

  • 即使进入了新的PID命名空间,/proc仍然指向原来命名空间的视图(比如主机的/proc);
  • 此时执行pstop,看到的还是主机的进程,无法体现PID命名空间的隔离效果。

--mount-proc的作用是:在新的PID命名空间中,自动将/proc重新挂载为“当前命名空间的进程视图”。这样执行ps时,只能看到新命名空间内的进程。

三、操作演示:直观感受隔离效果

步骤1:创建新PID命名空间并重新挂载/proc
# 执行命令,进入新的bash进程(在新PID命名空间中)
sudo unshare -fp --mount-proc /bin/bash

# 此时在新bash中查看PID:当前bash是这个命名空间的第一个进程,所以PID=1
echo $$  # 输出:1(局部PID)

# 查看进程列表:只能看到当前命名空间内的进程(只有bash自己)
ps aux  # 输出中只有1个进程(PID=1的bash)
步骤2:在新命名空间中创建子进程
# 在新bash中启动一个sleep进程(子进程)
sleep 3600 &  # 后台运行

# 查看进程:sleep的PID在当前命名空间中是2
ps aux  # 输出:PID=1(bash)、PID=2(sleep)
步骤3:在主机终端查看(全局视角)

打开另一个终端(主机默认命名空间):

# 查找新命名空间中bash的全局PID(假设是1234)
pgrep -f "unshare -fp --mount-proc"  # 输出:1234

# 查看该进程的子进程(sleep的全局PID,比如1235)
ps -ef | grep 1234  # 输出:1234(bash)、1235(sleep)

# 但主机终端中,sleep的PID是1235(全局PID),和新命名空间内的PID=2完全不同

总结

PID命名空间通过“独立的PID编号体系”实现进程隔离,而--mount-proc(或手动重新挂载/proc)是让这种隔离“可见”的关键(确保ps等工具只显示当前命名空间的进程)。

这正是容器技术中“进程隔离”的底层原理:每个容器就是一个独立的PID命名空间,容器内的PID=1进程(如nginxbash)与主机的PID=1systemd)完全隔离,彼此互不可见。

### 如何在 Linux 中查看进程 PID 的方法 在 Linux 系统中,可以通过多种方式查看正在运行的进程及其对应的 PID(Process Identifier)。以下是常用的方法: #### 使用 `ps` 命令 `ps` 是最基础也是最常见的用于显示当前进程状态的命令。通过特定选项可以筛选出目标进程PID。例如,要查找名为 `java` 的进程 ID 可以使用以下命令: ```bash ps aux | grep java ``` 上述命令会列出所有包含关键字 `java` 的进程信息,其中包括用户的名称、CPU 和内存占用情况以及最重要的 PID 列表[^1]。 #### 结合 `pgrep` 或 `pids` 工具 如果知道确切的服务名或者程序名,则可以直接利用专门设计来定位指定服务对应 PIDs 的工具——`pgrep` 来简化操作流程。 ```bash pgrep java ``` 这条指令仅返回匹配到的第一个符合条件的 Java 进程编号[^2]。 #### 利用 `/proc` 文件系统 每一个活跃中的进程都在 /proc 下面拥有自己独立目录结构形式表示出来,其名字正好就是该进程自身的 PID 数字串。因此我们也可以遍历整个 procfs 寻找感兴趣的项目。 ```bash ls /proc/[0-9]* ``` 这将展示所有的数字命名文件夹,实际上也就是全部现存进程号列表[^3]。 另外需要注意的是,在实际应用过程中可能会遇到某些特殊场景下的限制条件比如当系统的 pid_max 达到了预设界限之后就无法再继续分配新的进程标识码给新生出来的子任务们了。此时就需要调整内核参数重新定义允许的最大范围值[^4]。 ```bash echo 65536 > /proc/sys/kernel/pid_max sysctl -w kernel.pid_max=65536 ``` 以上就是在不同情况下适用于查询 linux 平台下任意类型应用程序实例所关联起来的那个独一无二的身份标签—PID的具体做法汇总说明文档啦!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值