
容器使用存储卷实战
1.什么是存储卷
所谓的存储卷就是一种持久化容器数据的一种存储方案。
2.存储卷的基本管理
2.1 清空容器
[root@elk92 ~]# docker container rm -f `docker container ps -qa`
2.2 查看本地的存储卷列表
[root@elk92 ~]# docker volume ls
DRIVER VOLUME NAME
local 0bd65347815590fc2b97b905ce1956cc95ec5a426e5b651abd51ee5bd9728a3a
local 9855be3402732954195ae84bde12747543b21248559dcfe12334e2a6c501bd38
local f9ef3a710d56b5d971961c1ff7c4591353ab86fbe8db4b4774ecb345a2714416
[root@elk92 ~]#
2.3 清理存储卷【清理所有未使用的存储卷】
[root@elk92 ~]# docker volume prune -f
Deleted Volumes:
9855be3402732954195ae84bde12747543b21248559dcfe12334e2a6c501bd38
0bd65347815590fc2b97b905ce1956cc95ec5a426e5b651abd51ee5bd9728a3a
f9ef3a710d56b5d971961c1ff7c4591353ab86fbe8db4b4774ecb345a2714416
Total reclaimed space: 638.8MB
[root@elk92 ~]#
[root@elk92 ~]# docker volume ls
DRIVER VOLUME NAME
[root@elk92 ~]#
2.4 创建存储卷
[root@elk92 ~]# docker volume ls
DRIVER VOLUME NAME
[root@elk92 ~]#
[root@elk92 ~]# docker volume create custom-example # 创建存储卷指定名称
custom-example
[root@elk92 ~]#
[root@elk92 ~]# docker volume ls
DRIVER VOLUME NAME
local custom-example
[root@elk92 ~]#
[root@elk92 ~]#
[root@elk92 ~]# docker volume create # 若不指定存储卷的名称则默认会生成一个匿名(随机)存储卷。
8ee576eb01877bc9feb422d4184ef662c6a7fd1672e459f5803efc8f44d1f4ca
[root@elk92 ~]#
[root@elk92 ~]# docker volume ls
DRIVER VOLUME NAME
local 8ee576eb01877bc9feb422d4184ef662c6a7fd1672e459f5803efc8f44d1f4ca
local oldboyedu-linux96
[root@elk92 ~]#
2.5 删除指定的存储卷
[root@elk92 ~]# docker volume ls
DRIVER VOLUME NAME
local 8ee576eb01877bc9feb422d4184ef662c6a7fd1672e459f5803efc8f44d1f4ca
local custom-example
[root@elk92 ~]#
[root@elk92 ~]#
[root@elk92 ~]# docker volume rm 8ee576eb01877bc9feb422d4184ef66...
8ee576eb01877bc9feb422d4184ef662c6a7fd1672e459f5803efc8f44d1f4ca
[root@elk92 ~]#
[root@elk92 ~]# docker volume ls
DRIVER VOLUME NAME
local custom-example
[root@elk92 ~]#
2.6 查看一个存储卷的详细信息
[root@elk92 ~]# docker volume inspect custom-example
[
{
"CreatedAt": "2025-03-20T09:23:06+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/custom-example/_data",
"Name": "custom-example",
"Options": {},
"Scope": "local"
}
]
[root@elk92 ~]#
[root@elk92 ~]# ll /var/lib/docker/volumes/custom-example/_data
total 8
drwxr-xr-x 2 root root 4096 Mar 20 09:23 ./
drwx-----x 3 root root 4096 Mar 20 09:23 ../
[root@elk92 ~]#
- 3.将存储卷给一个容器使用
3.1 容器使用特定的存储卷
[root@elk92 ~]# ll /var/lib/docker/volumes/custom-example/_data
total 8
drwxr-xr-x 2 root root 4096 Mar 20 09:23 ./
drwx-----x 3 root root 4096 Mar 20 09:23 ../
[root@elk92 ~]#
[root@elk92 ~]#
[root@elk92 ~]#
[root@elk92 ~]# docker run -d --name c2 -v custom-example:/usr/share/nginx/html registry.cn-hangzhou.aliyuncs.com/violet-k8s/apps:v1
a8cdc8eaecb5d0247b672c5a138c71193ab8e71dbf657ff9f573d5e56f2611d5
[root@elk92 ~]#
[root@elk92 ~]# ll /var/lib/docker/volumes/custom-example/_data
total 244
drwxr-xr-x 2 root root 4096 Mar 20 09:26 ./
drwx-----x 3 root root 4096 Mar 20 09:23 ../
-rw-r--r-- 1 root root 233472 Jan 20 2024 1.jpg
-rw-r--r-- 1 root root 494 May 25 2021 50x.html
-rw-r--r-- 1 root root 357 Jan 20 2024 index.html
[root@elk92 ~]#
[root@elk92 ~]#
3.2 修改容器的数据
[root@elk92 ~]# docker container inspect -f "{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" c2
172.17.0.2
[root@elk92 ~]#
[root@elk92 ~]# curl 172.17.0.2
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>yinzhengjie apps v1</title>
<style>
div img {
width: 900px;
height: 600px;
margin: 0;
}
</style>
</head>
<body>
<h1 style="color: green">凡人修仙传 v1 </h1>
<div>
<img src="1.jpg">
<div>
</body>
</html>
[root@elk92 ~]#
[root@elk92 ~]# docker exec -it c2 sh
/ # echo www.vionletarchitect.top > /usr/share/nginx/html/index.html
/ #
/ # cat /usr/share/nginx/html/index.html
www.vionletarchitect.top
/ #
[root@elk92 ~]#
[root@elk92 ~]# curl 172.17.0.2
www.vionletarchitect.top
[root@elk92 ~]#
[root@elk92 ~]# cat /var/lib/docker/volumes/custom-example/_data/index.html
www.vionletarchitect.top
[root@elk92 ~]#
3.3 删除容器观察存储卷是否删除
[root@elk92 ~]# docker rm -f c2
c2
[root@elk92 ~]#
[root@elk92 ~]# ll /var/lib/docker/volumes/custom-example/_data/ # 发现数据并没有丢失
total 244
drwxr-xr-x 2 root root 4096 Mar 20 09:26 ./
drwx-----x 3 root root 4096 Mar 20 09:23 ../
-rw-r--r-- 1 root root 233472 Jan 20 2024 1.jpg
-rw-r--r-- 1 root root 494 May 25 2021 50x.html
-rw-r--r-- 1 root root 18 Mar 20 09:28 index.html
[root@elk92 ~]#
3.4 重新创建新的容器并使用之前的存储卷
[root@elk92 ~]# docker run -d --name c3 -v custom-example:/usr/share/nginx/html registry.cn-hangzhou.aliyuncs.com/violet-k8s/apps:v1
3a79ca38546481517a35a55e49c4105a37808df68ce78d3ac1694f30f5a00eba
[root@elk92 ~]#
[root@elk92 ~]# docker container inspect -f "{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" c3
172.17.0.2
[root@elk92 ~]#
[root@elk92 ~]# curl 172.17.0.2
www.vionletarchitect.top
[root@elk92 ~]#
3.5 将多个容器挂载到同一个存储卷
[root@elk92 ~]# docker run -d --name c4 -v custom-example:/usr/share/nginx/html registry.cn-hangzhou.aliyuncs.com/violet-k8s/apps:v1
9fd1654da34116af2c181f2f28200fc1b6f085c4b6c211270c92a9a2445ad58c
[root@elk92 ~]#
[root@elk92 ~]# docker container inspect -f "{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" c4
172.17.0.3
[root@elk92 ~]#
[root@elk92 ~]# curl 172.17.0.3
www.vionletarchitect.top
[root@elk92 ~]#
[root@elk92 ~]# docker exec -it c4 sh
/ # echo violet > /usr/share/nginx/html/index.html
/ #
[root@elk92 ~]#
[root@elk92 ~]# curl 172.17.0.3
violet
[root@elk92 ~]#
[root@elk92 ~]# curl 172.17.0.2
violet
[root@elk92 ~]#
3.6 新建容器和现有的容器使用相同的存储卷信息
[root@elk92 ~]# docker run -d --name c5 --volumes-from c4 registry.cn-hangzhou.aliyuncs.com/violet-k8s/apps:v1
de5f6acba7c49f7f7d612213d68065ef179f72ec50b31877bf3bf11fc94755fe
[root@elk92 ~]#
[root@elk92 ~]# docker container inspect -f "{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" c5
172.17.0.4
[root@elk92 ~]#
[root@elk92 ~]# curl 172.17.0.4
violet
[root@elk92 ~]#
容器使用存储卷注意事项
- 1.存储卷不存在会自动创建
[root@elk92 ~]# docker volume ls
DRIVER VOLUME NAME
[root@elk92 ~]#
[root@elk92 ~]# docker run -v custom-example:/usr/share/nginx/html -d --name c1 registry.cn-hangzhou.aliyuncs.com/violet-k8s/apps:v1
a3a26860c5dc66c69ba689ed586712bd2e2b0c7f43c037dfe7ea79411c593007
[root@elk92 ~]#
[root@elk92 ~]# docker volume ls
DRIVER VOLUME NAME
local oldboyedu
[root@elk92 ~]#
[root@elk92 ~]# docker volume inspect custom-example
[
{
"CreatedAt": "2025-03-20T10:06:45+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/oldboyedu/_data",
"Name": "custom-example",
"Options": null,
"Scope": "local"
}
]
[root@elk92 ~]# ll /var/lib/docker/volumes/custom-example/_data
total 244
drwxr-xr-x 2 root root 4096 Mar 20 10:06 ./
drwx-----x 3 root root 4096 Mar 20 10:06 ../
-rw-r--r-- 1 root root 233472 Jan 20 2024 1.jpg
-rw-r--r-- 1 root root 494 May 25 2021 50x.html
-rw-r--r-- 1 root root 357 Jan 20 2024 index.html
[root@elk92 ~]#
- 2.若不指定存储卷则会自动创建匿名存储卷
[root@elk92 ~]# docker volume ls
DRIVER VOLUME NAME
local oldboyedu
[root@elk92 ~]#
[root@elk92 ~]# docker run -v /usr/share/nginx/html -d --name c2 registry.cn-hangzhou.aliyuncs.com/violet-k8s/apps:v1
390e754181d6d57de79800ca5b71a12a2501c5d40516c9baf3ea45bea6ae66af
[root@elk92 ~]#
[root@elk92 ~]# docker volume ls
DRIVER VOLUME NAME
local 22d11c315365fe99f0810c343c89c37f60779c5633c6b54fbd2471baad1200b2
local oldboyedu
[root@elk92 ~]#
[root@elk92 ~]#
[root@elk92 ~]# docker volume inspect 22d11c315365fe99f0810c343c89c37f60779c5633c6b54fbd2471baad1200b2
[
{
"CreatedAt": "2025-03-20T10:08:00+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/22d11c315365fe99f0810c343c89c37f60779c5633c6b54fbd2471baad1200b2/_data",
"Name": "22d11c315365fe99f0810c343c89c37f60779c5633c6b54fbd2471baad1200b2",
"Options": null,
"Scope": "local"
}
]
[root@elk92 ~]#
[root@elk92 ~]# ll /var/lib/docker/volumes/22d11c315365fe99f0810c343c89c37f60779c5633c6b54fbd2471baad1200b2/_data
total 244
drwxr-xr-x 2 root root 4096 Mar 20 10:08 ./
drwx-----x 3 root root 4096 Mar 20 10:08 ../
-rw-r--r-- 1 root root 233472 Jan 20 2024 1.jpg
-rw-r--r-- 1 root root 494 May 25 2021 50x.html
-rw-r--r-- 1 root root 357 Jan 20 2024 index.html
[root@elk92 ~]#
- 3.容器删除匿名存储卷
[root@elk92 ~]# docker volume ls
DRIVER VOLUME NAME
local 22d11c315365fe99f0810c343c89c37f60779c5633c6b54fbd2471baad1200b2
local custom-example
[root@elk92 ~]#
[root@elk92 ~]#
[root@elk92 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
390e754181d6 registry.cn-hangzhou.aliyuncs.com/violet-k8s/apps:v1 "/docker-entrypoint.…" 46 seconds ago Up 45 seconds 80/tcp c2
a3a26860c5dc registry.cn-hangzhou.aliyuncs.com/violet-k8s/apps:v1 "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 80/tcp c1
[root@elk92 ~]#
[root@elk92 ~]#
[root@elk92 ~]# docker container rm -f -v `docker ps -aq` # 注意,使用-v选项可以删除匿名的存储卷。
390e754181d6
a3a26860c5dc
[root@elk92 ~]#
[root@elk92 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@elk92 ~]#
[root@elk92 ~]# docker volume ls
DRIVER VOLUME NAME
local custom-example
[root@elk92 ~]#
- 4.使用宿主机的某个路径作为存储卷挂载到容器【如果容器有数据,会将之前的内容清空】
[root@elk92 ~]# mkdir /data
[root@elk92 ~]#
[root@elk92 ~]# echo "欢迎来到天暗星小作坊~" > /data/index.html
[root@elk92 ~]#
[root@elk92 ~]# ll /data/
total 12
drwxr-xr-x 2 root root 4096 Mar 20 10:11 ./
drwxr-xr-x 23 root root 4096 Mar 20 10:10 ../
-rw-r--r-- 1 root root 41 Mar 20 10:11 index.html
[root@elk92 ~]#
[root@elk92 ~]# cat /data/index.html
欢迎来到天暗星小作坊~
[root@elk92 ~]#
[root@elk92 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@elk92 ~]#
[root@elk92 ~]# docker run -v /data:/usr/share/nginx/html -d --name c1 registry.cn-hangzhou.aliyuncs.com/violet-k8s/apps:v1
fc03e0faa05b95687defd41bb9e6a86c91d9a1ded48ffd125dc5fc7c9d70c0b8
[root@elk92 ~]#
[root@elk92 ~]# docker container inspect -f "{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" c1
172.17.0.2
[root@elk92 ~]#
[root@elk92 ~]# curl 172.17.0.2
欢迎来到天暗星小作坊~
[root@elk92 ~]#
[root@elk92 ~]# ll /data/
total 12
drwxr-xr-x 2 root root 4096 Mar 20 10:11 ./
drwxr-xr-x 23 root root 4096 Mar 20 10:10 ../
-rw-r--r-- 1 root root 41 Mar 20 10:11 index.html
[root@elk92 ~]#
- 5.如果挂载宿主机的某个目录不存在,则会自动创建【尽管该目录没有数据,也会将容器的数据清空】
[root@elk92 ~]# ll /data3
ls: cannot access '/data3': No such file or directory
[root@elk92 ~]#
[root@elk92 ~]# docker run -v /data3:/usr/share/nginx/html -d --name c3 registry.cn-hangzhou.aliyuncs.com/violet-k8s/apps:v1
42d9e15a2fab660dd0742431bd2a09da37b47b393cc5416d2a93afc6e3e9308d
[root@elk92 ~]#
[root@elk92 ~]# ll /data3
total 8
drwxr-xr-x 2 root root 4096 Mar 20 10:13 ./
drwxr-xr-x 25 root root 4096 Mar 20 10:13 ../
[root@elk92 ~]#
[root@elk92 ~]# docker container inspect -f "{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" c3
172.17.0.3
[root@elk92 ~]#
[root@elk92 ~]# curl 172.17.0.3
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.20.1</center>
</body>
</html>
[root@elk92 ~]#
docker底层Linux特性之chroot技术
- 1.什么是chroot
change root,表示改变根目录("/")。
[root@elk92 ~]# ldd /bin/bash
linux-vdso.so.1 (0x00007fff2d3ee000)
libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007f5478a32000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5478809000)
/lib64/ld-linux-x86-64.so.2 (0x00007f5478bd3000)
[root@elk92 ~]#
[root@elk92 ~]#
[root@elk92 ~]# ldd /usr/bin/ls
linux-vdso.so.1 (0x00007fff3d1d6000)
libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007fe181b71000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe181948000)
libpcre2-8.so.0 => /lib/x86_64-linux-gnu/libpcre2-8.so.0 (0x00007fe1818b1000)
/lib64/ld-linux-x86-64.so.2 (0x00007fe181bcf000)
[root@elk92 ~]#
[root@elk92 ~]# tree /linuxhaha/
linuxhaha
├── bin
│ └── bash
├── lib
│ └── x86_64-linux-gnu
│ ├── libc.so.6
│ ├── libpcre2-8.so.0
│ ├── libselinux.so.1
│ └── libtinfo.so.6
├── lib64
│ └── ld-linux-x86-64.so.2
├── usr
│ └── bin
│ └── ls
└── xixi.log
6 directories, 8 files
[root@elk92 ~]#
[root@elk92 ~]# cp -r linuxhaha linuxhehe
[root@elk92 ~]#
[root@elk92 ~]# chroot linuxhaha
bash-5.1# ls -l /
total 20
drwxr-xr-x 2 0 0 4096 Mar 20 02:21 bin
drwxr-xr-x 3 0 0 4096 Mar 20 02:22 lib
drwxr-xr-x 2 0 0 4096 Mar 20 02:22 lib64
drwxr-xr-x 3 0 0 4096 Mar 20 02:24 usr
-rw-r--r-- 1 0 0 18 Mar 20 02:26 xixi.log
bash-5.1# exit
[root@elk92 ~]#
[root@elk92 ~]# chroot linuxhehe
bash-5.1# ls /
bin lib lib64 usr xixi.log
bash-5.1#
bash-5.1# echo 111111111111111111111 > /haha.txt
bash-5.1#
bash-5.1# ls /
bin haha.txt lib lib64 usr xixi.log
bash-5.1# exit
[root@elk92 ~]#
[root@elk92 ~]# chroot oldboyedu-linux96 ls -l /
total 20
drwxr-xr-x 2 0 0 4096 Mar 20 02:21 bin
drwxr-xr-x 3 0 0 4096 Mar 20 02:22 lib
drwxr-xr-x 2 0 0 4096 Mar 20 02:22 lib64
drwxr-xr-x 3 0 0 4096 Mar 20 02:24 usr
-rw-r--r-- 1 0 0 18 Mar 20 02:26 xixi.log
[root@elk92 ~]#
[root@elk92 ~]# chroot oldboyedu-linux97 ls -l /
total 24
drwxr-xr-x 2 0 0 4096 Mar 20 02:28 bin
-rw-r--r-- 1 0 0 22 Mar 20 02:28 haha.txt
drwxr-xr-x 3 0 0 4096 Mar 20 02:28 lib
drwxr-xr-x 2 0 0 4096 Mar 20 02:28 lib64
drwxr-xr-x 3 0 0 4096 Mar 20 02:28 usr
-rw-r--r-- 1 0 0 18 Mar 20 02:28 xixi.log
[root@elk92 ~]#
- 3.验证docker底层用到了chroot技术
3.1 创建容器
[root@elk92 ~]# docker run -d --name c1 registry.cn-hangzhou.aliyuncs.com/violet-k8s/apps:v1
3c7766ed58bf1dad823f4a7c30b0de029ee5fe836e7490c4193ad2f48533208b
[root@elk92 ~]#
[root@elk92 ~]# docker run -d --name c2 registry.cn-hangzhou.aliyuncs.com/violet-k8s/apps:v1
6b21c993e17243080e6b39fe552289a5ef0dd6ea74d0d7af9cf4969501d56afc
[root@elk92 ~]#
[root@elk92 ~]#
[root@elk92 ~]# docker exec c1 touch /xixi.log
[root@elk92 ~]#
[root@elk92 ~]# docker exec c2 touch /haha.log
[root@elk92 ~]#
[root@elk92 ~]# ls /
bin cdrom data2 dev home lib32 libx32 media oldboyedu proc run snap swap.img tmp var
boot data data3 etc lib lib64 lost+found mnt opt root sbin srv sys usr yinzhengjie
[root@elk92 ~]#
3.2 查看容器的MergedDir目录
[root@elk92 ~]# docker inspect -f '{{.GraphDriver.Data.MergedDir}}' c1
/var/lib/docker/overlay2/e06301296149dd7363b456f71941c5f2fe53609b3d5c76ba800eb8de800c6188/merged
[root@elk92 ~]#
[root@elk92 ~]# docker inspect -f '{{.GraphDriver.Data.MergedDir}}' c2
/var/lib/docker/overlay2/ee96862518138d9c297fe86e95da53c9c4b3ba2d7737028371fe90b4413918c5/merged
[root@elk92 ~]#
[root@elk92 ~]# chroot /var/lib/docker/overlay2/e06301296149dd7363b456f71941c5f2fe53609b3d5c76ba800eb8de800c6188/merged ls /
bin etc mnt run tmp
dev home opt sbin usr
docker-entrypoint.d lib proc srv var
docker-entrypoint.sh media root sys xixi.log
[root@elk92 ~]#
[root@elk92 ~]# chroot /var/lib/docker/overlay2/ee96862518138d9c297fe86e95da53c9c4b3ba2d7737028371fe90b4413918c5/merged ls /
bin etc media root sys
dev haha.log mnt run tmp
docker-entrypoint.d home opt sbin usr
docker-entrypoint.sh lib proc srv var
[root@elk92 ~]#
docker底层Linux特性之overlayFS技术
- 1.什么overlayFS
overlayFS是docker用到的Linux的一款联合文件系统。
OverlayFS是一种堆叠文件系统,它依赖并建立在其它的文件系统之上(例如ext4fs和xfs等),并不直接参与磁盘空间结构的划分,仅仅将原来系统文件中的文件或者目录进行"合并一起",最后向用户展示"合并"的文件是在同一级的目录, 这就是联合挂载技术, 相对于AUFS (<1.12 早期使用的存储技术), OverlayFS速度更快,实现更简单。
Linux内核为Docker提供的OverlayFS驱动有两种:Overlay和Overlay2。而Overlay2是相对于Overlay的一种改进,在Inode利用率方面比Overlay更有效。
但是Overlay有环境需求:
(1)Docker版本17.06.02+;
(2)宿主机文件系统需要是EXT4或XFS格式;
OverlayFS实现方式:
OverlayFS通过三个目录:lower目录、upper目录、以及work目录实现。
lower:
一般对应的是只读数据。
upper:
可以进行读写操作的目录。
work:
目录为工作基础目录,挂载后会自动创建一个work子目录(实际测试手动卸载后该目录并不会被删除)
该目录主要是存储一些临时存放的结果或中间数据的工作目录。
值得注意的是,在使用过程中其内容用户不可见,最后联合挂载完成给用户呈现的统一视图称为merged目录。
OverlayFS结构分为三个层: LowerDir、Upperdir、MergedDir
LowerDir (只读)
只读的image layer,其实就是rootfs。
在使用Dockfile构建镜像的时候, Image Layer可以分很多层,所以对应的lowerdir会很多(源镜像)。
Lower 包括两个层:
(1)系统的init
1)容器在启动以后, 默认情况下lower层是不能够修改内容的, 但是用户有需求需要修改主机名与域名地址, 那么就需要添加init层中的文件(hostname, resolv.conf,hosts,mtab等文件), 用于解决此类问题;
2)修改的内容只对当前的容器生效, 而在docker commit提交为镜像时候,并不会将init层提交。
3)init文件存放的目录为/var/lib/docker/overlay2/<init_id>/diff
(2)容器的镜像层
不可修改的数据。
Upperdir (读写)
upperdir则是在lowerdir之上的一层, 为读写层。容器在启动的时候会创建, 所有对容器的修改, 都是在这层。比如容器启动写入的日志文件,或者是应用程序写入的临时文件。
MergedDir (展示)
merged目录是容器的挂载点,在用户视角能够看到的所有文件,都是从这层展示的。
- 2.overlayFS参考案例
2.1 创建工作目录
[root@elk92 ~]# mkdir -pv /linux2025/lower{0..2} /oldboyedu2025/{uppper,work,merged}
mkdir: created directory '/linux2025'
mkdir: created directory '/linux2025/lower0' #---> RO
mkdir: created directory '/linux2025/lower1' #---> RO
mkdir: created directory '/linux2025/lower2' #---> RO
mkdir: created directory '/linux2025/uppper' #---> RW
mkdir: created directory '/linux2025/work' #---> TEMP|CACHE
mkdir: created directory '/linux2025/merged' #---> USER
[root@elk92 ~]#
2.2 挂载文件系统
[root@elk92 ~]# mount -t overlay overlay -o lowerdir=/linux2025/lower0:/linux2025/lower1:/linux2025/lower2,upperdir=/linux2025/uppper,workdir=/linux2025/work /linux2025/merged/
[root@elk92 ~]#
2.3 查看挂载信息
[root@elk92 ~]# df -h | grep linux2025
overlay 97G 15G 78G 16% /oldboyedu2025/merged
[root@elk92 ~]#
2.4 尝试在lower层写入准备初始数据
ll /oldboyedu2025/ -R
cp /etc/hosts /linux2025/lower0/
cp /etc/issue /linux2025/lower1/
cp /etc/resolv.conf /linux2025/lower2/
ll /linux2025/ -R
2.5 尝试在upper层写入准备初始数据
cp /etc/hostname /linux2025/uppper/
ll /linux2025/ -R
2.6 尝试在merged目录写入数据,观察数据实际写入的应该是upper层
cp /etc/fstab /linux2025/merged/
ll /linux2025/ -R
2.7 重新挂载,但不挂载upperdir层
umount /linux2025/merged
mount -t overlay overlay -o lowerdir=/linux2025/lower0:/linux2025/lower1:/linux2025/lower2,workdir=/linux2025/work /linux2025/merged/
2.8 再次尝试写入数据失败,因为没有写层。
[root@elk92 ~]# cp /etc/os-release /linux2025/merged/
cp: cannot create regular file '/linux2025/merged/os-release': Read-only file system
[root@elk92 ~]#
- 3.验证docker底层用到了overlayFS
[root@elk92 ~]# docker inspect -f '{{.GraphDriver.Data.MergedDir}}' c1
/var/lib/docker/overlay2/e06301296149dd7363b456f71941c5f2fe53609b3d5c76ba800eb8de800c6188/merged
[root@elk92 ~]#
[root@elk92 ~]# docker inspect -f '{{.GraphDriver.Data.MergedDir}}' c2
/var/lib/docker/overlay2/ee96862518138d9c297fe86e95da53c9c4b3ba2d7737028371fe90b4413918c5/merged
[root@elk92 ~]#
[root@elk92 ~]# df -h | grep overlay
overlay 97G 15G 78G 16% /var/lib/docker/overlay2/e06301296149dd7363b456f71941c5f2fe53609b3d5c76ba800eb8de800c6188/merged
overlay 97G 15G 78G 16% /var/lib/docker/overlay2/ee96862518138d9c297fe86e95da53c9c4b3ba2d7737028371fe90b4413918c5/merged
overlay 97G 15G 78G 16% /oldboyedu2025/merged
[root@elk92 ~]#
[root@elk92 ~]# docker inspect -f '{{.GraphDriver.Data.UpperDir}}' c1
/var/lib/docker/overlay2/e06301296149dd7363b456f71941c5f2fe53609b3d5c76ba800eb8de800c6188/diff
[root@elk92 ~]#
[root@elk92 ~]# docker inspect -f '{{.GraphDriver.Data.UpperDir}}' c2
/var/lib/docker/overlay2/ee96862518138d9c297fe86e95da53c9c4b3ba2d7737028371fe90b4413918c5/diff
[root@elk92 ~]#
[root@elk92 ~]# ll /var/lib/docker/overlay2/e06301296149dd7363b456f71941c5f2fe53609b3d5c76ba800eb8de800c6188/diff
total 32
drwxr-xr-x 6 root root 4096 Mar 20 10:31 ./
drwx--x--- 5 root root 4096 Mar 20 10:31 ../
drwxr-xr-x 3 root root 4096 Mar 20 10:31 etc/
drwx------ 2 root root 4096 Mar 20 10:35 root/
drwxr-xr-x 2 root root 4096 Mar 20 10:31 run/
drwxr-xr-x 3 root root 4096 Nov 12 2021 var/
-rw-r--r-- 1 root root 0 Mar 20 10:31 xixi.log # 数据的确写入到了UpperDir层
[root@elk92 ~]#
[root@elk92 ~]# ll /var/lib/docker/overlay2/ee96862518138d9c297fe86e95da53c9c4b3ba2d7737028371fe90b4413918c5/diff
total 28
drwxr-xr-x 5 root root 4096 Mar 20 10:31 ./
drwx--x--- 5 root root 4096 Mar 20 10:31 ../
drwxr-xr-x 3 root root 4096 Mar 20 10:31 etc/
-rw-r--r-- 1 root root 0 Mar 20 10:31 haha.log # 数据的确写入到了UpperDir层
drwxr-xr-x 2 root root 4096 Mar 20 10:31 run/
drwxr-xr-x 3 root root 4096 Nov 12 2021 var/
[root@elk92 ~]#
- 4.查看docker的存储驱动就是overlayFS
[root@elk92 ~]# docker info | grep "Storage Driver"
Storage Driver: overlay2
[root@elk92 ~]#