Skip to main content

Configuring container networking with Podman

Confused about how to network rootless and rootfull pods with Podman? Read on.
Image
Peas in a pod

Podman uses two different means for its networking stack, depending on whether the container is rootless or rootfull. When rootfull, defined as being run by the root (or equivalent) user, Podman primarily relies on the containernetworking plugins project. When rootless, defined as being run by a regular user, Podman uses the slirp4netns project.

Networking and Podman pods

By definition, all containers in a Podman pod share the same network namespace. This fact means that they will have the same IP address, MAC addresses, and port mappings. You can conveniently communicate between containers in a pod by using localhost.

Rootfull networking

When the Podman package is installed, a default network configuration is commonly installed into /etc/cni/net.d as 87-podman-bridge.conflist. In addition, the default network name is defined in /usr/share/containers/libpod.conf with the key cni_default_network. In an unaltered libpod.conf, the default network name will be that of the default configuration provided by the package. You can copy the libpod.conf file to /etc/containers/libpod.conf if you want to alter any of its default settings.

To create a new network for rootfull containers, use the podman network command. You can customize the network with the command flags or by editing it by hand afterward. The podman network create command provides you with the newly created network configuration file path:

$ sudo podman network create
/etc/cni/net.d/cni-podman4.conflist

To display the currently configured networks, use the podman network ls command, and to remove a given network or networks, use podman network rm.

Note: All podman network commands are for rootfull containers only.

See the examples below to learn how to get various forms of communication working amongst rootfull containers. As with many networking topics, there are multiple ways to accomplish a given result based on restrictions and needs. These examples reflect the simplest of those ways.

Communicate between a rootfull container and the host

To communicate between the host container system and the nginx container, use the port mapping, which can be discovered with the podman port command:

# podman run -dt --rm --publish-all alpine_nginx
34e3b5c686baa2298c37475864457e1b3a383c6d172266a8847257a33d790cc4
# podman port -l
80/tcp -> 0.0.0.0:40109
# curl http://localhost:40109
podman rulez

Communicate between two rootfull containers

Communicating between two rootfull containers on the same network can be accomplished by using their IP addresses:

# podman run -dt --rm --name nginx alpine_nginx
2e383ec1ca1873c3665e975bbaf40f98020a288534f686ce08fb243d321a653c
# sudo podman inspect -f "{{.NetworkSettings.IPAddress}}" nginx
10.88.6.9
# podman run -it --rm alpine_nginx /bin/sh
/ # curl http://10.88.6.9
podman rulez

Communicate between two rootfull containers in a pod

Communicating between two containers in a pod is probably the simplest of all the methods. Because they are in the same network namespace, localhost can be used:

[root@localhost libpod]# podman run -dt --pod new:mypod --rm --name nginx alpine_nginx
b72432387f603cd4da14348537cfad6b85424ee5dbc1e3af79a527b01c2e59a6
[root@localhost libpod]# podman run --pod mypod -it --rm alpine_nginx /bin/sh
/ # curl http://localhost
podman rulez

Rootless networking

When using Podman as a rootless user, the network setup is automatic. Technically, the container itself does not have an IP address, because without root privileges, network device association cannot be achieved. Moreover, pinging from a rootless container does not work because it lacks the CAP_NET_RAW security capability that the ping command requires. If you want to ping from within a rootless container, you can allow users to send ICMP packets using this sysctl command:

# sysctl -w "net.ipv4.ping_group_range=0 2000000" 

This action would allow any process within these groups to send ping packets.

To communicate amongst two or more rootless containers, there are two choices. The easiest would be to put all of the containers into a singular pod. These containers can then communicate using localhost. Another benefit is that no ports need to be opened so that the containers can communicate with each other directly.

A second option is to use a port mapping technique to map ports to containers and then use those ports to direct traffic to specific containers.

See the examples below to learn how to get various forms of communication working amongst rootless containers. As mentioned before, there are multiple ways to accomplish a given result based on restrictions and needs. These examples reflect the simplest of those ways.

Communicate between a rootless container and the host

To communicate between the container host and a rootless container, you can simply use port mapping and direct traffic to the port Podman assigns:

$ podman run -dt --rm -P alpine_nginx
95faeb0c9010d78fd6073ae4aea2e8a8baf10b77391218790682637c51c3ab4e
[bbaude@localhost libpod (master)]$ podman port -l
80/tcp -> 0.0.0.0:38997
[bbaude@localhost libpod (master)]$ curl http://localhost:38997
podman rulez

Communicate between two rootless containers

There are a number of non-trivial ways to accomplish communication between two rootless containers. The most straightforward is to use the port mapping technique from the previous example, and then communicate with the host from the second container:

$ podman run -dt --rm -P alpine_nginx
d73e09326390d5de9a8784daf25a13093e9012c7a1a8bef1febc585fd94f8a5f
$ podman port -l
80/tcp -> 0.0.0.0:35527
$ ip addr show enp0s31f6
2: enp0s31f6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
      link/ether c8:5b:76:f3:e9:f8 brd ff:ff:ff:ff:ff:ff
      inet 192.168.1.115/24 brd 192.168.1.255 scope global dynamic noprefixroute enp0s31f6
      valid_lft 78662sec preferred_lft 78662sec
      inet6 fe80::ee11:476a:eea:7924/64 scope link noprefixroute
      valid_lft forever preferred_lft forever
[bbaude@localhost libpod (master)]$ podman run -it --rm alpine_nginx /bin/sh
/ # curl http://192.168.1.115:35527[4] [5]
podman rulez

Communicate between two rootless containers in a pod

This is usually the simplest approach for two rootless containers to communicate. Putting them in a pod allows them to communicate directly over localhost:

$ podman run -dt --rm --pod new:mypod alpine_nginx
e2add389417957f2871503aeda82b1d826db3c8e00a5241528b59bf5060d5d94
[bbaude@localhost libpod (master)]$ podman run -it --rm --pod mypod alpine_nginx /bin/sh
/ # curl http://localhost
podman rulez

Summary

With Podman, remember there are subtleties in how networking is implemented for both rootfull and rootless containers. For communication between multiple containers, it is often easiest to put the containers within the same pod so they share a network namespace. For rootless users, if containers are not in a pod, you will have to use exposed ports on the host for them to communicate with each other.

Topics:   Networking   Containers  
Author’s photo

Brent Baude

Brent is a Principle Software Engineer at Red Hat and leads the Container Runtimes team which includes things like Podman and Buildah. He is a maintainer of Podman upstream and a major contributor as well. More about me

Related Content

OUR BEST CONTENT, DELIVERED TO YOUR INBOX