Overlay Filesystem

by Gautham Pai

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.

Layers upon layers of paint

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

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.

Test Your Knowledge

No quiz available

Tags