Skip to content

Click on each book below to review & buy on Amazon.

As an Amazon Associate, I earn from qualifying purchases.


RHCSA - Manage Containers: Attach Persistent Storage to a Container

Containers are known for their lightweight and ephemeral nature, which means that by default, any data or changes made inside a container are lost when the container is stopped or removed. However, there are scenarios where we need to retain data even after a container exits, such as in databases or application configurations. This is where persistent storage comes into play. Persistent storage in Docker allows containers to store and access data that survives the container's lifecycle. Docker provides several mechanisms for achieving persistent storage, including volumes and bind mounts.

Volumes

Volumes are a feature that enables the creation of a dedicated storage area outside of the container's file system. Volumes are independent of the container and can be shared among multiple containers. They ensure data persistence even if the associated container is removed.

To create volumes you use the podman volume create <volume name> command and to attach the storage volume to a container persistently you include the -v <volume name>:<mount point within container> option to the podman run command.

When creating volumes as a normal user, the created volumes reside in directory ~/.local/share/containers/storage/volumes. For root created volumes, the location of the volumes will be /var/lib/containers/storage/volumes

When using volumes, the SELinux context of container_file_t is applied automatically to files and directories within the volume.

In the following exercise you will create a storage volume and have a container write to the volume persistently.

Create and mount a storage volume to a container:

Create a volume called vol1:

podman volume create vol1

If the volume was created successfully, vol1 will print to screen.

Run a container with the storage volume vol1 mounted to container directory /mnt/vol1:

podman run -it -v vol1:/mnt/vol1 --name vol1_storage_container ubi9/ubi-minimal

You will be dropped into the container within an interactive shell which you can tell by your command prompt changing to:

[root@<container ID> /]#

Check to see if the storage volume has been mounted within the container:

df -h

The output will resemble the following, which shows the local /dev/mapper/os_vg-root logical volume mounted at /mnt/vol1:

The /dev/mapper/os_vg-root in my case is where the vol1 storage volume is located, this may be different for you.

Filesystem              Size  Used Avail Use% Mounted on
overlay                  15G  7.3G  7.7G  49% /
tmpfs                    64M     0   64M   0% /dev
/dev/mapper/os_vg-root   15G  7.3G  7.7G  49% /mnt/vol1
tmpfs                   768M  848K  767M   1% /etc/hosts
shm                      63M     0   63M   0% /dev/shm
devtmpfs                4.0M     0  4.0M   0% /dev/tty

Perform a test to ensure the storage volume can be written to from within the container:

echo 'test write from container' > /mnt/vol1/container_vol1.txt

Stop the container with Ctrl+D, then run the following to check for the existents and contents of the container_vol1.txt file.

cat ~/.local/share/containers/storage/volumes/vol1/_data/container_vol1.txt

The contents of the file should now be displayed:

test write from container

Bind Mounts

Bind mounts, link a specific file or directory on the host system to a path inside the container. This allows data to be directly accessed and manipulated on the host, providing persistent storage that is easy to manage and can be shared across containers.

When using bind mounts, the SELinux context of container_file_t is NOT applied automatically to files and directories within the host directory.

The following exercise will get you using bind mounts and ensuring the correct host permissions are set:

Create bind mount ~/bind-mounts/data1 and mount to a container:

Create the directory for storing data persistently on the host:

mkdir -pv ~/bind-mounts/data1

The output should resemble:

mkdir: created directory '/home/user/bind-mounts'
mkdir: created directory '/home/user/bind-mounts/data1'

Now create a container with the host directory mounted at /mnt/data1:

podman run -it -v ~/bind-mounts/data1:/mnt/data1 --name bind_mount_container ubi9/ubi-minimal

You will be dropped into the container within an interactive shell which you can tell by your command prompt changing to:

[root@<container ID> /]#

Check to see if the host directory ~/bind-mounts/data1 has been mounted within the container:

df -h

The output will resemble the following, which shows the local /dev/mapper/os_vg-root logical volume mounted at /mnt/data1:

The /dev/mapper/os_vg-root logical volume in my case is where host directory is located, this may be different for you.

Filesystem              Size  Used Avail Use% Mounted on
overlay                  15G  7.3G  7.8G  49% /
tmpfs                    64M     0   64M   0% /dev
tmpfs                   768M  624K  767M   1% /etc/hosts
shm                      63M     0   63M   0% /dev/shm
/dev/mapper/os_vg-root   15G  7.3G  7.8G  49% /mnt/data1
devtmpfs                4.0M     0  4.0M   0% /dev/tty

Perform a test to ensure the host directory can be written to from within the container:

echo 'test write from container' > /mnt/data1/container_data1.txt

You will receive a permission denied message due to SELinux.

bash: /mnt/data1/container_data1.txt: Permission denied

Stop the container with Ctrl+D, then remove it by running:

podman container rm bind_mount_container

Run the container again, but this time include :Z at the end of the volume arguments to ensure SELinux context labels are added:

podman run -it -v ~/bind-mounts/data1:/mnt/data1:Z --name bind_mount_container ubi9/ubi-minimal

Attempting to write to the bind mount from within the container will no longer error:

echo 'test write from container' > /mnt/data1/container_data1.txt

Stop the container with Ctrl+D, then run the following to check for the existents and contents of the container_data1.txt file.

cat ~/bind-mounts/data1/container_data1.txt

The contents of the file should now be displayed:

test write from container

You can see the SELinux context label of container_file_t has been added to the bind mount and created file by running:

ls -ZR ~/bind-mounts
/home/user/bind-mounts/:
system_u:object_r:container_file_t:s0:c760,c941 data1

/home/user/bind-mounts/data1:
system_u:object_r:container_file_t:s0:c760,c941 container_data1.txt

Support DTV Linux

Click on each book below to review & buy on Amazon. As an Amazon Associate, I earn from qualifying purchases.

NordVPN ®: Elevate your online privacy and security. Grab our Special Offer to safeguard your data on public Wi-Fi and secure your devices. I may earn a commission on purchases made through this link.