浅谈容器(五)—— Docker 容器存储

Docker 容器存储

Docker 容器文件系统

联合文件系统是一种把多个目录(不同层的文件系统)联合挂载成一个目录来使用的技术。

对使用者来说,好像只有一个文件系统,实际上,背后可能有很多层。

Docker 镜像和容器就依赖这种机制。

Docker 默认使用 overlay2 版本的联合文件系统:

[root@remote-host ~]# docker info -f json | jq .Driver
"overlay2"

查看 overlay2 联合文件系统挂载:

[root@remote-host ~]# mount | grep overlay
overlay on /var/lib/docker/overlay2/600c849ce398f4c0bfdd894c21400c25aa9f18c0682e46ded23594d07cd0ae43/merged type overlay (rw,relatime,lowerdir=/var/lib/docker/overlay2/l/ROCQDGOGAQVFZVRHDRENQJZDLH:/var/lib/docker/overlay2/l/TRZ4RD3VYWEPDRTC2JCSE6FKPM:/var/lib/docker/overlay2/l/NMVX6ZGAZZQBPHXRGXEBN6HVL7:/var/lib/docker/overlay2/l/ORNLAV6RV3O4KISZHEJNETEUOT:/var/lib/docker/overlay2/l/6ELSV2ZTA5AHGJN2R7I34PZRZT:/var/lib/docker/overlay2/l/GWUXXNTGSISMOCLYRSPSUF2KJH:/var/lib/docker/overlay2/l/SUKDJBIVPXG2ESK32VOJYEXAP4:/var/lib/docker/overlay2/l/3ZTCGC6FBKFQFRNW4U55DTDXT7,upperdir=/var/lib/docker/overlay2/600c849ce398f4c0bfdd894c21400c25aa9f18c0682e46ded23594d07cd0ae43/diff,workdir=/var/lib/docker/overlay2/600c849ce398f4c0bfdd894c21400c25aa9f18c0682e46ded23594d07cd0ae43/work)

各字段含义

字段 含义
overlay 使用的是 Linux 的 overlay 文件系统
on /var/lib/docker/overlay2/.../merged 这是最终的挂载点,也就是容器内部看到的根目录 /
lowerdir 只读层(多个镜像层),按冒号分隔顺序叠加,最底层镜像在最后
upperdir 可写层,即该容器启动之后写入的所有更改(copy-on-write)都在这里
workdir overlay2 的工作目录(系统操作时使用)
rw,relatime 挂载参数,表示读写挂载 + 相对时间更新(节省 I/O)

以下是 overlay2 联合文件系统的简化图:

容器看到的是 merged(合并)目录:
                    ↓
+------------------------------------+
|        /merged = 用户视图           |
|------------------------------------|
|  upperdir = 容器的写入层             |
|------------------------------------|
|  lowerdir = 镜像的多个只读层          |
+------------------------------------+

所以 Docker 容器的存储就是一些只读层加顶层的可写层组合到一块的,下边展示一下这个文件系统:

# 创建一个容器
[root@remote-host ~]# docker run --rm -itd --name nginx -v /data:/data nginx:latest
e7d5ab25d7249a718db1d7f4776dd11306e1897679e653a78a986ef1873192cc

# 检查容器存储信息
[root@remote-host ~]# docker inspect nginx -f json | jq .[0].GraphDriver
{
  "Data": {
    "ID": "e7d5ab25d7249a718db1d7f4776dd11306e1897679e653a78a986ef1873192cc",
    "LowerDir": "/var/lib/docker/overlay2/65e25eb592560c44234f2a7412e53292c9125eec207bfaef3051fec9c3f971a9-init/diff:/var/lib/docker/overlay2/ca46c57b83d9ba56d86baba9ef751e7eeda120d5d12ae99a01bf409b2762e475/diff:/var/lib/docker/overlay2/c869e1af9132a71a52dba999dd403f913b98977f3d69821b17d49da2e5485e49/diff:/var/lib/docker/overlay2/c1994238aee78b95e17f4b934f98d71474d30ca5dee6ba2822d2f1fd3b601e3f/diff:/var/lib/docker/overlay2/7361e60e95891cc7f6deb9276ab17c85fb1bcb0dceb3ea78f26414d982541d3f/diff:/var/lib/docker/overlay2/8ac950d7be44412b43c3a7d3b8ff49215f2b148805ec86c962726119c6d16efa/diff:/var/lib/docker/overlay2/e34c03364361edfdf542c32578b5ed053aeb85db5d3d4b1456ae62c53f0f1f17/diff:/var/lib/docker/overlay2/12d65b3c0db6cfe2c0fc80ae5795ac5fe1bc802433d7e7c0328124533e62a29a/diff",
    "MergedDir": "/var/lib/docker/overlay2/65e25eb592560c44234f2a7412e53292c9125eec207bfaef3051fec9c3f971a9/merged",
    "UpperDir": "/var/lib/docker/overlay2/65e25eb592560c44234f2a7412e53292c9125eec207bfaef3051fec9c3f971a9/diff",
    "WorkDir": "/var/lib/docker/overlay2/65e25eb592560c44234f2a7412e53292c9125eec207bfaef3051fec9c3f971a9/work"
  },
  "Name": "overlay2"
}
[root@remote-host ~]# docker inspect nginx -f json | jq .[0].Mounts
[
  {
    "Type": "bind",
    "Source": "/data",
    "Destination": "/data",
    "Mode": "",
    "RW": true,
    "Propagation": "rprivate"
  }
]

