Docker实战09|使用AUFS包装busybox
前几篇文章中,重点讲解了如何实现构建容器,需要回顾的小伙伴可以看以下文章:
- 《Docker实战06|深入剖析Docker Run命令》
- 《Docker实战07|Docker增加容器资源限制》
- 《Docker实战08|Docker管道及环境变量识别》
以上三篇主要实现了Docker Run命令、Docker如何对容器资源进行限制以及Docker不同进程之间是如何进行通信的底层原理与实现。
接下来的时间会和大家一起学习Docker是如何构造镜像的。
使用busybox创建容器
获取代码
git clone https://gitee.com/mjreams/docker.git
busybox
首先使用一个最精简的镜像——busybox。busybox是一个集合了非常多UNIX工具的箱子,他可以提供非常多在UNIX环境下经常使用的命令,可以说busybox提供了一个非常完整而且小巧的系统。 本文中也会先使用它来作为第一个容器内运行的文件系统。
获得busybox文件系统的rootfs很简单,可以使用docker export将一个镜像打成一个tar包。
docker pull busybox
docker run -d busybox top -b
docker export -o busybox.tar 6e6415edd69c(容器ID)
mkdir busybox
tar -xvf ./busybox.tar -C busybox/
root@iZ2ze:~/busybox# ls
bin dev etc home lib lib64 proc root sys tmp usr var
pivot_root
pivot_root是一个系统调用,主要功能是去改变当前的root文件系统。pivot_root可以将当前进程的root文件系统移动到put_old文件夹中,然后使new_root成为新的root文件系统。new_root和put_old必须不能同时存在当前root的同一个文件系统中。pivot_root和chroot的主要区别是,pivot_root是把整个系统切换到一个新的root目录,而移除对之前root文件系统的依赖,这样你就能够umount原先的root文件系统。而chroot是针对某个进程,系统的其他部分依旧运行于老的root目录中。
下面,一起把代码来实现一下。
见container/init.go

有了这个函数后,就可以在init容器进程的时候,进行一系列的mount操作 。

其中,tmpfs是一种基于内存的文件系统,可以使用RAM或swap分区来存储。下面把下载好的busybox放到/root/busybox宿主机的目录下,使用cmd.Dir="/root/busybox"这个方法给创建出来的子进程指定容器初始化后的工作目录,然后就会运行前面讲到的那些进程,挂载rootfs然后把当前目录虚拟成根目录。

将此处修改为cmd.Dir="/root/busybox"
下面运行一下来看看效果。

我此处使用的是容器镜像的名字进行挂载。你如果修改成/root/busybox,则此处显示/root/busybox。
使用AUFS包装busybox
Docker在使用镜像启动一个容器时,会新建2个layer: writelayer和container-init layer。write layer是容器唯一的可读写层:而container-init layer是为容器新建的只读层,用来存储容器启动时传入的系统信息(前面也提到过,在实际的场景下,它们并不是以write layer和container-init layer命名的)。最后把write layer、container叮iit layer和相关镜像的layers都mount到一个mnt目录下,然后把这个mnt目录作为容器启动的根目录。
在上面己经实现了使用宿主机/root/busybox目录作为文件的根目录,但在容器内对文件的操作仍然会直接影响到宿主机的/root/busybox目录。本节要进一步进行容器和镜像隔离,实现在容器中进行的操作不会对镜像产生任何影响的功能。
见container/volume.go

- CreateReadOnlyLayer函数新建busybox文件夹,将busybox.tar 解压到busybox目录下,作为容器的只读层。
- CreateWriteLayer函数创建了一个名为writeLayer的文件夹,作为容器唯一的可写层。
- 在CreateMountPoint函数中,首先创建了mnt文件夹,作为挂载点,然后把writeLayer目录和busybox目录mount到mnt目录下。
最后,在NewParentProcess函数中将容器使用的宿主机目录/root/busybox 替换成/root/mnt。

