Volumes and Mounts
This lab runs on a real VM
This box is not a Pod but a virtual machine launched by KubeVirt. A separate Linux kernel runs in it, systemd actually manages services, and docker is a real Docker engine, not an imitation. A container started with docker run becomes a real process, and both docker exec and docker logs work as usual.
This lab used to run inside a Pod. That box had dropped every kernel capability, so the step that starts a container was blocked, and you learned by working around it and unpacking image archives by hand. The workaround is no longer needed.
There are two things to know.
- The first start takes a little over a minute. The VM boots and installs Docker, so it is slower than a Pod lab (usually 40 seconds).
- There is no browser preview. Only one grading port is open for connections into the VM. If you start a web server, check it with
curlfrom inside the VM.
Goal
You create a volume, a bind mount and a read-only mount yourself, and confirm that data remains even after you delete the container and that backup and restore can make a round trip.
Why it matters
The saying "containers are stateless" does not mean that containers cannot handle state; it means keep the state outside the container. If you cannot tell this apart, either the data disappears on every redeployment, or conversely volumes pile up like a snowball and nobody can delete them. One more thing. A read-only mount is not about performance but a declaration of intent. If you write in the manifest what this container must not write, then the moment code that violates that rule is deployed, it does not pass silently but shows up as an error.
Steps
- Create
/root/ops1and create a named volume calleddk-data. - With a container named
dk-writer, mountdk-dataat/dataand, in/data/hello.txt, writevolume-alive. - Delete the
dk-writercontainer, then read the same volume with a new container to check whether the content remains, and save that output to/root/ops1/persist.txt. - Create
/root/ops1/site/index.htmlwithlabhub-sitein it, and startnginx:1.27-alpinewith the namedk-site, bind-mounting/root/ops1/siteat/usr/share/nginx/html. - Start a
dk-rocontainer, mountdk-dataat/dataas read-only, try writing a file inside it, and save the resulting error message to/root/ops1/ro-error.txt. - Start a
dk-site2container with the--mountsyntax, attaching the same source and target as in step 4, but make it read-only. - Back up the contents of the
dk-datavolume to/root/ops1/dk-data.tgz. The archive must containhello.txt. - Create a new volume called
dk-data-restoreand restore the backup into it. The content must be the same as the original.
Notes
- If you start a temporary working container with
docker run --rm, there is no cleanup to do afterward. - The backup takes the form
docker run --rm -v dk-data:/source:ro -v /root/ops1:/backup alpine:3.20 tar czf /backup/dk-data.tgz -C /source .. - Common mistake 1: if the container ends immediately in step 5, there is nothing left to grade. Keep it running in the background.
- Common mistake 2: in step 7, if you store absolute paths without
-C, the paths get misaligned on restore.
Create a named volume
Create /root/ops1 and create a named volume called dk-data.
There is a separate group of subcommands for handling volumes. You only need to create it, and you do not need a container yet.
Write a file to the volume
With a container named dk-writer, mount dk-data at /data and, in /data/hello.txt, write volume-alive.
Start a container, mount the volume and write the file. Give it a name — you will delete that name in the next step.
Does it remain after the container is deleted
Delete the dk-writer container, then read the same volume with a new container to check whether the content remains, and save that output to /root/ops1/persist.txt.
After deleting the container that wrote the file, read the same volume with a new container. Keep what you confirmed in a file as well.
Attach a host directory as is
Create /root/ops1/site/index.html with labhub-site in it, and start nginx:1.27-alpine with the name dk-site, bind-mounting /root/ops1/site at /usr/share/nginx/html.
A bind mount specifies a host path directly. If you attach it at nginx's default document root path, you can check it right away.
Attach it read-only
Start a dk-ro container, mount dk-data at /data as read-only, try writing a file inside it, and save the resulting error message to /root/ops1/ro-error.txt.
Add the read-only flag to the mount option, try writing inside, and save the resulting error message as it is.
Rewrite with the --mount syntax
Start a dk-site2 container with the --mount syntax, attaching the same source and target as in step 4, but make it read-only.
It should give the same result as the short syntax. Join type, source, target and readonly with commas.
Back up the volume
Back up the contents of the dk-data volume to /root/ops1/dk-data.tgz. The archive must contain hello.txt.
Use a temporary container that mounts both the volume and the backup destination directory. Enter the source with -C to keep the paths clean.
Restore to a new volume
Create a new volume called dk-data-restore and restore the backup into it. The content must be the same as the original.
Create a new volume and unpack the archive into it. The content must be exactly the same as the original.