容器目录挂载原理

news/2024/11/25 21:58:27/

前言

就我目前的对容器的了解, 使用namespace技术实现隔离, 使用cgroups技术实现资源限制. 但是具体是如何实现却从未深究过.

闲来无事, 挑其中的Mount Namespace来康康, 容器是如何实现目录隔离的.

目录隔离

在耗子叔的这篇文章中对此技术进行了介绍.

c函数库中, 可通过如下方式实现目录的隔离:

int container_main(void* arg)
{// 调用 mount 方法, 触发目录隔离机制. 将根目录替换为 /root/tmpmount("/root/tmp", "/", "tmpfs", 0, "");// dosomethingreturn 1;
}void main(){// 调用 clone 创建子进程// 传递 CLONE_NEWNS 标识, 标明需要创建目录隔离clone(container_function, stack, CLONE_NEWNS | SIGCHLD , NULL)
}

如果想在命令行中测试目录隔离, 也可以如此操作:


# 创建用于挂载的临时目录
mkdir -p mount/bin
mkdir -p mount/lib64
mkdir -p mount/lib
# 将执行文件放进去
cp /bin/ls  mount/bin
# 将依赖的链接库放入 (依赖库可通过命令 ldd /bin/ls 查看)
cp /lib/x86_64-linux-gnu/libselinux.so.1 mount/lib
cp /lib/x86_64-linux-gnu/libc.so.6 mount/lib/
cp /lib/x86_64-linux-gnu/libpcre.so.3 mount/lib/
cp /lib/x86_64-linux-gnu/libdl.so.2 mount/lib/
cp /lib64/ld-linux-x86-64.so.2 mount/lib64/
cp /lib/x86_64-linux-gnu/libpthread.so.0 mount/lib/
# 替换运行进程的根目录
# 执行此命令时, chroot 命令会将 ls 命令的运行根目录替换为 ./mount 目录
# 可以尝试着执行 /bin/ls 命令查看
chroot ./mount /bin/ls

至此, 虽然举的例子很简单, 但依然足够我们理解目录隔离了. 容器启动后, 会将整个进程的根目录换掉, 甚至直接挂载整个操作系统的ISO. 这也就解释了为什么容器只是一个运行在宿主机上的进程, 却可以表现为不同的操作系统.

docker中, 容器和镜像的文件系统目录, 保存在宿主机的/var/lib/docker/overlay2.

你可以通过命令docker inspect <container_id>来查看容器的层级关系.

至于docker是如何将镜像的多层进行聚合, 最终展现给容器的, 简单说是通过UnionFS 技术, 将多个目录挂载到同一个目录下, 且可以设置优先级. 因为使用了union mount技术, 因此在overlay2中是看不到容器的完整文件系统的. 它实际上并没有在磁盘上创建一个包含所有层文件的单一目录。相反,当你查看容器的文件系统时,Docker 和 Linux 内核会动态地将所有层组合在一起,使它们看起来像一个单一的文件系统。因此,即使你可以在 /var/lib/docker/overlay2 下找到每个层的文件,你也不能直接在这里找到一个包含容器完整文件系统的单一目录.

虽然在overlay2目录下没有容器的完整文件系统, 但其实在宿主机的/proc/<pid>/root目录中可以看到, 不过前面也说了, 完整的文件系统是动态组合的, 因此/proc/<pid>/root目录也只是一个软连接. 至于容器的pid, 可以通过命令docker inspect --format '{{ .State.Pid }}' <container_id>获取.

exec

目录隔离使得容器启动后文件系统自成一派. 那么执行exec命令进入容器时, 又是如何做到的呢?

那必然是系统已经支持的啦. 在/proc/<pid>/ns目录下, 记录了命令空间隔离的数据.

在这里插入图片描述

其中的mnt记录的就是目录隔离. 可以使用命令行nsenter -t <pid> -m来进入到特定进程的目录命名空间. (-m 表示要进入 mount namespace). 命令执行后, 再执行ls命令, 就会发现已经进入到容器的文件系统中了.

c的函数库中, 则使用setns函数来实现此功能. 函数具体使用不做赘述.


至此, 容器是如何做到目录隔离的, 有了一个大致模糊的印象. 收工.


http://www.ppmy.cn/news/75056.html

相关文章

Useraws的ec2服务器安装mysql

要在AWS EC2实例上安装MySQL&#xff0c;您可以按照以下步骤进行操作&#xff1a; 1. 启动EC2实例&#xff1a;登录到AWS控制台&#xff0c;启动一个EC2实例。确保您选择了合适的实例类型和配置&#xff0c;并确保具有所需的存储容量。 2. 连接到EC2实例&#xff1a;使用SSH客…

解决城市内涝的措施有哪些?需要用到哪些监测设备?

随着城市化的不断推进&#xff0c;城市内涝问题日益凸显。极端天气事件如暴雨、台风等对城市基础设施和居民生活造成了严重影响。那么&#xff0c;解决城市内涝的措施有哪些?需要用到哪些监测设备?针对上述问题&#xff0c;本文会为大家一一进行讲解。 解决城市内涝的措施有哪…

不要被别人影响,踏实做自己的事

预习 笔记 复习 做题 专注 效率 记忆 欢迎观看我的博客&#xff0c;如有问题交流&#xff0c;欢迎评论区留言&#xff0c;一定尽快回复&#xff01;&#xff08;大家可以去看我的专栏&#xff0c;是所有文章的目录&#xff09;   文章字体风格&#xff1a; 红色文字表示&#…

Scala学习(七)---面向对象特质

文章目录 1.面向对象特质(Trait)2.特质声明2.1 特质的特点2.2 特质冲突2.3 特质叠加2.4 特质自身类型2.5 特质和抽象类的区别扩展 1.面向对象特质(Trait) 在Scala语言中&#xff0c;采用特质trait(特征)来代替接口的概念&#xff0c;也就是说&#xff0c;多个类具有相同的特质…

MarkDown语法1

MarkDown语法1 段落样式 RUNOOB.COM GOOLE.COM 字体 斜体文本 斜体文本 粗体文本 粗斜体文本 粗斜体文本 高亮文本 高亮加粗文本 分割线 删除线 RUNOOB.COM GOOGLE.COM BAIDU.COM 下划线 带下划线文本 脚注 MarkDown列表 MarkDown支持有序列表和无序列表。…

电脑版pdf阅读器有哪些?编辑途径分析

PDF 阅读器电脑版是一种十分流行的电子文档阅读工具&#xff0c;它可以让用户在电脑上轻松地阅读各种文档&#xff0c;包括 PDF 文件。在数字化信息时代&#xff0c;PDF 阅读器电脑版已经成为了许多人电脑上必备的工具之一。本文将探讨 PDF 阅读器电脑版的优缺点&#xff0c;以…

体验css:repeat和grid

文章目录 一、repeat1. 语法2. auto-fill和auto-fit3. 专属尺寸① fr② auto③ max-content④ min-content 二、grid1. 设置grid布局2. 设置列宽行高3. 设置间距4. 设置分区5. 设置布局排列顺序6. 设置单元格内容对齐方式7. 设置整个网格对齐方式8. 设置隐式网格大小9. 设置网格…

波奇学Linux:时间指令,查找指令,压缩指令,热键

日志&#xff1a;时间&#xff0c;日志等级&#xff0c;日志具体信息&#xff0c;其他信息用来记录程序信息 时间指令 data指令显示时间 修改时间显示格式 时间戳&#xff1a; date %s 时间戳&#xff1a;统一的时间格式&#xff0c;因为有时差原因&#xff0c;时间相对于各…