此处将busybox.tar解压到busybox目录下,作为容器的只读层。
接下来,在NewParentProcess函数中将容器使用的宿主机目录/root/busybox替换成/root/mnt。这样,使用 AUFS 系统启动容器的代码就完成了。

Docker会在删除容器的时候,把容器对应的Write Layer和Container-init Layer删除,而保留镜像所有的内容。本节中,在容器退出的时候会删除Write Layer。DeleteWorkSpace函数,包括DeleteMountPoint和DeleteWrite Layer。
- 首先,在 DeleteMountPoint 函数中 umountmnt 目录 。
- 然后,删除 mnt 目录。
- 最后,在 DeleteWriteLayer 函数中删除 writeLayer 文件夹。这样容器对文件系统的更改就都己经抹去了。
见container/volume.go

整体流程如下:

测试
启动一个容器
./mydocker run -ti sh
sh-5.1# ls /root
bash busybox busybox.tar mnt writeLayer
在容器中新建一个文件夹。

新建一个宿主机窗口,查看/root/mnt目录。

可以看到多了一个studydocker文件夹。
在容器中执行exit退出容器,,然后再次查看宿主机上的/root/mnt文件夹内容。发现已经没有了刚才的容器。
相关文章:
Docker实战09|使用AUFS包装busybox
前几篇文章中,重点讲解了如何实现构建容器,需要回顾的小伙伴可以看以下文章: 《Docker实战06|深入剖析Docker Run命令》《Docker实战07|Docker增加容器资源限制》《Docker实战08|Docker管道及环境变量识别…...
什么是uni.request()?如何使用它?
uni.request()是uni-app提供的一个用于发起网络请求的API。 使用uni.request()的步骤如下: 在需要发起网络请求的页面中引入uni.request()方法。 调用uni.request()方法,并传入相应的参数,包括请求地址、请求方法、请求头部和请求数据等。 …...
用React给XXL-JOB开发一个新皮肤(一):环境搭建和项目初始化
目录 一. 简述二. Fork 项目三. 搭建开发环境四. 初始化皮肤项目五. 添加相关依赖六. 预览 一. 简述 大名鼎鼎的 xxl-job 任务调度中心我们应该都使用过,项目地址:xxl-job。它是一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单…...
华为常用的命令——display,记得点赞收藏!
华为设备提供了多条display命令用于查看硬件部件、接口及软件的状态信息。通常这些状态信息可以为用户故障处理提供定位思路。 常用的故障信息搜集的命令如下: 路由器常用维护命令表 交换机常用的故障信息搜集 关注 工 仲 好:IT运维大本营,获…...
Costco攻入山姆大本营
01 Costco深圳店开业火爆 “我今天不去Costco,早上还没开业,路上就已经堵车了,看来今天人很多,过几天再去”,原本计划在Costco开业当天去逛逛的张芸(化名)无奈只能放弃。 家住在Costco深圳店旁…...
什么是常量?如何区分常量和变量?
一、问题 什么是常量,什么是变量?怎样区分⼆者? 二、解答 1. 常量与变量 (1)常量即其值在程序运⾏的过程中是不可以改变的,如123,-4567 为数值常量; (2)变量…...
uniapp返回上一页并刷新数据
在uniapp中,返回页面时onLoad是不会触发的 如果只需要在特定情况下返回上一页才需要刷新数据 可以使用$emit和$no去解决 例如:注册完成后返回到首页并隐藏注册按钮,register.vue和index.vue register.vue <template><view clic…...
LeetCode 0083.删除排序链表中的重复元素:模拟
【LetMeFly】83.删除排序链表中的重复元素:模拟 力扣题目链接:https://leetcode.cn/problems/remove-duplicates-from-sorted-list/ 给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的…...
Javaweb之SpringBootWeb案例新增部门的详细解析
2.3 删除部门 查询部门的功能我们搞定了,下面我们开始完成删除部门的功能开发。 2.3.1 需求 点击部门列表后面操作栏的 "删除" 按钮,就可以删除该部门信息。 此时,前端只需要给服务端传递一个ID参数就可以了。 我们从接口文档中也…...
基于微信小程序的音乐平台 开源项目
目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示 四、核心代码4.1 查询单首音乐4.2 新增音乐4.3 新增音乐订单4.4 查询音乐订单4.5 新增音乐收藏 五、免责说明 一、摘要 1.1 项目介绍 基于微信小程序JAVAVueSpringBootMySQL的音乐平台,包含了音乐…...
uniapp 微信小程序跳转外部链接
一、背景: 开发小程序时,跳转到内部路径通常会使用:uni.navigateTo,uni.redirectTo,uni.reLaunch,uni.switchTab等方法,可以跳转到pages.json中已经注册的页面 uni.navigateTo(OBJECT) | uni-…...
【STM32】FLASH闪存
1 FLASH闪存简介 本节所指STM32内部闪存,即下载程序的时候,程序存储的地方。(非易失性) STM32F1系列的FLASH包含程序存储器、系统存储器(bootloader,不允许修改)和选项字节三个部分࿰…...
滴水内存地址堆栈
两个十六进制数 刚好是一个字节刚好 DC这的一个字节数据为E4 一个内存地址 后面表示四个字节的数据 所以有八个十六进制的数 BASE是高地址 所以放入一个四字节后就 -4...
Laravel中的lockForUpdate悲观锁
lockForUpdate 是悲观锁,测试就不写了 注意的事项 lockForUpdate 必须在事务中lockForUpdate 被阻塞的查询必须是同样添加了lockForUpdate的语句查询语句走索引,则使用行锁,否则使用表锁 现在举例说明第一项和第二项 开启事务并添加锁 pub…...
BikeDNA(八)外在分析:OSM 与参考数据的比较2
BikeDNA(八)外在分析:OSM 与参考数据的比较2 1.数据完整性 见链接 2.网络拓扑结构 见链接 3.网络组件 本节仔细研究两个数据集的网络组件特征。 断开连接的组件不共享任何元素(节点/边)。 换句话说,…...
28 星际旋转
效果演示 实现了一个太阳系动画,其中包括了地球、火星、金星、土星、水星、天王星、海王星以及火卫二号等行星的动画效果。太阳系的行星都被放在一个固定的容器中,并使用CSS动画来实现旋转和移动的效果。当太阳系的行星绕着太阳运行时,它们会…...
测试人员必备基本功(3)
容易被忽视的bug 第三章 查询列表容易被忽视的bug 文章目录 容易被忽视的bug第三章 查询列表容易被忽视的bug 前言1.查询角色2.接口设计 三、测试设计1.测试点2.容易发现bug的测试点如下: 总结 前言 一个WEB系统的所有功能模块,其实都是围绕“增、删、…...
记一次数据修复,需要生成十万条sql进行数据回滚
一、背景 数据回滚 二、难点 2.1 需要处理的数据涉及多达数万个用户,每个用户涉及的表达到10个 2.2 时间紧急,需要快速回滚,数据需要完整 2.3 数据存在重复或空缺问题 三、解决方案 3.1 数据多,使用分批处理,把大任务分割成若…...
[paddle]paddlehub部署paddleocr的hubserving服务
步骤如下: 第一步:首先需要安装好paddleocr环境已经paddlehub环境 第二步:下载paddleocr源码: git clone https://github.com/PaddlePaddle/PaddleOCR.git 然后切换到paddocr目录执行 新建个文件夹叫Inference把paddleocr模型…...
2024校招,网易互娱游戏测试工程师一面
前言 大家好,今天回顾一下,我前段时间参加的游戏测试工程师技术面试 两个面试官,一个提问,另一个负责记录 过程 自我介绍比赛经历介绍一下使用的博弈算法穷举算法对性能有什么影响怎么评估局面好坏出现的bug怎么解决的&#x…...
UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...
vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