# 检查容器文件系统目录树
[root@remote-host ~]# tree /var/lib/docker/overlay2/65e25eb592560c44234f2a7412e53292c9125eec207bfaef3051fec9c3f971a9-init/
/var/lib/docker/overlay2/65e25eb592560c44234f2a7412e53292c9125eec207bfaef3051fec9c3f971a9-init/
├── committed
├── diff
│   ├── dev
│   │   ├── console
│   │   ├── pts
│   │   └── shm
│   └── etc
│       ├── hostname
│       ├── hosts
│       ├── mtab -> /proc/mounts
│       └── resolv.conf
├── link
├── lower
└── work
    └── work
        └── #13f0

7 directories, 9 files
[root@remote-host ~]# tree -L 2 /var/lib/docker/overlay2/65e25eb592560c44234f2a7412e53292c9125eec207bfaef3051fec9c3f971a9/
/var/lib/docker/overlay2/65e25eb592560c44234f2a7412e53292c9125eec207bfaef3051fec9c3f971a9/
├── diff
│   ├── data
│   ├── etc
│   ├── run
│   └── var
├── link
├── lower
├── merged
│   ├── bin -> usr/bin
│   ├── boot
│   ├── data
│   ├── dev
│   ├── docker-entrypoint.d
│   ├── docker-entrypoint.sh
│   ├── etc
│   ├── home
│   ├── lib -> usr/lib
│   ├── lib64 -> usr/lib64
│   ├── media
│   ├── mnt
│   ├── opt
│   ├── proc
│   ├── root
│   ├── run
│   ├── sbin -> usr/sbin
│   ├── srv
│   ├── sys
│   ├── tmp
│   ├── usr
│   └── var
└── work
    └── work

29 directories, 3 files

# 进入容器添加和删除数据
[root@remote-host ~]# docker exec -it nginx bash
root@e7d5ab25d724:/# touch /tmp/testfile
root@e7d5ab25d724:/# rm -rf /mnt/
root@e7d5ab25d724:/# mkdir  /tmp/testdir
root@e7d5ab25d724:/# rm -rf /etc/issue
root@e7d5ab25d724:/# exit
exit

# 再次检查目录树
[root@remote-host ~]# tree /var/lib/docker/overlay2/65e25eb592560c44234f2a7412e53292c9125eec207bfaef3051fec9c3f971a9-init/
/var/lib/docker/overlay2/65e25eb592560c44234f2a7412e53292c9125eec207bfaef3051fec9c3f971a9-init/
├── committed
├── diff
│   ├── dev
│   │   ├── console
│   │   ├── pts
│   │   └── shm
│   └── etc
│       ├── hostname
│       ├── hosts
│       ├── mtab -> /proc/mounts
│       └── resolv.conf
├── link
├── lower
└── work
    └── work
        └── #13f0

7 directories, 9 files
[root@remote-host ~]# tree -L 2 /var/lib/docker/overlay2/65e25eb592560c44234f2a7412e53292c9125eec207bfaef3051fec9c3f971a9/
/var/lib/docker/overlay2/65e25eb592560c44234f2a7412e53292c9125eec207bfaef3051fec9c3f971a9/
├── diff
│   ├── data
│   ├── etc
│   ├── mnt
│   ├── root
│   ├── run
│   ├── tmp
│   └── var
├── link
├── lower
├── merged
│   ├── bin -> usr/bin
│   ├── boot
│   ├── data
│   ├── dev
│   ├── docker-entrypoint.d
│   ├── docker-entrypoint.sh
│   ├── etc
│   ├── home
│   ├── lib -> usr/lib
│   ├── lib64 -> usr/lib64
│   ├── media
│   ├── opt
│   ├── proc
│   ├── root
│   ├── run
│   ├── sbin -> usr/sbin
│   ├── srv
│   ├── sys
│   ├── tmp
│   ├── usr
│   └── var
└── work
    └── work

