功能,还可以支持容器在跨主机的迁移前后保持内部进程的 PID 不发生变化。
文件系统的命令工作,还需要挂载 /proc 文件系统。下面的例子演示了挂载 /proc 文件系统的重要性。先输出当前进程的 PID,然后查看其 PID namespace,接着通过 unshare 命令创建新的 PID namespace:
显示的 PID namespace 并没有变化。让我们接着做实验:
显示的 PID 还是旧 namespace 中的编号,而 $$ 为 1 说明当前进程已经被认为是该 PID namespace 中的 1 号进程了。再看看 1 号进程的详细信息:/sbin/init,这是系统的 init 进程,这一切看起来实在是太乱了。文件系统,由于我们新的 mount namespace 的挂载信息是从老的 namespace 拷贝过来的,所以这里看到的还是老 namespace 里面的进程号为 1 的信息。执行下面的命令挂载 /proc 文件系统:
显示了新的 PID namespace,当前 PID namespace 中的 1 号进程也变成了 bash 进程。
自动挂载 /proc 文件系统,就不需要我们手动执行 mount -t proc proc /proc 命令了。
修改的进程 PID namespace
添加了 --fork /bin/bash 参数:
调用 unshare 和 nsenter 等命令后,原进程还是属于老的 PID namespace,新 fork 出来的进程才属于新的 PID namespace。
方法创建 PID namespace 的进程所在的 PID namespace。
403.png" alt="">
显示我们通过 nsenter 添加进来的 bash 进程,让我们来看看究竟:
显示。这也是我们创建的 PID namespace 根最外层的 PID namespace 不一样的地方:可以有多个 PPID 为 0 的进程。
添加的 bash 进程。到这里我们也可以看出,同样的进程在不同的 PID namespace 中拥有不同的 PID。
增加,并且不能重复(当然进程退出后,PID 会被回收再利用),进程的 PID 为 1 的进程是内核启动的第一个应用层进程,被称为 init 进程(不同的 init 系统的进程名称可能不太一样)。这个进程具有特殊意义,当 init 进程退出时,系统也将退出。所以除了在 init 进程里指定了 handler 的信号外,内核会帮 init 进程屏蔽掉其他任何信号,这样可以防止其他进程不小心 kill 掉 init 进程导致系统挂掉。退出后,该进程就变成了孤儿进程。孤儿进程会被当前 PID namespace 中 PID 为 1 的进程接管,而不是被最外层的系统级别的 init 进程接管。
, 新启动两个 bash 进程:
后台 sleep 一小时: