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.mzph.cn/pingmian/79524.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java List分页工具

PageUtil.java import com.google.common.collect.Lists; import com.jd.platform.hotkey.dashboard.common.domain.Page; import org.springframework.util.CollectionUtils;import java.util.ArrayList; import java.util.List;public class PageUtil {/*** 通用分页工具类*…

中阳策略:如何从K线行为中提取交易逻辑信号?

中阳策略:如何从K线行为中提取交易逻辑信号? 在量化趋势研究中,中阳形态常被视作市场动能变化的重要标志。它不仅代表价格的强势上行,更隐含着主力资金换手与情绪转换的信号。将“中阳”这一结构元素抽象为模型中的“强动能突破”…

Java SE(8)——继承

1.继承的概念&作用 在Java中,继承是面向对象编程的三大基本特性之一(还有封装和多态),允许一个类(子类/继承类)继承另一个类(父类/基类)的属性和方法 继承的核心目的是&#xf…

Python爬虫(18)反爬攻防战:动态IP池构建与代理IP实战指南(突破95%反爬封禁率)

目录 引言一、背景:为什么代理IP是爬虫的“第二生命”?1.1 反爬系统的IP检测三把刀1.2 代理IP的核心价值 二、基础实战:快速搭建代理IP系统2.1 免费代理IP的获取与筛选2.2 代理IP的智能容错机制 三、高阶攻防:突破企业级反爬封锁3…

LFU算法解析

文章目录 LFU缓存中关键变量的访问与更新机制1. min_freq - 最小频率访问时机更新时机更新示例 2. capacity - 缓存容量访问时机更新时机访问示例 3. key_to_node - 键到节点的映射访问时机更新时机更新示例 4. freq_to_dummy - 频率到链表哑节点的映射访问时机更新时机更新示例…

ByteArrayInputStream 类详解

ByteArrayInputStream 类详解 ByteArrayInputStream 是 Java 中用于从字节数组读取数据的输入流,位于 java.io 包。它允许将内存中的字节数组当作输入流来读取,是处理内存数据的常用工具。 1. 核心特性 内存数据源:从字节数组(b…

rvalue引用()

一、先确定基础:左值(Lvalue)和右值(Rvalue) 理解Rvalue引用,首先得搞清楚左值和右值的概念。 左值(Lvalue):有明确内存地址的表达式,可以取地址。比如变量名、引用等。 复制代码 int a = 10; // a是左值 int& ref = a; // ref也是左值右值(Rval…

吴恩达深度学习作业 RNN模型——字母级语言模型

一. 简单复习一下RNN RNN RNN适用于处理序列数据,令是序列的第i个元素,那么就是一个长度为的序列,NLP中最常见的元素是单词,对应的序列是句子。 RNN使用同一个神经网络处理序列中的每一个元素。同时,为了表示序列的…

基于python的哈希查表搜索特定文件

Python有hashlib库,支持多种哈希算法,比如MD5、SHA1、SHA256等。通常SHA256比较安全,但MD5更快,但可能存在碰撞风险,得根据自己需求决定。下面以SHA256做例。 import hashlib import os from typing import Dict, Lis…

idea创建springboot项目无法创建jdk8原因及多种解决方案

idea创建springboot项目无法创建jdk8原因及多种解决方案 提示:帮帮志会陆续更新非常多的IT技术知识,希望分享的内容对您有用。本章分享的是springboot的使用。前后每一小节的内容是存在的有:学习and理解的关联性。【帮帮志系列文章】&#x…

【C++进阶十】多态深度剖析

【C进阶十】多态深度剖析 1.多态的概念及条件2.虚函数的重写3.重写、重定义、重载区别4.C11新增的override 和final5.抽象类6.虚表指针和虚表6.1什么是虚表指针6.2指向谁调用谁,传父类调用父类,传子类调用子类 7.多态的原理8.单继承的虚表状态9.多继承的…

面向网络安全的开源 大模型-Foundation-Sec-8B

1. Foundation-Sec-8B 整体介绍 Foundation-Sec-8B 是一个专注于网络安全领域的大型语言模型 (LLM),由思科的基础人工智能团队 (Foundation AI) 开发 。它基于 Llama 3.1-8B 架构构建,并通过在一个精心策划和整理的网络安全专业语料库上进行持续预训练而得到增强 。该模型旨在…

Python爬虫的基础用法

Python爬虫的基础用法 python爬虫一般通过第三方库进行完成 导入第三方库(如import requests ) requests用于处理http协议请求的第三方库,用python解释器中查看是否有这个库,没有点击安装获取网站url(url一定要解析正确&#xf…

WHAT - Tailwind CSS + Antd = MetisUI组件库

文章目录 Tailwind 和 Antd 组件库MetisUI 组件库 Tailwind 和 Antd 组件库 在 WHAT - Tailwind 样式方案(不写任何自定义样式) 中我们介绍了 Tailwind,至于 Antd 组件库,我们应该都耳熟能详,官网地址:htt…

Day 4:牛客周赛Round 91

好久没写了,问题还蛮多的。听说这次是苯环哥哥出题 F题 小苯的因子查询 思路 考虑求因子个数,用质因数分解;奇数因子只需要去掉质数为2的情况,用除法。 这里有个比较妙的细节是,提前处理出数字x的最小质因数&#xff0…

使用直觉理解不等式

问题是这个: 题目 探究 ∣ max ⁡ b { q 1 ( z , b ) } − max ⁡ b { q 2 ( z , b ) } ∣ ≤ max ⁡ b ∣ q 1 ( z , b ) − q 2 ( z , b ) ∣ |\max_b\{q_1(z,b)\}-\max_b\{q_2(z,b)\}|\le\max_b|q_1(z,b)-q_2(z,b)| ∣maxb​{q1​(z,b)}−maxb​{q2​(z,b)}∣≤…

恶心的win11更新DIY 设置win11更新为100年

‌打开注册表编辑器‌:按下Win R键,输入regedit,然后按回车打开注册表编辑器。‌12‌导航到指定路径‌:在注册表编辑器中,依次展开HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings‌新建DWORD值‌&…

嵌入式驱动学习

时钟 定义 周期型的0、1信号 时钟信号由“心脏”时钟源产生,通过“动脉”时钟树传播到整个芯片中。 SYSCLK系统时钟,由HSI、HSE、PLLCLK三选一。 HCLK是AHB总线时钟, PCLK是APB总线时钟。 使用某个外设,必须要先使能该外设时钟系统…

Java:从入门到精通,你的编程之旅

Java,一门历久弥新的编程语言,自诞生以来就以其跨平台性、面向对象、稳定性和安全性等特性,在企业级应用开发领域占据着举足轻重的地位。无论你是初学者还是经验丰富的开发者,Java 都能为你提供强大的工具和广阔的舞台。 为什么选…

Linux:深入理解数据链路层

实际上一台主机中,报文并没有通过网络层直接发送出去,而是交给了自己的下一层协议——数据链路层!! 一、理解数据链路层 网络层交付给链路层之前,会先做决策再行动(会先查一下路由表,看看目标网…