云计算百科
云计算领域专业知识百科平台

Linux系统Namespace隔离实战:dd/mkfs/mount/unshare命令组合应用

引言: 💡 阅读策略建议 本文设计为「工具字典」,无需死记硬背,遇到问题时直接按场景查阅即可。 你只需要:  🔸 了解每个指令能解决什么问题  🔸 收藏本文作为实战弹药库  🔸 需要时用 Ctrl+F 精准提取

文章目录

  • 1.什么是Namespace?
  • 2.dd命令
  • 3.mkfs命令
  • 4.df命令
  • 5.mount命令
  • 6.unshare 命令
  • 7.PID隔离
  • 8.Mount隔离

1.什么是Namespace?

  namespace是 Linux 内核用来隔离内核资源的方式。通过 namespace,不同进程能看到各自独立的资源,彼此之间完全感知不到对方的存在。具体的实现方式是把一个或多个进程的相关资源指定在同一个 namespace 中。   Linux namespaces 是对 全局系统资源的一种封装隔离,使得处于不同 namespace 的进程拥有独立的全局系统资源,改变一个 namespace 中的系统资源只会影响当前namespace 里的进程,对其他 namespace 中的进程没有影响。   Linux 提供了多个API 用来操作 namespace,它们是 clone()、 setns()和 unshare()函数,为了明确隔离的具体是哪类 namespace,在使用这些 API 时,通常需要指定一些调用参数: CLONE_NEWIPC、 CLONE_NEWNET、 CLONE_NEWNS、CLONE_NEWPID、 CLONE_NEWUSER、 CLONE_NEWUTS和CLONE_NEWCGROUP。如果要同时隔离多个 namespace,可以使用 | (按位或)组合这些参数。

举个例子   三年一班的小明和三年二班的小明,虽说他们名字是一样的,但是所在班级不一样,那么,在全年级排行榜上面,即使出现两个名字一样的小明,也会通过各自的学号来区分。对于学校来说,每个班级就相当于是一个命名空间,这个空间的名称是班级号。班级号用于描述逻辑上的学生分组信息,至于什么学生分配到 1 班,什么学生分配到 2 班,那就由学校层面来统一调度。

2.dd命令

  • 功能:用于读取、转换并输出数据。dd可从标准输入或文件中读取数据,根据指定的格式来转换数据,再输出到文件、设备或标准数据。

语法:

dd OPITION

参数:

  • if=文件名:输入文件名(即指的源文件),默认为标准输入
  • of=文件名:输出文件名(即指定目的文件),默认为标准输出
  • ibs=bytes:一次读入bytes个字节,即指定一个块大小为bytes个字节
  • obs=bytes:一次输出bytes个字节
  • bs=bytes:同时读入/输出的块大小为bytes字节
  • cbs=bytes:一次转换bytes个字节,即指定转换缓冲区大小
  • skip=blocks:从输入文件开头跳过blocks个块后再开始拷贝
  • seek=blocks:从输出文件开头跳过blocks个块后开始拷贝
  • count=blocks:仅拷贝blocks个块,块大小等于ibs指定的字节数
  • conv=<关键字>,关键字有以下11中:
    • conversion:用指定的参数转换文件
    • ascii:转换 ebcdic 为 ascii
    • ebcdic:转换 ascii 为 ebcdic
    • ibm:转换 ascii 为 alternate ebcdic
    • block:把每一行转换为长度为 cbs,不足部分用空格填充
    • unblock:使每一行的长度都为 cbs,不足部分用空格填充
    • lcase:把大写字符转换为小写字符
    • ucase:把小写字符转换为大写字符
    • swap:交换输入的每对字节
    • noerror:出错时不停止
    • sync: 将每个输入块填充到 ibs 个字节,不足部分用空(NULL)字符补齐。
  • –help: 显示帮助信息
  • –version: 显示版本信息

示例:创建指定大小空白文件

  • 输入文件:特殊文件设备,产生连续不断的空白字符流。
  • 输出文件:空白镜像文件。

dd if=/dev/zero of=test.img bs=8k count=1024

效果如下: 在这里插入图片描述 示例2: 大小写转换

vim in.txt #创建文件,在里面写入 hello world
dd if=in.txt of=out.txt conv=ucase

效果: 在这里插入图片描述

3.mkfs命令

功能:

  • 用于在设备上创建 Linux 文件系统(俗称格式化),例如格式化 U 盘等存储设备。

语法:

