5 underused Podman features to try now
5 underused Podman features to try now
https://www.redhat.com/ja/blog/podman-features-2
In the first part of 5 Podman features to try now, Dan Walsh talked about the Podman team’s effort to attain feature parity with Docker and the ways Podman has surpassed Docker. He then reviewed five of his favourite Podman commands and options that are not present in Docker.
In part two, I will review five Podman features that I think are either underused or under-appreciated largely because Docker does not implement them, yet will simplify your container experience.
- Utilise pods Pods are generally a unique feature for single-node container runtimes and originate from the Kubernetes world. A pod is one or more containers that share a set of namespaces and cgroups. Many container users do not employ pods or understand how pods can help them.
More than half of the basic questions I field about containers can be solved by using pods. Because pods share namespaces, they simplify intercontainer communication, enable lightweight orchestration of container deployment, and even sprinkle in some special functions.
For example, one common question people ask is, “How can I get container A with a service on a particular port communicating with container B on a specific port?” I see users doing all kinds of IP address parsing and container aliasing to solve this problem. My answer? Put them in a pod and tell the services to communicate over the pod’s localhost interface. This approach eliminates the need for IP addresses or aliases.
You can create a new pod with the podman pod create command or by defining the pod with podman run. I prefer the latter. I’ll make a fictitious pod called example. The first container in the pod will run MySQL:
$ podman run -dt –pod new:example docker.io/library/mysql:latest 7edd8961a0ca11932491899afa29c7a36adb17421345007de66a69247164daa9 And now I can add another container to the pod with the podman run command:
$ podman run -dt –pod example quay.io/libpod/alpine_nginx 0f7ecf9bec272420e649bf4fc59bce3c6f3acfd76ebd87dda2ec84e69f33fd2d A pod that contains a database and a web server within a pod looks like this:
$ podman pod ls POD ID NAME STATUS CREATED INFRA ID # OF CONTAINERS 5e157786e495 example Running 4 minutes ago 918771c42cc1 3 I can further inspect the pod’s contents by adding the –pod option to podman ps. Notice how it now shows each container’s pod ID:
$ podman ps –pod CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES POD ID PODNAME 918771c42cc1 localhost/podman-pause:4.0.0-dev-1645134365 4 minutes ago Up 4 minutes ago 5e157786e495-infra 5e157786e495 example 0f7ecf9bec27 quay.io/libpod/alpine_nginx:latest nginx -g daemon o… 4 minutes ago Up 4 minutes ago nginx 5e157786e495 example 7edd8961a0ca docker.io/library/mysql:latest mysqld About a minute ago Up About a minute ago db 5e157786e495 example In this setup, both the web server and the database can refer to each other over localhost because they share the same network space. There is no need to name the container or deal with IP addresses or hostnames.
Another perhaps unintended benefit of pods is they offer a very lightweight orchestration for containers on a single node. If you have several containers in a single pod, they can all be stopped, started, and restarted with the podman pod command.
[ Try this course: A basic introduction to container management in Red Hat Enterprise Linux. ]
- Understand init containers In the previous section, I mentioned that pods bring some specific functions into play. Init containers are one of those. An init container runs after the pod’s infra container starts but before regular pod containers start. Init containers are useful for running setup operations for the pod’s applications.
There are two flavors of init containers: always or once. The always value means the container will run with each and every pod start, whereas the once value means the container will run once when the pod starts and be removed from the pod. Consider the following layout of a LAMP pod.
LAMP pod The LAMP pod has four containers and two volumes before it runs the first time. The two core containers run MySQL, Apache, and PHP. Then there are also two complementary init containers. The pod has a one-time init container for MySQL, which defines the database tables and preloads data. This container disappears after it runs. Then there is an always init container that runs before the Apache container starts. This init container runs Git commands to clone down the most recent web server code.
Check out the article Build Kubernetes pods with Podman play kube for a deeper dive into this example.
- Create additional image stores Podman’s storage libraries are capable of using more than one image store. When you use Podman normally, users have default image stores. For rootless users, the store is usually in their homedir, and for rootfull users (depending on the distribution), it is /var/lib/containers/storage. But in the storage configuration, you can also add additional stores, usually read-only, to Podman.
Secondary storage opens up some interesting use cases for Podman users. Given the correct location, secondary stores can be shared between root and unprivileged users. Moreover, you can set permissions so that unprivileged users can put images in the store for other users, which results in fewer pulls and pushes to and from the image registries. I’ve put an example together and added a Fedora image to the store. Here is what the default image store looks like:
$ podman images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/library/rust 1-slim-buster 3ca1d8ed11bf 7 days ago 653 MB docker.io/library/debian buster 739ca6e61c27 8 days ago 119 MB docker.io/library/alpine latest c059bfaa849c 3 months ago 5.87 MB quay.io/libpod/helloworld latest d7b9a2cfb457 4 months ago 5.87 MB The first thing I need to do is create the mount point for the additional storage. Then I will set the permissions so the wheel group can read and write to it:
$ sudo mkdir –mode=u+rwx,g+rws /var/sharedstore $ sudo chgrp -R wheel /var/sharedstore Now I’ll create the store. The easiest way is to populate the store with an image. Because the additional store is read-only, use the –root parameter to point to only the extra share, which will allow users to write to it:
$ podman –root /var/sharedstore/ pull fedora
Resolved “fedora” as an alias (/etc/containers/registries.conf.d/000-shortnames.conf)
Trying to pull registry.fedoraproject.org/fedora:latest…
Getting image source signatures
Copying blob 9c6cc3463716 done
Copying config 750037c05c done
Writing manifest to image destination
Storing signatures
750037c05cfe1857e16500167c7c217658e15eb9bc6283020cfb3524c93d1240
I’m using Fedora 35, and as such, I need to set SELinux permissions for the new store:
$ sudo semanage fcontext -a -e /var/lib/containers/storage /var/sharedstore $ sudo restorecon -r /var/sharedstore/ The next step is to teach Podman about the additional store. Do this by editing the respective storage.conf files. For unprivileged users, that is usually $HOME/.config/containers/storage.conf; and for rootfull users it is /etc/containers/storage.conf. Those files are not likely to already exist, so just add the following to enable the share:
[storage] driver = “overlay” [storage.options] additionalimagestores = [ “/var/sharedstore” ] With that, the additional store should be enabled. The real test will be if the Fedora image is now seen as an available image.
$ podman images REPOSITORY TAG IMAGE ID CREATED SIZE R/O docker.io/library/rust 1-slim-buster 3ca1d8ed11bf 7 days ago 653 MB false docker.io/library/debian buster 739ca6e61c27 8 days ago 119 MB false localhost/foobar latest 750037c05cfe 2 weeks ago 159 MB false registry.fedoraproject.org/fedora latest 750037c05cfe 2 weeks ago 159 MB true docker.io/library/alpine latest c059bfaa849c 3 months ago 5.87 MB false quay.io/libpod/helloworld latest d7b9a2cfb457 4 months ago 5.87 MB false You can basically use images in additional stores as you would regular images. Just remember that the store itself is read-only.
$ podman run -it –rm fedora cat /etc/redhat-release Fedora release 35 (Thirty Five) [ Want to test your sysadmin skills? Take a skills assessment today. ]
Earlier, I mentioned that the root user could share the additional image store. To do so, root must edit /etc/containers/storage.conf and add the additional store. As was mentioned above, the store can be made accessible for rootfull and rootless users if given the correct permissions. After the root user edits storage.conf, a rootfull user can see the secondary store:
$ sudo podman images REPOSITORY TAG IMAGE ID CREATED SIZE R/O docker.io/nicolaka/netshoot latest f56a7d7fefd7 33 hours ago 452 MB false registry.fedoraproject.org/fedora latest 750037c05cfe 2 weeks ago 159 MB true
- Use the system reset command One command I didn’t use until recently is Podman’s system reset. As a Podman developer, I have to do quite a bit of container and image teardown after developing some feature or debugging a very specific problem. While I use Podman’s -a switch to remove images, I still have to issue one command for containers and a different one for images, unless I remember podman rmi -fa deletes all containers and images.
Even so, this can leave artifacts in the stores. Using podman system reset –force deletes the stores, resulting in a more thorough removal of everything. Any network configurations you created will also be deleted. This is like hitting the reset button on your phone. When the process completes, it is like you never ran Podman.
Here is an example of a container image store:
$podman images REPOSITORY TAG IMAGE ID CREATED SIZE localhost/sillyboy latest a1e9cccd2fab 2 days ago 5.62 GB docker.io/library/postgres latest 6a3c44872108 4 days ago 382 MB quay.io/libpod/alpine_nginx latest 036646f5d23c 4 days ago 23.2 MB localhost/net latest 036646f5d23c 4 days ago 23.2 MB