当前位置: 首页 > web >正文

Docker —— 隔离的基本操作(2)

Docker —— 隔离的基本操作(2)

  • unshare
  • `unshare` 命令详解
    • 基本语法
    • 常用选项
    • 常用示例
    • 实际应用场景
    • 注意事项
    • 与 Docker 的关系
      • 1. 执行命令
      • 2. 修改主机名
      • 3. 退出命名空间
      • 4. 验证宿主机主机名
      • 关键原理
      • 类比 Docker 容器
      • 总结
  • 实战操作一(PID 隔离)
      • 关于 `unshare --pid --fork --mount-proc` 的深入解释
        • 1. `--fork` 的作用
        • 2. `--pid` 的隔离特性
        • 3. `--mount-proc` 的必要性
      • 完整命令的意义
      • 常见问题
        • Q1:不加 `--fork` 会怎样?
        • Q2:不加 `--mount-proc` 会怎样?
        • Q3:为什么需要 `sudo`?
      • 总结
  • 实战操作二(Mount 隔离)

我们上次简单介绍了一些关于隔离的一些基本操作,如果不熟悉的小伙伴可以点击这里:

https://blog.csdn.net/qq_67693066/article/details/147712428

我们今天主要来操作一下隔离,如何实现:

unshare

unshare 命令详解

unshare 是 Linux 系统中用于创建新命名空间(namespace)并运行程序的命令,它是 Linux 容器技术(如 Docker)的基础工具之一。通过 unshare 可以创建隔离的运行环境。

基本语法

unshare [选项] [--] [程序 [参数...]]

常用选项

短参数长参数含义
-i--ipc不共享 IPC 空间(隔离进程间通信:消息队列、共享内存等)
-m--mount不共享 Mount 空间(隔离文件系统挂载点)
-n--net不共享 Net 空间(隔离网络栈:IP、端口、路由等)
-p--pid不共享 PID 空间(隔离进程 ID,需配合 --fork--mount-proc 使用)
-u--uts不共享 UTS 空间(隔离主机名和域名)
-U--user不共享用户命名空间(隔离用户和组 ID,普通用户可用)
-V--version查看版本信息
--fork创建子进程并在子进程中执行 unshare(通常与 --pid 共用,使子进程成为 PID 1)
--mount-proc在新 PID 命名空间中挂载 /proc 文件系统(确保 pstop 等命令正常工作)

常用示例

  1. 创建新的 mount 命名空间

    unshare --mount
    

    在这个新命名空间中的挂载操作不会影响主系统

  2. 创建 PID 命名空间(类似容器环境)

    sudo unshare --pid --fork --mount-proc bash
    

    在这个新环境中,bash 将成为 PID 1 的进程

  3. 创建网络命名空间

    sudo unshare --net
    

    这个新环境将有独立的网络栈

  4. 创建完整的隔离环境

    sudo unshare --pid --fork --mount-proc --net --mount --uts bash
    
  5. 创建用户命名空间(不需要 root 权限)

    unshare --user --map-root-user
    
  6. 在新命名空间中运行特定程序

    unshare --pid --fork --mount-proc -- sleep 1000
    

实际应用场景

  1. 测试软件安装

    unshare --mount bash
    mkdir /tmp/testroot
    mount --bind /tmp/testroot /tmp/testroot
    mount --make-private /tmp/testroot
    mount --bind /path/to/package /tmp/testroot
    chroot /tmp/testroot /bin/bash
    
  2. 创建临时网络环境

    sudo unshare --net
    ip link set lo up
    ip addr add 192.168.1.100/24 dev lo
    
  3. 安全测试

    unshare --user --map-root-user --pid --fork --mount-proc bash
    

注意事项

  1. 大多数命名空间需要 root 权限,除了用户命名空间
  2. 使用 --pid 时通常需要同时使用 --fork--mount-proc
  3. 命名空间中的修改不会影响主系统
  4. 可以使用 nsenter 命令进入已存在的命名空间

与 Docker 的关系

Docker 等容器技术底层就是使用 unshare 类似的机制创建隔离环境。例如:

# 类似于 Docker 容器的基础隔离
sudo unshare --pid --fork --mount-proc --net --mount --uts --ipc bash

unshare 是理解 Linux 容器技术的重要工具,通过它可以深入了解 Linux 的命名空间隔离机制。

我们来简单使用一下:
在这里插入图片描述
这段命令演示了使用 unshare 创建 UTS 命名空间(主机名隔离)的过程。以下是逐步解释:


1. 执行命令

sudo unshare -u /bin/bash
  • -u--uts):创建新的 UTS 命名空间,隔离主机名和域名。
  • /bin/bash:在新命名空间中启动 Bash shell。
  • 需要 sudo 因为 UTS 命名空间默认需要 root 权限。

2. 修改主机名

hostname test1
hostname
  • 在新 UTS 命名空间中,将主机名修改为 test1
  • hostname 命令验证修改成功,此时 仅影响新命名空间

3. 退出命名空间

exit
  • 退出 Bash shell 后,回到原来的 UTS 命名空间(宿主机环境)。

4. 验证宿主机主机名

hostname
  • 显示 localhost.localdomain,证明宿主机的主机名 未被修改
  • 因为之前的 hostname test1 只在新创建的 UTS 命名空间中生效。

关键原理

  1. UTS 命名空间隔离

    • 每个 UTS 命名空间维护独立的主机名和域名。
    • 子命名空间的修改不会影响父命名空间(宿主机)。
  2. 作用域

    • unshare -u 创建的子进程及其后代进程会继承新的 UTS 命名空间。
    • 退出子进程后,命名空间自动销毁(除非使用 --persistent 等选项)。

类比 Docker 容器

Docker 容器启动时也会创建独立的 UTS 命名空间:

# 在容器内修改主机名不影响宿主机
docker run -it --hostname mycontainer alpine sh

总结

  • 发生了什么
    通过 unshare -u 创建了一个临时的隔离环境,在其中修改的主机名仅在该环境内有效,退出后宿主机环境保持不变。
  • 为什么需要
    这种隔离机制是容器技术的基础,允许不同环境拥有独立的主机名配置,避免冲突。

实战操作一(PID 隔离)

在主机上执行 ps -ef,可以看到进程列表如下,其中启动进程 PID 1 为 init 进程:

在这里插入图片描述
我们打开另外一个 shell ,执行下面命令创建一个 bash 进程,并且新建一个 PID
Namespace:

unshare --fork --pid --mount-proc /bin/bash

在这里插入图片描述
执行 exit 退出进程
在这里插入图片描述

关于 unshare --pid --fork --mount-proc 的深入解释

1. --fork 的作用
  • 核心问题
    当使用 --pid 创建新的 PID 命名空间时,新命名空间需要有一个独立的进程树,且第一个进程(PID 1)必须是该命名空间内的进程。

    • 如果不加 --forkunshare 自身进程(父进程)会作为新命名空间的初始进程,但该父进程 并不属于新命名空间,导致内核无法正确初始化 PID 命名空间,报错 Cannot allocate memory
  • 解决方案
    --fork 会让 unshare 先创建一个子进程(fork),再在该子进程中调用 unshare 创建新命名空间。此时子进程成为新命名空间的 PID 1(类似 init 进程),符合内核要求。

2. --pid 的隔离特性
  • 仅隔离 PID
    --pid 仅隔离进程 ID 视图,其他资源(如网络、挂载点等)仍与宿主机共享

    • 新命名空间内的进程无法看到宿主机其他进程,但宿主机仍能看到新命名空间内的进程(只是 PID 不同)。
  • 对比完整容器
    若需完全隔离,需组合其他命名空间(如 --net --mount --uts)。

3. --mount-proc 的必要性
  • /proc 文件系统的特殊性
    Linux 的 /proc 是一个虚拟文件系统,动态反映当前命名空间的进程信息。

    • 默认情况下,/proc 显示 宿主机全局进程信息,与新 PID 命名空间隔离的视图冲突。
  • 挂载新 /proc 的作用
    --mount-proc 会自动在新命名空间中重新挂载 /proc,使其仅包含 当前命名空间及其子命名空间的进程信息

    • 这样,pstop 等命令才能正确显示当前命名空间内的进程。
  • --mount 的关系
    --mount-proc 隐含了挂载点隔离(类似 --mount),但专门针对 /proc 优化,避免手动挂载的复杂性。


完整命令的意义

sudo unshare --pid --fork --mount-proc bash
  • 流程
    1. --fork 创建子进程作为 PID 1。
    2. --pid 在新子进程中初始化独立的 PID 命名空间。
    3. --mount-proc 挂载隔离后的 /proc,确保进程工具正常工作。
    4. 启动 bash,成为新命名空间的主进程。

常见问题

Q1:不加 --fork 会怎样?
  • 内核拒绝初始化 PID 命名空间,报错 Cannot allocate memory,因为缺少合法的 PID 1 进程。
Q2:不加 --mount-proc 会怎样?
  • ps/top 仍显示宿主机所有进程,破坏 PID 隔离的语义。
Q3:为什么需要 sudo
  • 创建 PID 命名空间默认需要 root 权限(涉及系统级进程管理)。

总结

参数作用必要性
--pid创建独立的 PID 命名空间核心功能
--fork确保新命名空间有合法的 PID 1 进程必须配合 --pid 使用
--mount-proc挂载隔离后的 /proc,使进程工具正常工作强烈推荐(否则隔离不完整)

这种机制是 Linux 容器(如 Docker)的基础:通过组合多个命名空间(--pid --net --mount 等)和 --mount-proc,实现进程、网络、文件系统等资源的隔离。

实战操作二(Mount 隔离)

打开第一个 shell 窗口 A,执行命令, df -h ,查看主机默认命名空间的磁盘挂载情
况:
在这里插入图片描述
打开一个新的 shell 窗口 B,执行 Mount 隔离命令

unshare --mount --fork /bin/bash

在窗口 B 中添加新的磁盘挂载

dd if=/dev/zero of=fdimage.img bs=8k count=10240
mkfs -t ext4 ./fdimage.img
mount ./fdimage.img 文件路径

在这里插入图片描述

在这里插入图片描述
在窗口 B 挂载的磁盘中添加文件

echo "Hello world!" > ./tmpmount/hello.txt

在这里插入图片描述
查看窗口 A 中的磁盘挂载信息
在这里插入图片描述
查看窗口 B 中的文件信息
在这里插入图片描述
查看窗口 A 中的文件信息,可以看到窗口 B 中新建的文件和磁盘挂载在主机的窗
口中并没有,说明我们实现了文件系统隔离。
在这里插入图片描述
窗口 B 执行 exit,退出
在这里插入图片描述

http://www.xdnf.cn/news/4028.html

相关文章:

  • ABAP 导入Excel形成内表
  • spring中的@ConfigurationProperties注解详解
  • 网星安全AWS攻防方案,重磅发布!
  • 机器学习模型训练模块技术文档
  • AVHRR中国积雪物候数据集(1980-2020年)
  • yolo 用roboflow标注的数据集本地训练 kaggle训练 comet使用 训练笔记5
  • FISCO BCOS【初体验笔记】
  • Python 闭包:函数式编程中的魔法变量容器
  • ciscn_2019_c_1
  • 普联的AC100+AP+易展路由组网方案的一些问题
  • docker介绍以及安装
  • sherpa-ncnn:Linux_x86交叉编译Linux_arm32上的sherpa-ncnn -- 语音转文本大模型
  • 蓝桥杯单片机备战笔记
  • 【中间件】brpc_基础_TimerThread
  • 五一假期作业
  • springboot单体项目的执行流程
  • LFU算法解析
  • 【PostgreSQL数据分析实战:从数据清洗到可视化全流程】4.5 清洗流程自动化(存储过程/定时任务)
  • 【中间件】brpc_基础_单例
  • FreeRTOS学习系列·二值信号量
  • Linux查询日志常用命令
  • 解锁现代健康密码:科学养生新主张
  • 基于PLC的换热器温度控制系统设计
  • 状态模式(State Pattern)
  • 电子商务商家后台运营专员模板
  • C++ 中二级指针的正确释放方法
  • 【KWDB 创作者计划】_Ubuntu 22.04系统KWDB数据库安装部署使用教程
  • Qt中的UIC
  • Amazon Bedrock Converse API:开启对话式AI新体验
  • Qt开发:容器组控件的介绍和使用