# Overlay FileSystem (overlayFS) ###### tag: `overlayfs` Test and understand overlay filesystem. #### create loopback block device create images and setup loopback ``` root@NUC10:~# dd if=/dev/zero of=/mnt/lower.img bs=1M count=1024 1024+0 records in 1024+0 records out 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 0.473045 s, 2.3 GB/s root@NUC10:~# dd if=/dev/zero of=/mnt/overlay.img bs=1M count=1024 1024+0 records in 1024+0 records out 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 0.472078 s, 2.3 GB/s root@NUC10:~# losetup -fP /mnt/lower.img root@NUC10:~# losetup -fP /mnt/overlay.img root@NUC10:~# losetup -a | grep "/mnt/" /dev/loop26: [66305]:52166664 (/mnt/overlay.img) /dev/loop20: [66305]:52166663 (/mnt/lower.img) ``` format image files ``` root@NUC10:~# mkfs.ext4 /mnt/lower.img mke2fs 1.46.5 (30-Dec-2021) Discarding device blocks: done Creating filesystem with 262144 4k blocks and 65536 inodes Filesystem UUID: b467fd35-0ac6-4f1a-9c6e-d622fe6b90f1 Superblock backups stored on blocks: 32768, 98304, 163840, 229376 Allocating group tables: done Writing inode tables: done Creating journal (8192 blocks): done Writing superblocks and filesystem accounting information: done root@NUC10:~# mkfs.ext4 /mnt/overlay.img mke2fs 1.46.5 (30-Dec-2021) Discarding device blocks: done Creating filesystem with 262144 4k blocks and 65536 inodes Filesystem UUID: dceb523e-57a3-4051-9a49-d3e38f16dfbc Superblock backups stored on blocks: 32768, 98304, 163840, 229376 Allocating group tables: done Writing inode tables: done Creating journal (8192 blocks): done Writing superblocks and filesystem accounting information: done ``` #### create directories ``` root@NUC10:/mnt# mkdir test-overlay root@NUC10:/mnt# cd test-overlay/ root@NUC10:/mnt/test-overlay# mkdir lower overlay merged root@NUC10:/mnt/test-overlay# ls -l total 12 drwxr-xr-x 3 root root 4096 Nov 15 00:29 lower drwxr-xr-x 2 root root 4096 Nov 15 00:48 merged drwxr-xr-x 5 root root 4096 Nov 15 00:45 overlay ``` #### mount lower loopback device and create some files inside. ``` root@NUC10:~# mount -o rw /dev/loop20 /mnt/test-overlay/lower/ root@NUC10:~# echo "lower data1 line" > /mnt/test-overlay/lower/data1 root@NUC10:~# echo "lower data2 line" > /mnt/test-overlay/lower/data2 root@NUC10:~# ls -l /mnt/test-overlay/lower total 24 -rw-r--r-- 1 root root 17 Nov 15 00:28 data1 -rw-r--r-- 1 root root 17 Nov 15 00:29 data2 drwx------ 2 root root 16384 Nov 15 00:22 lost+found ``` ``` root@NUC10:~# sync root@NUC10:~# umount /dev/loop20 ``` #### overlayFS usage mount lower layer ``` root@NUC10:~# cd /mnt/test-overlay/ root@NUC10:/mnt/test-overlay# mount -o ro /dev/loop20 ./lower/ root@NUC10:/mnt/test-overlay# ls -l ./lower/ total 24 -rw-r--r-- 1 root root 17 Nov 15 00:28 data1 -rw-r--r-- 1 root root 17 Nov 15 00:29 data2 drwx------ 2 root root 16384 Nov 15 00:22 lost+found ``` mount overlay layer and create "upper" and "work" directories ``` root@NUC10:/mnt/test-overlay# mount /dev/loop26 ./overlay/ root@NUC10:/mnt/test-overlay# mkdir ./overlay/{upper,work} root@NUC10:/mnt/test-overlay# ls -l ./overlay/ total 24 drwx------ 2 root root 16384 Nov 15 00:23 lost+found drwxr-xr-x 2 root root 4096 Nov 15 00:45 upper drwxr-xr-x 2 root root 4096 Nov 15 00:45 work ``` create overlayFS on /mnt/test-overlay/merged ``` root@NUC10:/mnt/test-overlay# mount overlay -t overlay -o lowerdir=/mnt/test-overlay/lower,upperdir=/mnt/test-overlay/overlay/upper/,workdir=/mnt/test-overlay/overlay/work/ /mnt/test-overlay/merged ``` > -t specify type of filesystem to mount > -o set mount options, in this case, "lowerdir", "workdir" and "upperdir" A overlay filesytem is mounted on "/mnt/test-overlay/merged" ``` root@NUC10:/mnt/test-overlay# df -h | grep overlay /dev/loop20 974M 32K 907M 1% /mnt/test-overlay/lower /dev/loop26 974M 36K 907M 1% /mnt/test-overlay/overlay overlay 974M 36K 907M 1% /mnt/test-overlay/merged root@NUC10:/mnt/test-overlay# mount | grep -i overlay /dev/loop20 on /mnt/test-overlay/lower type ext4 (ro,relatime) /dev/loop26 on /mnt/test-overlay/overlay type ext4 (rw,relatime) overlay on /mnt/test-overlay/merged type overlay (rw,relatime,lowerdir=/mnt/test-overlay/lower,upperdir=/mnt/test-overlay/overlay/upper/,workdir=/mnt/test-overlay/overlay/work/) root@NUC10:/mnt/test-overlay# ls -l ./merged/ total 24 -rw-r--r-- 1 root root 17 Nov 15 00:28 data1 -rw-r--r-- 1 root root 17 Nov 15 00:29 data2 drwx------ 2 root root 16384 Nov 15 00:22 lost+found ``` Add extra line to data1 file in the merged directory. ``` root@NUC10:/mnt/test-overlay# echo "overlay data1 line" >> ./merged/data1 root@NUC10:/mnt/test-overlay# cat ./merged/data1 lower data1 line overlay data1 line ``` In the lower directory, data1 has no change ``` root@NUC10:/mnt/test-overlay# cat ./lower/data1 lower data1 line ``` In the upper directory, a same file is present which is same with one in merged directory. ``` root@NUC10:/mnt/test-overlay# ls -l ./overlay/upper/ total 4 -rw-r--r-- 1 root root 36 Nov 15 00:53 data1 root@NUC10:/mnt/test-overlay# cat ./overlay/upper/data1 lower data1 line overlay data1 line ``` Delete data2 file in merged directory ``` root@NUC10:/mnt/test-overlay# rm ./merged/data2 root@NUC10:/mnt/test-overlay# ls -l ./merged/ total 20 -rw-r--r-- 1 root root 36 Nov 15 00:53 data1 drwx------ 2 root root 16384 Nov 15 00:22 lost+found ``` In upper directory, same filename is created with file mode "character" device. This ``` root@NUC10:/mnt/test-overlay# ls -l ./overlay/upper/ total 4 -rw-r--r-- 1 root root 36 Nov 15 00:53 data1 c--------- 2 root root 0, 0 Nov 15 00:55 data2 ``` > A whiteout is created as a character device with 0/0 device number. When a whiteout is found in the upper level of a merged directory, any matching name in the lower level is ignored, and the whiteout itself is also hidden. #### Verify with a docker container overlay filesystem ``` root@m900:~# docker inspect gitlab | grep overlay "Driver": "overlay2", "LowerDir": "/var/lib/docker/overlay2/74f18d3b7d672328d102d1e6f1cbfceb4cebbda38732e068c3514b4041a96552-init/diff:/var/lib/docker/overlay2/3c955f9235c05722aa60de2aa7e93817540ead7ed273b5d936f9d9d18a3ae4c1/diff:/var/lib/docker/overlay2/2eb1fa2b58ddf6ea5b7f059c7acef741144504200f9fed1289dc71ad98d26055/diff:/var/lib/docker/overlay2/8266245b479f72ed4596f9f1b9c65cb3e20dab74ebe3c80474447fe3d53c8e83/diff:/var/lib/docker/overlay2/ed7dd462df2cdf4163e202a959b5629e6cdd105ad78018b532ae16bc0f589728/diff:/var/lib/docker/overlay2/336930137b4564c7cdc73f67ad53817481ee3f3bc32aacc2273bd807984df436/diff:/var/lib/docker/overlay2/bf34ce7cadb43f6e2572e6a081f868ae682b8e9b80b05892bf36c6c0d09604dc/diff:/var/lib/docker/overlay2/5e6ff6719b97ef488787171809ec6999c24d47b5022fbffe47a9435f24a39c17/diff:/var/lib/docker/overlay2/c8e4af5dad4021a3d17b38dc0dee4dbff43ab8ece5036fd8e07181b21d4a2217/diff", "MergedDir": "/var/lib/docker/overlay2/74f18d3b7d672328d102d1e6f1cbfceb4cebbda38732e068c3514b4041a96552/merged", "UpperDir": "/var/lib/docker/overlay2/74f18d3b7d672328d102d1e6f1cbfceb4cebbda38732e068c3514b4041a96552/diff", "WorkDir": "/var/lib/docker/overlay2/74f18d3b7d672328d102d1e6f1cbfceb4cebbda38732e068c3514b4041a96552/work" "Name": "overlay2" ``` ``` root@m900:~# df -h | grep /var/lib/docker/overlay2/74f18d3b7d672328d102d1e6f1cbfceb4cebbda38732e068c3514b4041a96552/merged overlay 916G 35G 835G 5% /var/lib/docker/overlay2/74f18d3b7d672328d102d1e6f1cbfceb4cebbda38732e068c3514b4041a96552/merged ``` ``` root@m900:~# mount | grep /var/lib/docker/overlay2/74f18d3b7d672328d102d1e6f1cbfceb4cebbda38732e068c3514b4041a96552/merged overlay on /var/lib/docker/overlay2/74f18d3b7d672328d102d1e6f1cbfceb4cebbda38732e068c3514b4041a96552/merged type overlay (rw,relatime,lowerdir=/var/lib/docker/overlay2/l/KMTT27XT4SJWTURLJ53IAI73QZ:/var/lib/docker/overlay2/l/N25TEKVF3L5MMWTVEVMYIC2HBJ:/var/lib/docker/overlay2/l/2QTL77FSXAKS42FKED4HQAHNWQ:/var/lib/docker/overlay2/l/Q462WZSPHS4ZO6PEO7COEDOSHQ:/var/lib/docker/overlay2/l/RNP4ERXAPLMHLSHM6M6NRGCDSC:/var/lib/docker/overlay2/l/V25GWMW6HVAYD2WRKBGGOAY7VC:/var/lib/docker/overlay2/l/3DGWPPXXQYPYLFNJ2VGOG6EBHE:/var/lib/docker/overlay2/l/EH2CU2CCQFVKLCBLFSYSP2UGXW:/var/lib/docker/overlay2/l/PGDBRHCU2KLMSXOKVSO4FBYQF2,upperdir=/var/lib/docker/overlay2/74f18d3b7d672328d102d1e6f1cbfceb4cebbda38732e068c3514b4041a96552/diff,workdir=/var/lib/docker/overlay2/74f18d3b7d672328d102d1e6f1cbfceb4cebbda38732e068c3514b4041a96552/work) ``` > Multiple lower layers can now be given using the colon (":") as a separator character between the directory names. For example: > mount -t overlay overlay -olowerdir=/lower1:/lower2:/lower3 /merged #### reference https://docs.kernel.org/filesystems/overlayfs.html https://linuxconfig.org/introduction-to-the-overlayfs https://linuxhandbook.com/create-virtual-block-device/ https://stackoverflow.com/questions/31044982/how-to-use-multiple-lower-layers-in-overlayfs