容器镜像原理- 联合文件系统实践
容器的镜像是一次生成,多次生成容器实例。
镜像的本质其实就是一堆文件,而容器的工作目录就是在镜像的基础上生成一个有读写层的联和文件系统。而镜像文件在联合文件系统中是只读层,当容器在其工作目录有修改操作时,是在读写层进行修改或者新增文件,而不会去修改到原始镜像文件。
什么是联和文件系统
联合文件系统可以把其他文件系统的文件和目录挂载到同一个挂载点下,形成统一的文件系统,在挂载点下形成统一的文件视图。
而当对联合文件系统进行写操作时,其实是写到了新文件上,并没有去修改原文件,在linux上,原生自带了一种联合文件系统类型overlay,接下来用overlay来感受下挂载一个联合文件系统的过程。
动手实践
创建多个目录
mkdir overlaydemo
cd overlaydemo
mkdir container-layer image-layer1 image-layer2 image-layer3 image-layer4 mnt work
其中contailber-layer 后续会作为容器的读写层,image-layer会作为镜像层,mnt作为overlay联合文件系统的挂载目录,而work后续会作为overlay联合文件系统的工作目录,这个目录是overlay自己用的,对用户不可见。
往文件夹里面添加文件
touch image-layer1/image-layer1.txt && echo 'I am image layer1' > image-layer1/image-layer1.txt
touch image-layer2/image-layer2.txt && echo 'I am image layer2' > image-layer2/image-layer2.txt
touch image-layer3/image-layer3.txt && echo 'I am image layer3' > image-layer3/image-layer3.txt
touch image-layer4/image-layer4.txt && echo 'I am image layer4' > image-layer4/image-layer4.txt
touch container-layer/container-layer.txt && echo 'I am container-layer' > container-layer/container-layer.txt
挂载overlay文件系统,挂载目录为mnt
sudo mount -t overlay overlay -olowerdir=image-layer1:image-layer2:image-layer3:image-layer4,upperdir=container-layer,workdir=work mnt/
lowerdir就是下层的只读层文件夹,upperdir作为读写层文件夹,work作为overlay的自身用到的工作目录。
再来看mnt目录,发现已经有刚才挂载过来的文件
parallels@worker1:~/overlaydemo$ tree mnt/
mnt/
├── container-layer.txt
├── image-layer1.txt
├── image-layer2.txt
├── image-layer3.txt
└── image-layer4.txt
0 directories, 5 files
这时如果对image-layer1.txt进行修改
parallels@worker1:~/overlaydemo$ echo 'I am image layer1 test' > mnt/image-layer1.txt
parallels@worker1:~/overlaydemo$ tree container-layer/
container-layer/
├── container-layer.txt
└── image-layer1.txt
0 directories, 2 files
parallels@worker1:~/overlaydemo$ cat mnt/image-layer1.txt
I am image layer1 test
parallels@worker1:~/overlaydemo$ cat image-layer1/image-layer1.txt
I am image layer1
发现在读写层新增了一个image-layer1的文件,然后内容是我们新改的内容,然而在原始image-layer1下的文件却没有发生变化。 证明了image-layer1的确是作为只读层挂载的。
再次思考容器镜像的本质
再回顾下,镜像文件的本质,当启动容器的时候,会为容器创建一个可读写的文件夹作为后续挂载联合文件系统的可读写层,而镜像文件是作为只读层被挂载的,这就是容器镜像一次生成,到处运行的秘密了。
思考题:
如果只有联合文件系统机制,容器运行的时候是不是能看到挂载目录以外的其他主机上的目录,这样并没有达到隔离文件系统的机制,那么该采用什么办法呢,答案是采用根文件系统的机制,后续将会亲自实现下替换进程如何替换根文件系统,敬请期待。