30 directories, 4 files

# 检查几个目录
[root@remote-host ~]# ls -l /var/lib/docker/overlay2/65e25eb592560c44234f2a7412e53292c9125eec207bfaef3051fec9c3f971a9/diff/
total 0
drwxr-xr-x 2 root root    6 Aug  3 22:28 data
drwxr-xr-x 3 root root   32 Aug  3 22:34 etc
c--------- 3 root root 0, 0 Aug  3 22:34 mnt
drwx------ 2 root root   27 Aug  3 22:34 root
drwxr-xr-x 2 root root   23 Aug  3 22:28 run
drwxrwxrwt 3 root root   37 Aug  3 22:34 tmp
drwxr-xr-x 3 root root   19 Jul 21 08:00 var
[root@remote-host ~]# ls -l /var/lib/docker/overlay2/65e25eb592560c44234f2a7412e53292c9125eec207bfaef3051fec9c3f971a9/diff/tmp/
total 0
drwxr-xr-x 2 root root 6 Aug  3 22:34 testdir
-rw-r--r-- 1 root root 0 Aug  3 22:33 testfile
[root@remote-host ~]# ls -l /var/lib/docker/overlay2/65e25eb592560c44234f2a7412e53292c9125eec207bfaef3051fec9c3f971a9/diff/etc/
total 0
c--------- 3 root root 0, 0 Aug  3 22:34 issue
drwxr-xr-x 3 root root   20 Jul 22 09:13 nginx
[root@remote-host ~]# ls -l /var/lib/docker/overlay2/65e25eb592560c44234f2a7412e53292c9125eec207bfaef3051fec9c3f971a9/merged/tmp/
total 0
drwxr-xr-x 2 root root 6 Aug  3 22:34 testdir
-rw-r--r-- 1 root root 0 Aug  3 22:33 testfile
[root@remote-host ~]# ls -l /var/lib/docker/overlay2/65e25eb592560c44234f2a7412e53292c9125eec207bfaef3051fec9c3f971a9/merged/etc/issue
ls: cannot access '/var/lib/docker/overlay2/65e25eb592560c44234f2a7412e53292c9125eec207bfaef3051fec9c3f971a9/merged/etc/issue': No such file or directory
[root@remote-host ~]# ls -l /var/lib/docker/overlay2/65e25eb592560c44234f2a7412e53292c9125eec207bfaef3051fec9c3f971a9/merged/mnt
ls: cannot access '/var/lib/docker/overlay2/65e25eb592560c44234f2a7412e53292c9125eec207bfaef3051fec9c3f971a9/merged/mnt': No such file or directory

[root@remote-host ~]# cat /var/lib/docker/overlay2/65e25eb592560c44234f2a7412e53292c9125eec207bfaef3051fec9c3f971a9/lower
l/WYB2EPGYJ7BFVUV7WQWUAY6UIL:l/TRZ4RD3VYWEPDRTC2JCSE6FKPM:l/NMVX6ZGAZZQBPHXRGXEBN6HVL7:l/ORNLAV6RV3O4KISZHEJNETEUOT:l/6ELSV2ZTA5AHGJN2R7I34PZRZT:l/GWUXXNTGSISMOCLYRSPSUF2KJH:l/SUKDJBIVPXG2ESK32VOJYEXAP4:l/3ZTCGC6FBKFQFRNW4U55DTDXT7

可以看到 diff 目录下会显示文件差异,lower 文件下记录只读目录的架构,merged 目录是容器做过修改后的实际目录,也就是 lowerdiff 合并的结果。

为容器设置卷挂载

Docker 创建容器的时候可以通过 -v 将本地目录挂载到容器里,这样可以实现数据持久化挂载:

[root@remote-host ~]# docker run -itd --rm --name busybox -v /data:/data busybox:latest
aea1d937b943f27567fd1dd901f661f134a058aa00191243700a7f295edce74f

[root@remote-host ~]# docker inspect busybox -f json | jq .[0].Mounts
[
  {
    "Type": "bind",
    "Source": "/data",
    "Destination": "/data",
    "Mode": "",
    "RW": true,
    "Propagation": "rprivate"
  }
]
浅谈容器(五)—— Docker 容器存储
https://www.linuxstudynotes.com/2026/05/11/containerd/%e6%b5%85%e8%b0%88%e5%ae%b9%e5%99%a8/%e6%b5%85%e8%b0%88%e5%ae%b9%e5%99%a8%ef%bc%88%e4%ba%94%ef%bc%89-docker-%e5%ae%b9%e5%99%a8%e5%ad%98%e5%82%a8/
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