【Docker 内核详解】namespace 资源隔离(四):Mount namespace Network namespace

【Docker 内核详解 - namespace 资源隔离】系列包含:

  • namespace 资源隔离(一):进行 namespace API 操作的 4 种方式
  • namespace 资源隔离(二):UTS namespace & IPC namespace
  • namespace 资源隔离(三):PID namespace
  • namespace 资源隔离(四):Mount namespace & Network namespace
  • namespace 资源隔离(五):User namespaces

namespace 资源隔离(四):Mount namespace & Network namespace

1.Mount namespace

mount namespace 通过隔离文件系统挂载点对隔离文件系统提供支持,它是历史上第一个 Linux namespace,所以标识位比较特殊,就是 CLONE_NEWNS。隔离后,不同 mount namespace 中的文件结构发生变化也互不影响。可以通过 /proc/[pid]/mounts 查看到所有挂载在当前 namespace 中的文件系统,还可以通过 /proc/[pid]/mountstats 看到 mount namespace 中文件设备的统计信息,包括挂载文件的名字、文件系统类型、挂载位置等。

进程在创建 mount namespace 时,会把当前的文件结构复制给新的 namespace。新 namespace 中的所有 mount 操作都只影响自身的文件系统,对外界不会产生任何影响。这种做法非常严格地实现了隔离,但对某些情况可能并不适用。比如父节点 namespace 中的进程挂载了一张 CD-ROM,这时子节点 namespace 复制的目录结构是无法自动挂载上这张 CD-ROM 的,因为这种操作会影响到父节点的文件系统。

2006 年引入的 挂载传播mount propagation)解决了这个问题,挂载传播定义了 挂载对象mount object)之间的关系,这样的关系包括共享关系和从属关系,系统用这些关系决定任何挂载对象中的挂载事件如何传播到其他挂载对象。

  • 共享关系share relationship)。如果两个挂载对象具有共享关系,那么一个挂载对象中的挂载事件会传播到另一个挂载对象,反之亦然。
  • 从属关系slave relationship)。如果两个挂载对象形成从属关系,那么一个挂载对象中的挂载事件会传播到另一个挂载对象,但是反之不行;在这种关系中,从属对象是事件的接收者。

一个挂载状态可能为以下一种:

  • 共享挂载share):传播事件的挂载对象称为共享挂载。
  • 从属挂载slave):接收传播事件的挂载对象称为从属挂载。
  • 共享 / 从属挂载shared and slave):同时兼有前述两者特征的挂载对象称为共享 / 从属挂载。
  • 私有挂载private):既不传播也不接收传播事件的挂载对象称为私有挂载。
  • 不可绑定挂载unbindable):另一种特殊的挂载对象称为不可绑定的挂载,它们与私有挂载相似,但是不允许执行绑定挂载,即创建 mount namespace 时这块文件对象不可被复制。

通过下图可以更好地了解它们的状态变化。

在这里插入图片描述
以上图为例说明常用的挂载传播方式。最上层的 mount namespace 下的 /bin 目录与 child namespace 通过 master slave 方式进行挂载传播,当 mount namespace 中的 /bin 目录发生变化时,发生的挂载事件能够自动传播到 child namespace 中;/lib 目录使用完全的共享挂载传播,各 namespace 之间发生的变化都会互相影响;/proc 目录使用私有挂载传播的方式,各 mount namespace 之间互相隔离;最后的 /root 目录一般都是管理员所有,不能让其他 mount namespace 挂载绑定。

默认情况下,所有挂载状态都是私有的。设置为共享挂载的命令如下。

mount --make-shared <mount-object>

从共享挂载状态的挂载对象克隆的挂载对象,其状态也是共享,它们相互传播挂载事件。设置为从属挂载的命令如下。

mount --make-slave <shared-mount-object>

来源于从属挂载对象克隆的挂载对象也是从属的挂载,它也从属于原来的从属挂载的主挂载对象。

将一个从属挂载对象设置为共享 / 从属挂载,可以执行如下命令,或者将其移动到一个共享挂载对象下。

mount --make-shared <slave-mount-obiect>