mkfs [-V] [-t fstype] [fs-options] filesys [blocks]

参数说明

  • -V:启用详细显示模式。
  • -t fstype:指定要创建的文件系统类型(如 ext3、ext4)。
  • filesys:指定目标设备的文件名(如 /dev/sdb1)。
  • blocks:指定文件系统的磁盘块数。
  • fs-options:传递给具体文件系统的额外参数。

示例: 把镜像文件格式化为磁盘文件。

mkfs -t ext4 ./test.img

效果: 在这里插入图片描述

4.df命令

  • 功能:用于显示 Linux 系统上文件系统的磁盘使用情况统计。

语法:

df [OPTION]... [FILE]...

常见参数

  • -a, –all:显示所有文件系统(包括占用 0 Blocks 的文件系统)。
  • -h, –human-readable:以人类可读的格式显示(如 KB、MB、GB)。
  • -H, –si:类似 -h,但以 1000 为单位换算(而非 1024)。
  • -t, –type=TYPE:仅显示指定类型的文件系统(如 ext4)。
  • -T, –print-type:显示文件系统类型。 示例:

df

在这里插入图片描述

df -a

在这里插入图片描述

df -h

在这里插入图片描述

df -t ext4

在这里插入图片描述

5.mount命令

  • 功能:用于将文件系统加载到指定的挂载点。该命令常用于挂载光盘等存储设备,因为在 Linux 系统中插入光盘后不会自动挂载,需手动使用 mount 命令完成挂载操作。

语法:

mount -t [文件系统类型] [选项] [设备源] [挂载点]

什么是挂载?例子:插入U盘,然后弹出磁盘E:

Linux 挂载特点

  • 灵活组合:
    • Linux 系统下不同目录可以挂载到不同的分区或磁盘设备。
    • 目录与磁盘分区是分离的,可通过挂载自由组合。
  • 数据分布:
    • 不同目录的数据可以跨越多个磁盘分区或不同的磁盘设备。
  • 挂载实质:
    • 挂载的本质是为磁盘设备添加访问入口(挂载点)。

示例:   用上文格式化好的test.img文件,挂载到目录,如目录mkdir testmount(先创建好该目录) 挂载:

mount ./test.img /testmount

查看:

df -h

在这里插入图片描述

现在我们就把一个空白镜像文件挂载成磁盘。

6.unshare 命令

  • 功能:用于在不共享父进程命名空间的情况下运行指定程序。

语法:

unshare [options] program [arguments]

短参数 长参数 功能描述

  • -i,–ipc:不共享 IPC 命名空间(进程间通信隔离)
  • -m,–mount:不共享 Mount 命名空间(文件系统挂载点隔离)
  • -n,–net:不共享 Net 命名空间(网络栈隔离)
  • -p,–pid:不共享 PID 命名空间(进程ID隔离)
  • -u,–uts:不共享 UTS 命名空间(主机名和域名隔离)
  • -U,–user:不共享 User 命名空间(用户和用户组隔离)
  • -V,–version:显示 unshare 命令版本信息
  • –fork:先 fork 子进程,再在子进程中执行 unshare(用于避免影响父进程环境)
  • –mount-proc:在启动子进程前,优先挂载 /proc 文件系统(通常与 –pid 配合使用)

示例 隔离主机名,创建新的bash子进程并与父进程隔离:

unshare -u /bin/bash

验证:

hostname test #设置主机名,为test
hostname #查看主机名,并新窗口查看主机名是否一样。
exit #退出子进程
hostname #查看主机名

效果: 在这里插入图片描述

7.PID隔离

示例:

unshare -p /bin/bash #错误演示

在这里插入图片描述

PID 命名空间的特性

  PID 命名空间的目的是隔离进程树,使新命名空间中的进程从 PID 1 开始重新编号。但 Linux 要求:

  • 每个 PID 命名空间必须有一个初始进程(init 进程,PID=1)。
  • 这个 init 进程需要管理命名空间内的孤儿进程(防止僵尸进程)

如果直接运行 unshare -p /bin/bash:

  • /bin/bash 会继承当前进程的 PID(仍在原命名空间),无法成为新 PID 命名空间的 init 进程。

  • 新命名空间没有有效的 init 进程,导致功能异常(如ps、top 等命令失效)。

