docker中,可以看到容器的可用空间大小

wenqikai@system-develop:~/workspace$ sudo docker run --rm -it   alpine:latest sh                      
/ # df -h
Filesystem                Size      Used Available Use% Mounted on
overlay                 217.9G     16.1G    190.7G   8% /
tmpfs                    64.0M         0     64.0M   0% /dev
shm                      64.0M         0     64.0M   0% /dev/shm
/dev/sda3               217.9G     16.1G    190.7G   8% /etc/resolv.conf
/dev/sda3               217.9G     16.1G    190.7G   8% /etc/hostname
/dev/sda3               217.9G     16.1G    190.7G   8% /etc/hosts
tmpfs                    62.8G         0     62.8G   0% /proc/acpi
tmpfs                    64.0M         0     64.0M   0% /proc/kcore
tmpfs                    64.0M         0     64.0M   0% /proc/keys
tmpfs                    64.0M         0     64.0M   0% /proc/latency_stats
tmpfs                    64.0M         0     64.0M   0% /proc/timer_list
tmpfs                    62.8G         0     62.8G   0% /proc/scsi
tmpfs                    62.8G         0     62.8G   0% /sys/firmware
tmpfs                    62.8G         0     62.8G   0% /sys/devices/virtual/powercap
/ # t^C

可以看到根目录大小根宿主机的一致,也就是说容器的可用空间取决于宿主机中挂载的目录所在的目标磁盘剩余空间,如果容器将该目录用满,那也就意味着宿主机的根目录也将没有磁盘空间可用,这就威胁到宿主机的使用,那如何解决这个问题呢?

在容器中cat /proc/mount 查看容器的挂载情况

/ # cat /proc/mounts 
overlay / overlay rw,relatime,lowerdir=/var/lib/docker/overlay2/l/IQQYMB7LAOSYP5E76364MFZTJZ:/var/lib/docker/overlay2/l/M55IFLMXWPDHEROCQKFRVLF2RD,upperdir=/var/lib/docker/overlay2/a843f447802c1fe2ae5f69967c8fc2b75905a8774025e90eb0e741dcb9bb24d2/diff,workdir=/var/lib/docker/overlay2/a843f447802c1fe2ae5f69967c8fc2b75905a8774025e90eb0e741dcb9bb24d2/work,uuid=on,nouserxattr 0 0
proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0
tmpfs /dev tmpfs rw,nosuid,size=65536k,mode=755,inode64 0 0
...

可以看到,跟目录是一个overlay文件系统,overlay由三个部分组成,分别是lowerdir、upperdir,workdir,这三个目录对应其实就是宿主机的绝对路径。其中lowerdir为只读的,upperdir为最新的写入文件,work为两者合并之后的文件,作为docker的工作目录

在宿主机中,可以看到这三个目录

# lower有多层,随便拿一个
wenqikai@system-develop:~/fs/diff$ sudo ls -l /var/lib/docker/overlay2/l/IQQYMB7LAOSYP5E76364MFZTJZ
lrwxrwxrwx 1 root root 77  1月 10 23:12 /var/lib/docker/overlay2/l/IQQYMB7LAOSYP5E76364MFZTJZ -> ../a843f447802c1fe2ae5f69967c8fc2b75905a8774025e90eb0e741dcb9bb24d2-init/diff

# upper为diff目录
wenqikai@system-develop:~$ sudo du -d 1 -h /var/lib/docker/overlay2/a843f447802c1fe2ae5f69967c8fc2b75905a8774025e90eb0e741dcb9bb24d2/
12K     /var/lib/docker/overlay2/a843f447802c1fe2ae5f69967c8fc2b75905a8774025e90eb0e741dcb9bb24d2/diff
8.0K    /var/lib/docker/overlay2/a843f447802c1fe2ae5f69967c8fc2b75905a8774025e90eb0e741dcb9bb24d2/work
32K     /var/lib/docker/overlay2/a843f447802c1fe2ae5f69967c8fc2b75905a8774025e90eb0e741dcb9bb24d2/

也就是容器的根目录文件系统实际上是多个目录拼接而成的,层层叠加,差异化的内容存放在diff目录中

那是否可以限制diff目录的大小从而达到限制容器的使用量呢?

# 创建一个img镜像
sudo dd if=/dev/zero of=fs.img bs=1M count=4096
sudo mkfs.ext4 fs.img

# 停止容器
sudo docker stop xxxxx

# 拷贝容器中的diff目录到img中
sudo mkdir fs/
sudo mount fs.img fs/ 
sudo cp /var/lib/docker/overlay2/a843f447802c1fe2ae5f69967c8fc2b75905a8774025e90eb0e741dcb9bb24d2/diff/. fs/ -r

# 将img挂载到diff目录
sudo mount fs.img /var/lib/docker/overlay2/a843f447802c1fe2ae5f69967c8fc2b75905a8774025e90eb0e741dcb9bb24d2/diff

# 重启容器
wenqikai@system-develop:~$ sudo docker restart 8b0e35952d5a
Error response from daemon: Cannot restart container 8b0e35952d5a: error creating overlay mount to /var/lib/docker/overlay2/a843f447802c1fe2ae5f69967c8fc2b75905a8774025e90eb0e741dcb9bb24d2/merged: invalid argument

在重启容器时,发现重启失败,查看dmesg

wenqikai@system-develop:~$ sudo dmesg -T | tail 
[五 1月 10 23:28:24 2025] docker0: port 3(vethbd1c208) entered disabled state
[五 1月 10 23:28:24 2025] veth05d32ae: renamed from eth0
[五 1月 10 23:28:24 2025] docker0: port 3(vethbd1c208) entered disabled state
[五 1月 10 23:28:24 2025] vethbd1c208 (unregistering): left allmulticast mode
[五 1月 10 23:28:24 2025] vethbd1c208 (unregistering): left promiscuous mode
[五 1月 10 23:28:24 2025] docker0: port 3(vethbd1c208) entered disabled state
[五 1月 10 23:28:38 2025] overlayfs: workdir and upperdir must reside under the same mount
[五 1月 10 23:28:38 2025] overlayfs: workdir and upperdir must reside under the same mount
[五 1月 10 23:31:02 2025] overlayfs: workdir and upperdir must reside under the same mount
[五 1月 10 23:31:02 2025] overlayfs: workdir and upperdir must reside under the same mount

dmesg的信息告诉我们,overlayfs的工作目录和upperdir必须mount在同一个设备上,也就是说,当我们只挂载diff目录时,diff目录在img中,而merge目录还在原来的设备,系统不允许我们这么做,那是否可以将挂载整个a843f447802c1fe2ae5f69967c8fc2b75905a8774025e90eb0e741dcb9bb24d2目录呢?