如果想把修改过的挂载对象重新标记为私有的,可以执行如下命令。

mount --make-private <mount-obiect>

通过执行以下命令,可以将挂载对象标记为不可绑定的。

mount --make-unbindable <mount-object>

这些设置都可以递归式地应用到所有子目录中,如果大家感兴趣可以自行搜索相关命令在代码中实现 mount namespace 隔离与其他 namespace 类似,加上 CLONE_NEWNS 标识位即可。让我们再次修改代码,并且另存为 mount.c 进行编译运行。

// [...]
int child pid = clone(child main, child stack + STACK_SIZE, CLONE_NEWNS | CLONE_NEWPID | CLONE_NEWIPC | CLONE_NEWUTS | SIGCHLD,NULL);
// [...]

CLONE_NEWNS 生效之后,子进程进行的挂载与卸载操作都将只作用于这个 mount namespace,因此在上文中提到的处于单独 PID namespace 隔离中的进程在加上 mount namespace 的隔离之后,即使该进程重新挂载了 /proc 文件系统,当进程退出后,root mountnamespace(主机)的 /proc 文件系统是不会被破坏的。

2.Network namespace

当我们了解完各类 namespace,兴致勃勃地构建出一个容器,并在容器中启动一个 Apache 进程时,却出现了 “80 端口已被占用” 的错误,原来主机上已经运行了一个 Apache 进程,这时就需要借助 network namespace 技术进行网络隔离。

network namespace 主要提供了关于网络资源的隔离,包括网络设备、IPv4 和 IPv6 协议栈、IP 路由表、防火墙、/proc/net 目录、/sys/class/net 目录、套接字(socket)等。一个物理的网络设备最多存在于一个 network namespace 中,可以通过创建 veth pair虚拟网络设备对:有两端,类似管道,如果数据从一端传入,另一端也能接收到,反之亦然)在不同的 network namespace 间创建通道,以达到通信目的。

vethVirtual Ethernet Device 的缩写,是一种成对出现的 Linux 虚拟网络接口设备。它最常用的功能是用于将不同的 Linux network namespaces 命名空间网络连接起来,让两个 namespaces 之间可以进行通信。我们可以简单的把 veth pair 理解为用一根网线,把两台电脑(两个 namespaces)连接起来。这样我们就很好理解,veth pair 的任何一端 down 掉了,另外一端也就 down 掉了。

在这里插入图片描述

一般情况下,物理网络设备都分配在最初的 root namespace(表示系统默认的 namespace)中。但是如果有多块物理网卡,也可以把其中一块或多块分配给新创建的 network namespace。需要注意的是,当新创建的 network namespace 被释放时(所有内部的进程都终止,并且 namespace 文件没有被挂载或打开),在这个 namespace 中的物理网卡会返回到 root namespace,而非创建该进程的父进程所在的 network namespace

当说到 network namespace 时,指的未必是真正的网络隔离,而是把网络独立出来,给外部用户一种透明的感觉,仿佛在与一个独立网络实体进行通信。为了达到该目的,容器的经典做法就是创建一个 veth pair,一端放置在新的 namespace 中,通常命名为 eth0 ,一端放在原先的 namespace 中连接物理网络设备,再通过把多个设备接入网桥或者进行路由转发,来实现通信的目的。

也许大家会好奇,在建立起 veth pair 之前,新旧 namespace 该如何通信呢?答案是 pipe管道)。以 Docker daemon 启动容器的过程为例,假设容器内初始化的进程称为 init。Docker daemon 在宿主机上负责创建这个 veth pair,把一端绑定到 docker0 网桥上,另一端接入新建的 network namespace 进程中。这个过程执行期间,Docker daemon 和 init 就通过 pipe 进行通信。具体来说,就是在 Docker daemon 完成 veth pair 的创建之前,init 在管道的另一端循环等待,直到管道另一端传来 Docker daemon 关于 veth 设备的信息,并关闭管道。init 才结束等待的过程,并把它的 eth0 启动起来。整个结构如下图所示。
在这里插入图片描述