–fork的作用   –fork(或 -f)会让 unshare在创建新命名空间后,先调用 fork() 创建一个子进程,再在该子进程中运行 /bin/bash。这样:

  • unshare调用 fork(),生成一个子进程。
  • 子进程进入新的 PID 命名空间,并成为该命名空间的 init进程(PID=1)。
  • 子进程再执行 /bin/bash,此时 Bash 的 PID 在新命名空间中为 1。
  • 如果没有 –fork:

    • /bin/bash的 PID 仍然是原命名空间的 PID(非 1),导致新 PID 命名空间无 init 进程,破坏隔离性。

    添加 –fork:

    unshare -p –fork /bin/bash #错误演示

    注意:如果执行失败,使用exit指令退出子进程,再进行执行。   仅加上 –fork选项仍然有问题,当运行ps、top、htop 等命令时,它们实际上是从 历史/proc 读取数据。 效果: 在这里插入图片描述

    /proc 文件系统的作用 /proc 是一个 虚拟文件系统(procfs),它动态反映系统内核的运行时信息,包括:

    • 进程信息(/proc/[PID]/)
    • 系统资源(CPU、内存、设备等)
    • 内核参数(可通过 sysctl 调整)

    当运行ps、top、htop 等命令时,它们实际上是从/proc 读取数据。 默认 /proc 的问题 默认情况下,/proc 挂载的是 宿主机的 PID 命名空间 的信息。如果只运行:

    • bash
    • unshare -p –fork /bin/bash虽然进入了新的 PID 命名空间(echo $$ 显示 1), 但 /proc 仍然显示原命名空间的进程信息,导致:
      • ps aux会显示所有宿主机进程(而非当前命名空间的进程)。
      • top、htop等工具也无法正确运行。

    –mount-proc 的作用

    –mount-proc选项会自动:

    • 卸载当前 /proc(如果已挂载)。
    • 重新挂载一个新的 /proc,使其仅显示 当前 PID命名空间 的进程信息。

    示例(正确用法):

    unshare -p –fork –mount-proc /bin/bash

    效果: 在这里插入图片描述

    运行后:

    • echo $$返回 1(当前 Bash 是新命名空间的 init 进程)。
    • ls /proc仅显示当前命名空间的进程(如 1/, 2/ 等)。
    • ps aux仅显示当前命名空间的进程。

    如果不加 –mount-proc会怎样? 如果不加 –mount-proc,你需要 手动重新挂载 /proc: mount -t proc proc /proc# 手动挂载 否则:

    • ps aux会显示 宿主机的所有进程(不符合 PID 隔离的预期)。
    • 某些依赖 /proc 的命令(如 pstree、pgrep)可能报错。

    为什么不能复用旧的 /proc?

    • 因为 /proc 的内容是动态生成的,它依赖于 当前 PID 命名空间:
    • 在 新 PID 命名空间 中,进程的 PID 会重新编号(如 bash 变成 PID 1)。 但旧的 /proc 仍然关联 原命名空间,导致:
      • /proc/1/可能指向宿主机 systemd 或 init,而非当前 bash。
      • ps读取 /proc 时,会看到错误的进程信息。

    –mount-proc确保 /proc 和 当前 PID 命名空间 匹配。

    验证:打开新窗口,查看两个窗口的ls -l /proc和ps -ef

    8.Mount隔离

    文件系统隔离 一共需要完成三步:

    • 创建–mount进程
    • 创建空白文件,挂载成磁盘
    • 创建mount隔离进程

    创建–mount进程

    unshare –mount –fork /bin/bash

    创建空白文件完成挂载

    dd if=/dev/zero of=data.img bs=8k count=10240 #创建空白文件
    mkfs -t ext4 ./data.img #格式化空白文件

    完成挂载隔离

    mkdir -p test/mt1 #创建目录
    mount -t ext4 ./data.img test/mt1 #挂载到目录
    df -h #新建窗口,两窗口执行该指令,验证是否完成文件系统隔离

    效果: 在这里插入图片描述 📌 写给读者的小纸条   “这些指令组合就像厨房里的调味罐——不用记住每一瓶的位置,用的时候拉开抽屉随手拿就好。   建议把本文丢进收藏夹吃灰(偶尔能翻出来用的才是好工具),需要时Ctrl+F一搜,省下的时间够喝杯咖啡啦 ☕”

    非常感谢您能耐心读完这篇文章。倘若您从中有所收获,还望多多支持呀! 在这里插入图片描述

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » Linux系统Namespace隔离实战:dd/mkfs/mount/unshare命令组合应用
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!