Introduction to Overlay Filesystem
An Overlay Filesystem is a type of filesystem that combines two or more underlying filesystems into a single, unified view. It allows multiple layers of files and directories to be stacked on top of each other, with the top layer being writable and the lower layers being read-only.
How to setup an Overlay Filesystem?
To set up an Overlay Filesystem, you need two directories: a lower
directory and an upper
directory. The lower
directory contains the base filesystem, while the upper
directory contains the modifications.
Let's create the directories and files:
mkdir -p ~/data
cd ~/data
# Create the lower directory
mkdir lower
# Create the upper directory
mkdir upper
# Create the overlay mount point
mkdir merged
# Create a work directory (for internal purposes)
mkdir work
# Create some files in the lower directory
echo "Foo" > lower/foo
echo "Bar" > lower/bar
echo "Bet" > lower/bet
Now, let's mount the Overlay Filesystem:
sudo mount -t overlay overlay -o lowerdir=lower,upperdir=upper,workdir=work merged
Verify that the merged
directory shows the files of the lower
directory:
ls merged
How various filesystem operations are handled
Let's explore how various filesystem operations are handled in the Overlay Filesystem.
Modifying a file in the merged view
# Before merged/foo shows the original contents of foo
cat merged/foo
# Modify merged/foo
echo "Changed foo" > merged/foo
# Verify the changes in merged/foo and confirm that it shows the modified contents of foo
cat merged/foo
# The change is only reflected in the upper directory
ls upper
cat upper/foo
# The lower directory's foo has not changed
cat lower/foo
Adding a new file in the merged view
# The file baz is not present initially in merged
ls merged
# Let us create it
echo "Baz" > merged/baz
# Verify that the file was created
ls merged
# The new file is created in the upper directory
ls upper
cat upper/baz
Removing a file in the merged view
# Let us now remove the file bet. The file is present in merged to begin with.
ls merged` shows `bet`.
# Remove the file
rm merged/bet
# merged does not show bet anymore
ls merged
The file is not deleted from the lower
directory but is hidden in the merged
view. The Overlay Filesystem creates a file called bet
in the upper
directory and "marks it as deleted".
ls lower
ls upper
ls -l upper/bet
Removing a file added in the merged view
# If we remove a file that is only present in the upper directory, it will actually be deleted from upper. There is a file baz in merged.
ls merged
# Remove the file baz from merged
rm merged/baz
# The file is no longer present in merged
ls merged
# The file is deleted from the `upper` directory.
ls upper
One thing we notice is that for all 3 types of changes: addition of a new file, updating an existing file or deletion of a file, the changes are always maintained in the upper
directory. The lower
directory is never written into by the Overlay Filesystem.
Removing the Overlay Filesystem
sudo umount merged
sudo rm -rf lower upper work merged
Multiple Lower Directories
We can provide multiple lower directories. Let us say we want a new filesystem with the changes that we have done in our old Overlay. We first copy the changes that have been made in the upper
directory, into a separate directory. We have called it lower2
. We can now create an Overlay filesystem with lower2:lower
as the lower directory. This informs the Overlay driver to consider lower2
to be the diff from lower
.
mkdir lower2
cp -a upper/. lower2/
mkdir upper2 work2 merged2
sudo mount -t overlay overlay -o lowerdir=lower2:lower,upperdir=upper2,workdir=work2 merged2
The merged2
directory shows all the changes that we did in our old Overlay.
ls merged2
cat merged2/foo
cat merged2/bar
If we make changes to this filesystem, the changes will be written to upper2
.
touch merged2/boo
ls upper2
How Overlay Filesystem is related to Docker
Docker uses Overlay Filesystems to manage the container's filesystem. When a container is created, Docker creates an Overlay Filesystem, where the lower
directory is the image, and the upper
directory is the container's writable layer. This allows multiple containers to share the same base image while keeping their modifications separate.
The upper
directory is empty to begin with. So when containers are created, there is a minimal overhead. Docker does not need to make an entire copy of the image for each container. Any changes made to the container are then written to the upper
directory, leaving the base image unchanged. This enables efficient storage and deployment of containers.
When we make changes to a container's filesystem and docker commit
it, the changes which are maintained in the container's upper
directory are copied into a new location. When we use this committed image to create another container, this new container will have the original image and the changes made in container1 as the lower directory.