与其他 namespace 类似,对 network namespace 的使用其实就是在创建的时候添加 CLONE_NEWNET 标识位。后续博客将会对 Docker 网络进行详细介绍,此处不再赘述。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/159676.html

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

相关文章

[23] T^3Bench: Benchmarking Current Progress in Text-to-3D Generation

3D生成蓬勃发展&#xff0c;主流方法通过事例比较和用户调查来评价方法好坏&#xff0c;缺少客观比较指标&#xff1b;本文提出Bench&#xff0c;首次综合比较了不同生成方法&#xff1b;具体来说&#xff0c;本文设计了质量评估&#xff08;Quality Assessment&#xff09;和对…

MyBatisPlus的学习项目页面

MyBatisPlus通过扫描实体类&#xff0c;并基于反射获取实体类信息作为数据库表信息 类名驼峰转下划线作为表名 名为id的字段作为主键 变量名驼峰转下划线作为表的字段名 常见注解 TableName&#xff1a;用来指定表名 Tableld&#xff1a;用来指定表中的主键字段信息 Tabl…

攻防世界题目练习——Web引导模式(三)(持续更新)

题目目录 1. mfw2.3.4.5. 1. mfw 进去看到网页和页面内容如下&#xff1a; 看到url的参数 ?pageabout &#xff0c;我以为是文件包含什么的&#xff0c;反复试了几次&#xff0c;想用 …/…/…/…/etc/passwd &#xff0c;但是发现.似乎被过滤了&#xff0c;实在不知道怎么做…

SpringCloud学习笔记-Nacos服务分级存储模型

Nacos服务分级存储模型 一级是服务&#xff0c;例如userservice二级是集群&#xff0c;例如杭州或上海三级是实例&#xff0c;例如杭州机房的某台部署了userservice的服务器 微服务互相访问时&#xff0c;应该尽可能访问同集群实例&#xff0c;因为本地访问速度更快。当本集…

Pygame中将鼠标形状设置为图片2-1

在Pygame中利用Sprite类的派生类将鼠标形状设置为图片&#xff0c;其原理就是将Sprite类的派生类对应图片的位置设置为鼠标的当前位置即可。其效果如图1所示。 图1 将鼠标设置为图片 从图1可以看出&#xff0c;鼠标的形状变为红色的&#xff0c;该红色的随着鼠标的移动而移动&…

前后端数据导入导出Excel

一&#xff1a;导入 Excel有读取也便有写出&#xff0c;Hutool针对将数据写出到Excel做了封装。 原理 Hutool将Excel写出封装为ExcelWriter&#xff0c;原理为包装了Workbook对象&#xff0c;每次调用merge&#xff08;合并单元格&#xff09;或者write&#xff08;写出数据&…

激发创意,打造震撼视觉效果——Adobe After Effects 2024(Ae2024)全新来袭!

想要创造独特的、令人惊叹的视觉效果吗&#xff1f;不要犹豫&#xff0c;现在就升级到全新的Adobe After Effects 2024&#xff08;Ae2024&#xff09;&#xff01;作为业界领先的动态图形和视觉效果软件&#xff0c;Ae2024将为您的创作带来前所未有的火花。 Ae2024拥有强大的…

GPT实战系列-ChatGLM2部署Ubuntu+Cuda11+显存24G实战方案

GPT实战系列-ChatGLM2部署UbuntuCuda11显存24G实战方案 自从chatGPT掀起的AI大模型热潮以来&#xff0c;国内大模型研究和开源活动&#xff0c;进展也如火如荼。模型越来越大&#xff0c;如何在小显存部署和使用大模型&#xff1f; 本实战专栏将评估一系列的开源模型&#xf…

处理ElementUI组件默认样式多次重复问题

问题截图&#xff1a; 解决办法&#xff1a; 在postcss.config.js文件里添加配置项&#xff1a; module.exports {plugins: {autoprefixer: {},cssnano: {} //添加这行代码}, } 处理结果&#xff1a; github issues&#xff1a; https://github.com/ElemeFE/element/is…

【LeetCode高频SQL50题-基础版】打卡第6天:第31~35题

