学习极客时间上的《深入剖析Kubernetes》
秉持眼过千遍不如手过一遍的原则.
以系统调用方式创建namespace实验
ns.c
1 |
|
build ns并进入ns
1 | $ gcc -o ns ns.c |
查看进程(在另外一个窗口中执行)
1 | $ ps -aux |
由上面的操作可见,即使开启了namespace,容器进程看到的文件系统与宿主机一样
重新挂载目录实验
修改代码
- 修改
ns.c
的container_main
函数,新创建文件ns_new.c
注:因为是在虚拟机上实验,根目录类型默认是shared,所以,需要先重新挂载根目录
1 | int container_main(void* arg) |
编译及测试效果
- 在容器内
1 | $ gcc -o ns_new ns_new.c |
- 在宿主机上
1 | $ mount -l | grep tmpfs |
chroot实验
准备
- 创建一个test目录并准备未见
1 | $ mkdir test |
chroot
1 | $ chroot test /bin/bash |
- 以busybox的镜像为例,同样可以chroot
1 | $ chroot busybox /bin/sh |
UnionFS实验
1 | $ mkdir A |
此时,可以尝试修改A/t1.txt
, A/t2.txt
, B/t2.txt
, B/t3.txt
1 | $ echo 'This is a test' > A/t1.txt |
docker image解析
1 | $ docker inspect ubuntu |
你会看到,Ubuntu镜像,在我的环境里面是4层
overlay挂载方式
先启动一个container
1 | $ docker run -it -d ubuntu |
查看系统挂载表
1 | $ cat /proc/mounts | grep overlay |
可以看到,lowerdir由5个目录共同挂载而成,分别是
7ZDIR6KYXXF6RMDW3JCBEQUGMH
TH3OYMS4POUF3S22QNB7UJPORG
BJILDL5W6H6U7LGVSUUS2QUTGO
6F6BVIETKMGL5QLJIOCP6CONB3
P5BANYVEKZJYYPT4M6IFNLAR7Z
查看overlay2目录下的文件
1 | $ ls /var/lib/docker/overlay2/l/ -l |
做个对比
-
容器ID为a274e38,对应的DIR的ID是0c3ff90
-
lowerdir=/var/lib/docker/overlay2/l/7ZDIR6KYXXF6RMDW3JCBEQUGMH
, 实际上指向了0c3ff90aba26b4197b2293789f75d4e3db7a9213601b8d222b1f0c413c7115b2-init/diff
1
2$ ls /var/lib/docker/overlay2/0c3ff90aba26b4197b2293789f75d4e3db7a9213601b8d222b1f0c413c7115b2-init/diff/
dev etc -
/var/lib/docker/overlay2/l/TH3OYMS4POUF3S22QNB7UJPORG
实际上指向了17bd5da0cda20e8ecd1d4955d25f49609ff0d7aa72fe45a0388a357fcc5b625f/diff
1
2$ ls /var/lib/docker/overlay2/17bd5da0cda20e8ecd1d4955d25f49609ff0d7aa72fe45a0388a357fcc5b625f/diff/
run -
而
17bd5da0cda20e8ecd1d4955d25f49609ff0d7aa72fe45a0388a357fcc5b625f/diff
实际上是ubuntu镜像的UpperDir
1
2$ ls /var/lib/docker/overlay2/17bd5da0cda20e8ecd1d4955d25f49609ff0d7aa72fe45a0388a357fcc5b625f/diff/
run -
/var/lib/docker/overlay2/l/BJILDL5W6H6U7LGVSUUS2QUTGO
实际上是823e415d4256d05fb0101af4dcc42a4389d44cf6467972d654e93e0cc575cd9b/diff
-
而
823e415d4256d05fb0101af4dcc42a4389d44cf6467972d654e93e0cc575cd9b/diff
实际上是ubuntu镜像的LowerDir
1
2$ ls /var/lib/docker/overlay2/823e415d4256d05fb0101af4dcc42a4389d44cf6467972d654e93e0cc575cd9b/diff/
etc usr var -
/var/lib/docker/overlay2/l/6F6BVIETKMGL5QLJIOCP6CONB3
实际上是37d3e588905fae55c8a0481e9cda7be36177af874631abb15724c893887e260b/diff
1
2$ ls /var/lib/docker/overlay2/37d3e588905fae55c8a0481e9cda7be36177af874631abb15724c893887e260b/diff/
var -
/var/lib/docker/overlay2/l/P5BANYVEKZJYYPT4M6IFNLAR7Z
实际上是40d198d6f624e455800254766eb6a7190ce02442fc48f02f6f16f72105cefd0d/diff
1
2$ ls /var/lib/docker/overlay2/40d198d6f624e455800254766eb6a7190ce02442fc48f02f6f16f72105cefd0d/diff/
bin boot dev etc home lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var
小结
- 容器的镜像即rootfs是按照一层一层的组合起来的。
- 启动容器进程时,将多个增量的rootfs联合挂载成一个完整的rootfs
- 启动容器时,会只读模式挂载一个init层,以及一个可写的层