2023-06-18 20:23:15 来源:博客园
前言
简单介绍一下一些容器的操作原理。
(资料图片)
正文
docker exec 是怎么做到进入容器里的呢。
比如说:
这里有一个容器,我们可以exec 进去:
docker exec -it b265 /bin/sh我们为什么能看到和容器内部一样的场景呢?
首先我们知道了为什么容器进程只能看到规定的namespace了,那么如果我们能拿到这个namespace的信息,那么我们就能看到容器进程一样的场景了。
docker inspect --format "{{ .State.Pid }}" b26585ee826b上面可以查看容器进程。
可以查看namespace信息。
#define _GNU_SOURCE#include #include #include #include #include #define errExit(msg) do { perror(msg); exit(EXIT_FAILURE);} while (0)int main(int argc, char *argv[]) {int fd;fd = open(argv[1], O_RDONLY);if (setns(fd, 0) == -1) {errExit("setns");}execvp(argv[2], &argv[2]);errExit("execvp");} 写入到文件中,然后编译:
tee exectest.c <<- "EOF" > #define _GNU_SOURCE> #include > #include > #include > #include > #include > > #define errExit(msg) do { perror(msg); exit(EXIT_FAILURE);} while (0)> > int main(int argc, char *argv[]) {> int fd;> > fd = open(argv[1], O_RDONLY);> if (setns(fd, 0) == -1) {> errExit("setns");> }> execvp(argv[2], &argv[2]);> errExit("execvp");> }> EOF gcc -o exectest exectest.c然后运行./exectest:
./exectest /proc/17240/ns/mnt /bin/sh那么看下这个进程看到的信息是啥:
./exectest /proc/17240/ns/mnt /bin/sh看到的信息:
这段代码的的核心操作,则是通过 open() 系统调用打开了指定的 Namespace 文件,并把这个文件的描述符 fd 交给 setns() 使用。在 setns() 执行后,当前进程就加入了这个文件对应的 Linux Namespace 当中了
你也可以将网络带进去:
正如上所示,当我们执行 ifconfig 命令查看网络设备时,我会发现能看到的网卡“变少”了:只有两个。而我的宿主机则至少有四个网卡。这是怎么回事呢?实际上,在 setns() 之后我看到的这两个网卡,正是我在前面启动的 Docker 容器里的网卡。也就是说,我新创建的这个 /bin/bash 进程,由于加入了该容器进程(PID=25686)的 Network Namepace,它看到的网络设备与这个容器里是一样的,即:/bin/bash 进程的网络设备视图,也被修改了。而一旦一个进程加入到了另一个 Namespace 当中,在宿主机的 Namespace 文件上,也会有所体现。
其实就是将自己的namespace 指向了原来容器进程的namespace。
查看进程号:
发现和原来的17240进程的net一样。
此外,Docker 还专门提供了一个参数,可以让你启动一个容器并“加入”到另一个容器的Network Namespace 里,这个参数就是 -net,比如:
docker run -it --net container:4ddf4638572d busybox ifconfig
而如果我指定–net=host,就意味着这个容器不会为进程启用 Network Namespace。这就意味着,这个容器拆除了 Network Namespace 的“隔离墙”,所以,它会和宿主机上的其他普通进程一样,直接共享宿主机的网络栈。这就为容器直接操作和使用宿主机网络提供了一个渠道。
docker commit 干了啥? 比如我们提交一个容器。
docker commit,实际上就是在容器运行起来后,把最上层的“可读写层”,加上原先容器镜像的只读层,打包组成了一个新的镜像。当然,下面这些只读层在宿主机上是共享的,不会占用额外的空间。而由于使用了联合文件系统,你在容器里对镜像 rootfs 所做的任何修改,都会被操作系统先复制到这个可读写层,然后再修改。这就是所谓的:Copy-on-Write。而正如前所说,Init 层的存在,就是为了避免你执行 docker commit 时,把 Docker 自己对 /etc/hosts 等文件做的修改,也一起提交掉。
前面我已经介绍过,容器技术使用了 rootfs 机制和 Mount Namespace,构建出了一个同宿主机完全隔离开的文件系统环境。这时候,我们就需要考虑这样两个问题:
- 容器里进程新建的文件,怎么才能让宿主机获取到?
- 宿主机上的文件和目录,怎么才能让容器里的进程访问到?这正是 Docker Volume 要解决的问题:Volume 机制,允许你将宿主机上指定的目录或者文件,挂载到容器里面进行读取和修改操作。
在 Docker 项目里,它支持两种 Volume 声明方式,可以把宿主机目录挂载进容器的 /test目录当中:
docker run -v /test ...docker run -v /home:/test ...而这两种声明方式的本质,实际上是相同的:都是把一个宿主机的目录挂载进了容器的/test 目录。
只不过,在第一种情况下,由于你并没有显示声明宿主机目录,那么 Docker 就会默认在宿主机上创建一个临时目录 /var/lib/docker/volumes/[VOLUME_ID]/_data,然后把它挂载到容器的 /test 目录上。而在第二种情况下,Docker 就直接把宿主机的 /home 目录挂载到容器的 /test 目录上
当容器进程被创建之后,尽管开启了 Mount Namespace,但是在它执行 chroot(或者 pivot_root)之前,容器进程一直可以看到宿主机上的整个文件系统
而宿主机上的文件系统,也自然包括了我们要使用的容器镜像。这个镜像的各个层,保存在/var/lib/docker/aufs/diff 目录下,在容器进程启动后,它们会被联合挂载在/var/lib/docker/aufs/mnt/ 目录中,这样容器所需的 rootfs 就准备好了。所以,我们只需要在 rootfs 准备好之后,在执行 chroot 之前,把 Volume 指定的宿主机目录(比如 /home 目录),挂载到指定的容器目录(比如 /test 目录)在宿主机上对应的目录(即 /var/lib/docker/aufs/mnt/[可读写层 ID]/test)上,这个 Volume 的挂载工作就完成了。
更重要的是,由于执行这个挂载操作时,“容器进程”已经创建了,也就意味着此时Mount Namespace 已经开启了。所以,这个挂载事件只在这个容器里可见。你在宿主机上,是看不见容器内部的这个挂载点的。这就保证了容器的隔离性不会被 Volume 打破。
注意:这里提到的 " 容器进程 ",是 Docker 创建的一个容器初始化进程(dockerinit),而不是应用进程 (ENTRYPOINT + CMD)。dockerinit 会负责完成根目录的准备、挂载设备和目录、配置 hostname 等一系列需要在容器内进行的初始化操作。最后,它通过 execv() 系统调用,让应用进程取代自己,成为容器里的 PID=1 的进程。而这里要使用到的挂载技术,就是 Linux 的绑定挂载(bind mount)机制。它的主要作用就是,允许你将一个目录或者文件,而不是整个设备,挂载到一个指定的目录上。并且,这时你在该挂载点上进行的任何操作,只是发生在被挂载的目录或者文件上,而原挂载点的内容则会被隐藏起来且不受影响
所以,在一个正确的时机,进行一次绑定挂载,Docker 就可以成功地将一个宿主机上的目录或文件,不动声色地挂载到容器中。
这样,进程在容器里对这个 /test 目录进行的所有操作,都实际发生在宿主机的对应目录(比如,/home,或者 /var/lib/docker/volumes/[VOLUME_ID]/_data)里,而不会影响容器镜像的内容。那么,这个 /test 目录里的内容,既然挂载在容器 rootfs 的可读写层,它会不会被 dockercommit 提交掉呢?也不会。
这个原因其实我们前面已经提到过。容器的镜像操作,比如 docker commit,都是发生在宿主机空间的。而由于 Mount Namespace 的隔离作用,宿主机并不知道这个绑定挂载的存在。所以,在宿主机看来,容器中可读写层的 /test 目录(/var/lib/docker/aufs/mnt/[可读写层 ID]/test),始终是空的。
不过,由于 Docker 一开始还是要创建 /test 这个目录作为挂载点,所以执行了 dockercommit 之后,你会发现新产生的镜像里,会多出来一个空的 /test 目录。毕竟,新建目录操作,又不是挂载操作,Mount Namespace 对它可起不到“障眼法”的作用。
实验:
docker run -d -v /test nginx查看挂载信息:
那么是哪一个呢?
docker inspect a9c79直接看这个好了。
docker exec -it a9c79 /bin/bash然后运行一下:
在里面写了一下文件.
然后看下这个目录里面有不。
然后我们看下读写层有不:
有一个test 目录,但是是空的。
可以确认,容器 Volume 里的信息,并不会被 docker commit 提交掉;但这个挂载点目录 /test 本身,则会出现在新的镜像当中。
如果你执行 docker run -v /home:/test 的时候,容器镜像里的 /test 目录下本来就有内容的话,你会发现,在宿主机的 /home 目录下,也会出现这些内容。这是怎么回事?为什么它们没有被绑定挂载隐藏起来呢?(提示:Docker 的“copyData”功能)
结
下一节k8s的本质。
标签:
- 加快虚拟仿真实训基地建设 启动职业学校信息化建设试点很必要
- “双减”后如何在满足学生多样需求方面做“加法”?
- 处于生理活跃期且心理发展不成熟 高校开设公共卫生必修课很必要
- 价格低于相应蔬菜零售价 西安投放约1万吨政府储备蔬菜
- 深受年轻消费群体所青睐 国潮风商品成为年货新选择
知识
- 他把银行卡卖给骗子,“黑吃黑”“截胡”十万元
- “老司机”4S店试驾豪车 结果油门当刹车撞了
- 新开工改造城镇老旧小区5.34万个
- 发动巡河志愿者2万余名 “用心护好每一条河”
- 假客服的套路:伪装成大平台客服,层层布局引人上钩
人物
- 当前热门:小鲨易贷网贷逾期7个月征信有什么影响
- 通讯!业界:搭平台促交流 助力中国白酒走向世界
- 视讯!LPR连续四月不变 专家预计短期内仍将持稳
- 环球热资讯!57.5% 网友赞成,马斯克或将卸任 Twitter CEO
- 提钱花网贷逾期半年会不会上征信_速看料
- 育碧正在为其《星球大战》游戏寻找测试人员
- 世界杯的阿尔法之战
- 别受伤!浓眉篮下被小卡晃飞 空中失去重心后背着地 当前速讯
- 世界新资讯:中油测井多相位定向光纤避射技术填补空白
- 天天快资讯:中材科技: 董事会决议公告
- 每日热门:锦程消费金融的一股东想彻底退出
- 深南电A董秘回复:关于您提出的问题,现回复如下:公司目前的主营业务为天然气发电,未涉及到核聚变反应相关业务
- 热议:伯特利: 芜湖伯特利汽车安全系统股份有限公司章程(2022年12月修订)(更正后)
- 宝钢包装(601968)12月15日主力资金净买入24.60万元 今日播报
- 鸥玛软件董秘回复:截至11月30日,公司股票持有数量15,896户
- 铂力特: 西安铂力特增材技术股份有限公司监事会关于2020年限制性股票激励计划首次授予部分第二个归属及预留授予第一个归属期归属名单的核查意见 今日报
- 济源市人民法院:加强失信曝光、法律文书电子送达 全球新要闻
- 【机构调研记录】中海基金调研楚江新材、伟星新材等4只个股(附名单)
- 世界通讯!一边要路权,一边要停车,占路20余年车棚这样拆违腾路
- 环球热消息:独家资金:早盘主力买入前10股
- 免费可商用!荣耀HONOR Sans字体来了 附下载
- 在南洋与中文相遇(阅读时光)_短讯
- 源杰科技(688498)新股概览,12月12日开始网上申购-视焦点讯
- 中欣氟材董秘回复:谢谢您对本公司的关注,目前公司钠电池电解液添加液产品正在设计及设备订购等前期项目准备中
- 头条:英集芯(688209)12月7日主力资金净卖出490.52万元
- 股票行情快报:石化机械(000852)12月6日主力资金净卖出3954.17万元
- 浙江两轮核酸检测结果均为阴性 无新增本土阳性感染者
- 新疆阿克苏地区库车市发生4.1级地震 震源深度18千米
- 抵返哈尔滨人员须持48小时内核酸检测阴性证明
- 浙大紫金港校区已解封 有7337人有序离开该校区
- 2021年广东省第七届风筝锦标赛落幕
- 黑龙江讷河市启动全员核酸检测 目前讷河市全员核酸检测结果均为阴性
- 【同心粤港澳 携手大湾区】南头古城,搭建深港澳三地文化创意活动交流平台
- 重庆入河排污口整治工作推进至全市26个区县
- 四川省第二批政法队伍教育整顿:立案审查调查省级政法机关干警58人
- 长三角区域生态环境部门“云签约”长江大保护倡议书
- 古老长城重焕新生机
- 藏不住了!你同事里有许多“武林高手”……
- 浙江杭州2例无症状感染者系感染德尔塔变异株
- 喜马拉雅的深情和誓言
- 浪漫之城打造山海城一体新地标
- 让老年人更适应数字生活
- 内蒙古通辽市新增1例本土确诊病例、1例无症状感染者
- 徐州无新增确诊病例 核酸检测55515人结果均为阴性
- 甘肃培树“农家巧娘”增技能:返乡创业掌勺又“掌柜”
- 内蒙古通辽市科尔沁区一地调整为中风险地区
- 上海本轮疫情涉及闭环管理的医疗机构全面恢复门急诊
- 青年学生成艾滋病感染高发人群 “社会疫苗”如何打?
- 内蒙古满洲里新增本土确诊病例1例 当地开展第二轮大规模核酸检测
- 江西无新增本土确诊病例 上饶全面恢复正常生产生活秩序
精彩阅读
- 中老铁路上会四国语言的列车长:用心维护中老友谊的桥梁
- 海南首次发现有环志的世界极危鸟种勺嘴鹬
- 一场“网络劝生者”和“网络劝死者”的战役
- 内蒙古通辽新增本土确诊和无症状感染者各1例 轨迹公布
- 江西中烟工业有限责任公司原总经理姚庆艳接受审查调查
- 宁夏45例新冠肺炎确诊病例均已治愈出院
- 内蒙古通辽市科尔沁区发现2名初筛阳性人员
- 生活在闹钟里的丈夫:自己迟一秒,渐冻症妻子就会多一分疼
- 辽宁新冠肺炎确诊病例零新增
- 11月28日16-24时,内蒙古新增本土确诊病例1例
- 奥密克戎毒株为何“需要关注”?现有防疫工具还有效吗?
- 黑龙江新增本土无症状感染者1例
- 这辈子一定要去趟这个公园 在这里“有种爱叫放手”
- 那年今日 | 一张漫画涨知识之11月29日
- 寒潮预警!我国中东部迎大范围降温 黑龙江等地降幅可达12℃
- 冷空气继续影响我国中东部 华北黄淮等地有雾和霾天气