文章目录 【LeetCode高频SQL50题-基础版】打卡第6天&#xff1a;第31~35题⛅前言员工的直属部门&#x1f512;题目&#x1f511;题解 判断三角形&#x1f512;题目&#x1f511;题解 连续出现的数字&#x1f512;题目&#x1f511;题解 指定日期的产品价格&#x1f512;题目&am…

让ChatGPT等模型学会自主思考!开创性技术“自主认知”框架

ChatGPT、百度文心一言、Bard等大语言模型展现出了超强的创造能力&#xff0c;加速了生成式AI的应用进程。但AI模型只能基于训练数据执行各种任务&#xff0c;无法像人类一样利用生活知识、过往经验用于复杂的推理和决策。 例如&#xff0c;在玩游戏时&#xff0c;人类可以利用…

01Maven的工作机制: Maven作为依赖管理工具以及Maven作为构建管理工具

Maven的特点及其应用 Maven是Apache软件基金会组织维护的一款专门为Java项目提供构建和依赖管理支持的工具 Maven作为依赖管理工具 管理jar包的规模: 随着我们使用的框架数量越来越多以及框架的封装程度也越来越高&#xff0c;项目中使用的jar包也就越来越多 Maven工程中依…

Qt QMovie和QLabel配合播放GIF表情包

文章目录 效果演示main函数创建MoviePlayer对象头文件movieplayer.h源文件movieplayer.cpp代码解释在Qt框架中,QMovie是用于处理动画和视频的类。所有源码已在本篇文章公布。 效果演示 main函数创建MoviePlayer对象 #include <QApplication>#include "movie

至强服务器BIOS/UEFI驱动开发笔记

至强服务器BIOS/UEFI驱动开发笔记 驱动开发基础Hello UEFI Driver 项目选择项目位置初始化驱动代码文件结构驱动程序入口和基本功能导入AMI工程AMI平台Hello UEFI Driver 编译问题测试结果打印设备列表继续开发`HelloWorldSupported`函数依赖配置使用脚本编译编译测试此DXE驱动…

RCNN系列网络的理解

R-CNN 作者 &#xff1a; Ross Girshick FAST R-CNN 作者 &#xff1a; Ross Girshick FASTER R-CNN 作者 &#xff1a; Jian Sun MASK R-CNN 作者 &#xff1a;kaiming he 一…

kong 和konga网关部署及使用

Kong是一款基于OpenResty&#xff08;Nginx Lua模块&#xff09;编写的高可用、易扩展的&#xff0c;由Mashape公司开源的API Gateway项目。Kong是基于NGINX和Apache Cassandra或PostgreSQL构建的&#xff0c;能提供易于使用的RESTful API来操作和配置API管理系统&#xff0c;…

使用XLua在Unity中获取lua全局变量和函数

1、Lua脚本 入口脚本 print("OK") --也会执行重定向 require("Test") 测试脚本 print("TestScript") testNum 1 testBool true testFloat 1.2 testStr "123"function testFun()print("无参无返回") endfunction te…

Android Framework通信:Handler

文章目录 前言一、Handler源码分析1、创建Handler2、发送消息3、取消息4、消息处理5、线程切换的方法&#xff08;Handler异步消息处理机制流程&#xff09;handler.sendMessage()handler.post()View.post()Activity中的runOnUiThread() 二、Handler高频面试题1、为什么要有Han…

React TreeSelect设置默认展开项的方法

需要实现TreeSelect组件的onTreeExpand、treeExpandedKeys方法。 代码样例如下&#xff1a; 1.TreeSelect标签部分 render() {const {codeselect} this.props;const {treeExpandedKeys} this.state ................<TreeSelectshowSearch{false}dropdownStyle{{ maxHei…

Java架构师缓存架构设计解决方案

目录 1 缓存常见的三大问题1.1 缓存雪崩1.2 缓存穿透1.3 缓存击穿2 缓存key的生成策略3 热点数据集中失效的问题4 如何提高缓存的命中率5 缓存和数据库双写不一致的问题6 如何对缓存数据进行分片想学习架构师构建流程请跳转:Java架构师系统架构设计 1 缓存常见的三大问题 缓…