docker使用的核心技术
1.cgroup,这个用来限制cpu和内存;(通过改配置文件,让pid的cpu和内存限制在配置文件里指定的大小)
2.namespace,这个用来隔离进程/文件系统等等;(unshare -m -u /bin/bash,那么当前session就是在一个namespace里了,在这里修改hostname和加载iso文件,是不会影响宿主机的;注意:不止有-m -u还有其他隔离参数)
具体行为:在执行了unshare -m -u /bin/bash的session a里执行hostname可以看到此时的hostname是aaa(此时可以开启另外一个控制台即新的session b),在session a里执行hostname ns1即在隔离里修改hostname,然后执行hostname可以看到session a里确实改成了ns1,此时切换到session b可以看到session b即宿主机里hostname是没有修改为ns1的;(已经测试过不开启隔离修改hostname是会同时影响其他宿主机session)
第二个行为是:mount 1.iso /var/docker/app1_single_write_folder/iso1folder,然后mount |grep iso1folder可以看到挂载了,但是在宿主机session里是看不到的;
3.chroot,用于容器应用的根目录是隔离后的文件系统目录;
这里app1_single_write_folder如果里面是/bin,/lib,/opt这样的结构,则可以chroot到这个目录,实现docker应用真正和宿主机的文件系统隔离
,它应该是在开启隔离后再执行的,而cgroup是改的app1_single_write_folder里面的配置;chroot后就可以执行应用了;
4.overlay2,层叠文件,用于将多个目录“合并”为一个目录,使得一个容器应用的部分资源是可以复用的;
mount -t overlay overlay -o lowerdir=/var/docker/readonly1:/var/docker/readonly2,upperdir=/var/docker/app1_single_write_folder,workdir=/var/docker/app1_single_tmp_folder /var/docker/app1_overlay_merged_folder
最终在宿主机或namespace里mount|grep app1_overlay_merged_folder看到有个加载好的层叠目录,cd到app1_overlay_merged_folder(之前是空白目录,app1_single_tmp_folder工作目录也是空白目录),可以看到它是由只读目录和可写目录堆叠后的目录,往app1_overlay_merged_folder写数据最终是写到了app1_single_write_folder里;
流程是:在宿主机session里先创建一个overlay,即最终是app1_overlay_merged_folder,然后由于app1_single_write_folder里有volume_bbb,
这个时候仍然是在宿主机session里执行:mount --bind /var/host/volume_aaa /var/docker/app1_overlay_merged_folder/volume_bbb,注意这里是用的overlay的而非writedir里的,5里是writedir目录;
然后再通过unshare -m -u /bin/bash开启隔离,最终是这个顺序;
app1_single_write_folder是应用真正的数据目录,但是app1_overlay_merged_folder这个也算(但本质上是空目录,但umount后),因为开启overlay是在宿主机的session里;
5.mount --bind(VOLUME),容器可以挂载外部的文件系统,实现和宿主机文件系统交互。(这个有点忘了,应该是在开启namespace之前先将容器目录即写目录里的某个目录如aaa, aaa bind到宿主机里的其他目录上如/var/kkk,当开启namespace后以及overlay2后,往该aaa目录里写数据,最终在宿主机里/var/kkk里能看到这个数据)
具体是这样:在没有通过unshare开启mount隔离之前,先执行:
mount --bind /var/host/volume_aaa /var/docker/app1_single_write_folder/volume_bbb,然后在宿主机里mount|grep volume_bbb是可以看到的;
然后执行:unshare -m -u /bin/bash后开启了session a,在此session里用mount|grep volume_bbb也一样可以看到这个挂载;
然后在session a里往volume_bbb里写文件,在volume_aaa里可以看到(不管是在session a还是宿主机的),同样的在宿主机的session往volume_aaa里写了文件,在session a里查看volume_bbb也可以看到这个文件,这样就实现了Docker的VOLUME 隔离里访问宿主机的目录文件的效果;
【注意,按这个顺序mount --bind的挂载项,虽然宿主机和session a里都能看到,但是在session a里取消挂载是不会影响宿主机里的,而且退出session a后重新进入session a可以发现又自动挂载了】
6.还有个就是chroot后执行程序前可能会设置LD_LIBRARY_PATH和添加PATH
7.用户这块docker用的是一个ocpuser:1001的账户,它在宿主机里的/etc/passwd里是找不到的,在chroot后的/etc/passwd里是能看到的;
而docker exec -it $containerId /bin/bash的实现原理则是通过命令nsenter,比如在宿主机里执行nsenter --target $pid -m -u -i /bin/bash,然后进去后在su ocpuser
,经过测试这里的/bin/bash可以不要,然后可以实现直接进入namespace就自动切换用户而不需要再次执行命令来切换,具体为:nsenter --target $pid -m -p -i su - ocpuser
8.docker chroot后的home目录~不一定是/home/xxx里,还可以是/opt这样的目录,具体在/etc/passwd里相关账户里有配置。
(似乎不是用的这个)还用到了伪终端技术(pty),实现在宿主机上进入容器里执行命令(错误,docker用到的是nsenter命令实现的在宿主机里开启一个bash并连接到已经存在的namespace里)
N.整体流程:
一.先修改app1_single_write_folder目录里的sys/fs/cgroup/...里的相关内存和cpu限制配置,为后续执行应用时的限制做好准备;
二.在宿主机session里创建overlay挂载目录app1_overlay_merged_folder;
三.如果Dockerfile里有VOLUME,则将挂载overlay目录app1_overlay_merged_folder里的某个子目录(这个子目录真正是在app1_single_write_folder里的,但是要通过overlay目录挂载)挂载到宿主机其他目录里
四.再通过unshare -m -u /bin/bash开启namespace隔离;【也可能是先chroot再开启隔离;问了chatgpt,应该是最后chroot】
五.然后chroot到app1_overlay_merged_folder里,此时/sys/fs/cgroup就是之前app1_single_write_folder/sys/fs/cgroup;
六.然后在新的root环境执行应用;
如果要实现和宿主机共用/bin,/lib等目录,可以在最后的lowerdir里创建空的lib,bin等目录
等挂载了overlay后,再通过:(不行,基本上就几个思路mount --bind,ln -s,多层overlay试了都不行,而又无法将/作为lowerdir,只能复制一份?)
sudo mount --bind /bin /home/silentdoer/DockerStudy/app1_overlay_empty_folder/bin
sudo mount --bind /lib /home/silentdoer/DockerStudy/app1_overlay_empty_folder/lib
sudo mount --bind /lib64 /home/silentdoer/DockerStudy/app1_overlay_empty_folder/lib64
来将系统的这些目录挂载到overlay目录上;【但是有问题,因为这个其实就是VOLUME的方式,这个会导致容器里的程序可以修改宿主机的/bin目录
,而如果是以只读方式挂载,则也有问题,会导致容器无法往/lib里写自己的特有的依赖;但是如果是完全的堆叠则可以,即lowerdir里就是保存有lib,bin等目录且
里面有需要的文件而非软连接或者堆叠目录,到最后overlay里bin显示的是lowerdir和upperdir堆叠后的,upperdir里的会“覆盖”lowerdir里的,这样就能实现】
这里最大的两个问题是,一个是无法以根目录作为lowerdir,第二个是这个堆叠目录无法多个overlay目录进行叠加,比如lowerdir里的某个目录自己也是overlay的目录
,最终是不会叠加的。】
posted on 2023-08-21 18:12 Silentdoer 阅读(24) 评论(0) 编辑 收藏 举报