Chapter 3: Running the First Container

In the previous chapters, we discussed the history of containers, their adoption, and the various technologies that contribute to their spread, while also looking at the main differences between Docker and Podman.

Now, it’s time to start working with real examples: in this chapter, we will learn about how to get Podman up and running on your preferred Linux operating system so that we can start our first container. We will discover the various installation methods, all the prerequisites, and then start a container.

In this chapter, we’re going to cover the following main topics:

  • Choosing an operating system and installation method
  • Preparing your environment
  • Running your first container

Technical requirements

Having good technical experience in administering a Linux operating system would be preferable for understanding the key concepts provided in this chapter.

We will go through the main steps of installing new software on various Linux distributions, so having some experience as a Linux sysadmin could be helpful in troubleshooting possible issues during installation.

In addition, some of the theoretical concepts that were explained in the previous chapters could help you understand the procedures described in this chapter.

Choosing an operating system and installation method

Podman is supported on different distributions and operating systems. It is very easy to install, and the various distributions now provide their own maintained packages that can be installed with their specific package managers.

In this section, we will cover the different installation steps for the most common GNU/Linux distributions, as well as on macOS and Windows, despite the focus of this book being on Linux-based environments.

As a bonus topic, we will also learn how to build Podman directly from source.

Choosing between Linux distributions and another OS

The choice between the different distributions of the GNU/Linux operating system is something that is dictated by the user’s preferences and needs, which are usually influenced by several factors that are outside the scope of this book.

Many advanced users today choose Linux distributions as their main operating systems. However, there is a large quota, especially among developers, who stick to macOS as their standard operating system. Microsoft Windows still retains the largest market share on desktop workstations and laptops.

Today, we have a huge ecosystem of Linux distributions that have evolved from a smaller subset of core, historical distributions such as Debian, Fedora, Red Hat Enterprise Linux, Gentoo, Arch, and openSUSE. Specialized websites such as DistroWatch (https://distrowatch.com) keep track of the many releases of Linux and BSD-based distributions.

Despite running a Linux kernel, the various distributions have different architectural approaches for userspace behavior, such as filesystem structure, libraries, or packaging systems used to deliver software releases.

Another significant difference is related to security and mandatory access control subsystems: for example, Fedora, CentOS, Red Hat Enterprise Linux, and all the derivates lean on SELinux as their mandatory access control subsystem. On the other hand, Debian, Ubuntu, and their derivates are based on a similar solution called AppArmor.

Podman interacts with both SELinux and AppArmor to provide better container isolation, but the underlying interfaces are different.

Important Note

All this book’s examples and source code has been written and tested using Fedora Workstation 34 as the reference OS.

Those of you who want to reproduce an environment as close as possible to the book in their lab have different options:

Running instances on public clouds is the best option for users who are not able to run virtual machines locally.

Providers such as Amazon Web Services, Google Cloud Platform, Microsoft Azure, and DigitalOcean also offer ready-to-use Fedora-based cloud instances with low monthly prices for smaller sizes.

Prices can vary in time and across tiers and keeping track of them is beyond the purpose of this book. Almost all providers offer free plans for learning or basic use, with small/micro tiers at very low prices.

Containers are Linux-based, and the different container engines and runtimes interact with the Linux kernel and libraries to operate. Windows has recently introduced support for native containers with an approach to isolation that’s quite close to the Linux namespace concepts described previously. However, only Windows-based images can run natively and not all container engines support native execution.

The same considerations are valid for macOS: its architecture is not based on Linux but on a hybrid Mach/BSD kernel called XNU. For this reason, it does not offer the Linux kernel features necessary to run containers natively.

For both Windows and macOS, a virtualization layer that abstracts the Linux machine is necessary to run native Linux containers.

Podman offers remote client functions for Windows and macOS, enabling users to connect to a local or remote Linux box.

Windows users can also benefit from an alternative approach based on the Windows Subsystem for Linux (WSL) 2.0, a compatibility layer that runs a lightweight VM to expose Linux kernel interfaces along with Linux userspace binaries, thanks to Hyper-V virtualization support.

The following sections will cover the necessary steps for installing Podman on the most popular Linux distributions, as well as macOS and Windows.

Installing Podman on Fedora

Fedora packages are maintained by its wide community and managed with the DNF package manager. To install Podman, run the following command from a terminal:

# dnf install –y podman

This command installs Podman and configures the environment with config files (covered in the next section). It also installs systemd units to provide additional features such as REST API services or container auto-updates.

Installing Podman on CentOS

Podman can be installed on CentOS 7, CentOS 8, and CentOS Stream (https://www.centos.org/). Users installing on CentOS 7 must have the Extras repository enabled, while users installing on CentOS 8 and Stream must have the Podman package available from the already enabled AppStream repository.

To install Podman, run the following command from a terminal:

# yum install –y podman

Like in Fedora, this command installs Podman and all its dependencies, including config files and systemd unit files.

Installing Podman on RHEL

To install Podman on Red Hat Enterprise Linux (RHEL) (https://www.redhat.com/en/technologies/linux-platforms/enterprise-linux), users should follow two different procedures on RHEL 7 and RHEL 8.

On RHEL 7, users must enable the extra channel and then install the Podman package:

# subscription-manager repos

--enable=rhel-7-server-extras-rpms

# yum -y install podman

On RHEL 8, the Podman package is available on a dedicated module called container-tools. Modules are custom sets of RPM packages that can be organized in streams with independent release cycles:

# yum module enable -y container-tools:rhel8

# yum module install -y container-tools:rhel8

The container-tools module installs, along with Podman, two useful tools, both of which will be covered later in this book:

  • Skopeo, a tool for managing OCI images and registries
  • Buildah, a specialized tool for building custom OCI images from Dockerfiles and from scratch

(Not) Installing Podman on Fedora CoreOS and Fedora Silverblue

The title of this subsection is a bit of a joke. The reality is that Podman is already installed on both distributions and is a crucial tool for running containerized workloads.

The Fedora CoreOS and Fedora SilverBlue distributions are immutable, atomic operating systems aimed to be used on server/cloud and desktop environments, respectively.

Fedora CoreOS (https://getfedora.org/en/coreos/) is the upstream of Red Hat CoreOS, the operating system used to run Red Hat OpenShift and the base OS of OpenShift Kubernetes Distribution (OKD), the community-based Kubernetes distribution used as the upstream of Red Hat OpenShift.

Fedora Silverblue (https://silverblue.fedoraproject.org/) is a desktop-focused immutable operating system that aims to provide a stable and comfortable desktop user experience, especially for developers working with containers.

So, on both Fedora CoreOS and Fedora Silverblue, just open a terminal and run Podman.

Installing Podman on Debian

The Podman package is available on Debian (https://www.debian.org/) since version 11, codename Bullseye (named after the famous toy horse from the Toy Story 2 and 3 movies).

Debian uses the apt-get package handling utility to install and upgrade system packages.

To install Podman on a Debian system, run the following command from the terminal:

# apt-get –y install podman

The preceding command installs the Podman binary and its dependencies, along with its config files, systemd units, and man pages.

Installing Podman on Ubuntu

Being built on Debian, Ubuntu (https://ubuntu.com/) behaves in an analogous way for package management. To install Podman on Ubuntu 20.10 or later, run the following commands:

# apt-get -y update

# apt-get -y install podman

These two commands update the system packages and then install the Podman binaries and related dependencies.

Installing Podman on openSUSE

The openSUSE distribution (https://www.opensuse.org/) is backed by SUSE and is available in two different flavors – the rolling release known as Tumbleweed, and the LTS distribution known as Leap. Podman is available in the openSUSE repositories and can be installed with the following command:

# zypper install podman

The Zypper package manager will download and install all the necessary packages and dependencies.

Installing Podman on Gentoo

Gentoo (https://www.gentoo.org/) is a clever distribution that is characterized by building installed packages directly on the target machine with the optional extra user customizations. To achieve this, it uses the Portage package manager, inspired by FreeBSD ports.

To install Podman on Gentoo, run the following command:

# emerge app-emulation/podman

The emerge utility will download and automatically build the Podman sources on the system.

Installing Podman on Arch Linux

Arch Linux (https://archlinux.org/) is a rolling Linux distribution that shines for being highly customizable. It uses the pacman package manager to install and update packages from official and users' custom repositories.

To install Podman on Arch Linux and derivate distributions, run the following command from the terminal:

# pacman –S podman

By default, Podman’s installation on Arch Linux does not permit rootless containers. To enable them, follow the official Arch wiki instructions: https://wiki.archlinux.org/title/Podman#Rootless_Podman.

Installing Podman on Raspberry Pi OS

The famous Raspberry Pi single-board computer has achieved enormous success among developers, makers, and hobbyists.

It runs the Raspberry Pi OS (https://www.raspberrypi.org/software/operating-systems/#raspberry-pi-os-32-bit), which is based on Debian.

Podman’s arm64 build is available and can be installed by following the same steps described previously for the Debian distribution.

Installing Podman on macOS

Apple users who develop and run Linux containers can install and use Podman as a remote client, while the containers are executed on a remote Linux box. The Linux machine can also be a VM that’s executed on macOS and directly managed by Podman.

To install Podman using the Homebrew package manager, run the following command from the terminal:

$ brew install podman

To initialize the VM running the Linux box, run the following commands:

$ podman machine init

$ podman machine start

Alternatively, users can create and connect to an external Linux host.

Another valid approach on macOS to creating fast, lightweight VMs for development use is Vagrant. When the Vagrant machine is created, users can manually or automatically provision additional software such as Podman and start using the customized instance using the remote client.

Installing Podman on Windows

To run Podman as a remote client, simply download and install the latest release from the GitHub releases page (https://github.com/containers/podman/releases/). Extract the archive in a suitable location and edit the TOML-encoded containers.conf file to configure a remote URI for the Linux machine or pass additional options.

The following code snippet shows an example configuration:

[engine]

remote_uri= " ssh://[email protected]:22/run/podman/podman.sock"

The remote Linux machine exposes Podman on a UNIX socket managed by a systemd unit. We will cover this topic in greater detail later in this book.

To run Podman on WSL 2.0, users must first install a Linux distribution from the Microsoft Store on their Windows host. There is a variety of available distributions under the Microsoft catalog.

The following example is based on Ubuntu 20.10:

# apt-get –y install podman

# mkdir -p /etc/containers

# echo -e "[registries.search] registries =

[‘docker.io’, ‘quay.io’]" | tee /etc/containers/registries.conf

The preceding commands install the latest Podman stable release and configure the /etc/containers/registries.conf file to provide a registries whitelist.

After its installation, some minor customizations are necessary to adapt it to the WSL 2.0 environment:

# cp /usr/share/containers/libpod.conf /etc/containers

# sed –i  ‘s/ cgroup_manager = "systemd"/ cgroup_manager = "cgroupfs"/g’ /etc/containers/libpod.conf

# sed –i ‘s/ events_logger = "journald"/ events_logger = "file"/g’ /etc/containers/libpod.conf

The preceding command configures logging and CGroup management to successfully run rootful containers in the subsystem.

Building Podman from source

Building an application from source has many advantages: users can inspect and customize code before building, cross-compile for different architectures, or selectively build only a subset of binaries. It is also a great learning opportunity to get into the project’s structure and understand its evolution. Last but not least, building from source lets the users get the latest development versions with cool new features, bugs included.

The following steps assume that the building machine is a Fedora distribution. First, we must install the necessary dependencies needed to compile Podman:

# dnf install -y

  btrfs-progs-devel

  conmon

  containernetworking-plugins

  containers-common

  crun

  device-mapper-devel

  git

  glib2-devel

  glibc-devel

  glibc-static

  go

  golang-github-cpuguy83-md2man

  gpgme-devel

  iptables

  libassuan-devel

  libgpg-error-devel

  libseccomp-devel

  libselinux-devel

  make

  pkgconfig

This command will take a while to install all the packages and their cascading dependencies.

When the installation is complete, choose a working directory and clone the Podman repository using the git command:

$ git clone https://github.com/containers/podman.git

This command will clone the entire repository in the working directory.

Change to the project directory and start the build:

$ cd podman

$ make package-install

The make package-install command compiles the source code, builds the RPM files, and installs the packages locally. Remember that the RPM format is associated with Fedora/CentOS/RHEL distributions and managed by the dnf and yum package managers.

The build process will take a few minutes to complete. To test the successful installation of the packages, simply run the following code:

$ podman version

Version:      4.0.0-dev

API Version:  4.0.0-dev

Go Version:   go1.16.6

Git Commit:   cffc747fccf38a91be5cd106d2e507afaaa23e14

Built:        Sat Aug  4 00:00:00 2018

OS/Arch:      linux/amd64

Sometimes, it is useful to build the binaries on a dedicated build host and then deploy them on other machines, using either package managers or simple archives. To only build the binaries, run the following command:

$ make

At the end of the build, the binaries will be available under the bin/ folder. To install the compiled binaries and config files locally by simply copying them into the target directories defined in the Makefile, run the following command:

$ make install

To create a binary release similar to the .tar.gz archive, which is available on the GitHub release page, run the following command:

$ make podman-release.tar.gz

Bonus tip: Building a different version is very easy – just switch to the tag of the target release using the git command. For example, to build v3.3.1, use the following command:

$ git checkout v3.3.1

In this section, we learned how to install binary releases of Podman on different distributions using their respective package managers. We also learned how to install the Podman remote client on macOS and Windows, along with Windows WSL 2.0 mode. We closed this section by showing you how to build from source.

In the next section, we will learn how to configure Podman for the first run by preparing the system environment.

Preparing your environment

Once the Podman packages have been installed, Podman is ready to be used out of the box. However, some minor customizations can be useful to provide better interoperability with external registries or to customize runtime behaviors.

Customizing the container registries search list

Podman searches for and downloads images from a list of trusted container registries. The /etc/containers/registries.conf file is a TOML config file that can be used to customize whitelisted registries that are allowed to be searched and used as image sources, as well as registry mirroring and insecure registries without TLS termination.

In this config file, the unqualified-search-registries key is populated with an array of unqualified registries with no specification regarding images repositories and tags.

On a Fedora system, with a new installation of Podman, this key has the following content:

unqualified-search-registries = ["registry.fedoraproject.org", "registry.access.redhat.com", "docker.io", "quay.io"]

Users can add or remove registries from this array to let Podman search and pull from them.

Important Note

Be very cautious when adding registries and use only trusted registries to avoid pulling images containing malicious code.

The default list is adequate to search for and run all the book examples. Those of you who are already running private registries can try to add them to the unqualified search registries array.

Since registries are both private and public, please keep in mind that private registries usually require additional authentication to be accessed. This can be accomplished with the podman login command, which will be covered later in this book.

If the $HOME/.config/containers/registries.conf file is found in the user home, it overrides the /etc/containers/registries.conf file. In this way, different users on the same system will be able to run Podman with their custom registry whitelists and mirrors.

Optional – enable socket-based services

This is an optional step and, in the absence of specific needs, this section’s contents can be safely skipped.

As we mentioned previously, Podman is a daemonless container manager that needs no background service to run containers. However, users may need to interact with the Libpod APIs exposed by Podman, especially when migrating from a Docker-based environment.

Podman can expose its APIs using a UNIX socket (default behavior) or a TCP socket. The latter option is less secure because it makes Podman accessible from the outside world, but it is necessary in some cases, such as when it should be accessed by a Podman client on a Windows or macOS workstation.

Important Note

Be careful when running the API service using a TCP endpoint on a machine exposed to the internet since the service will be globally accessible.

The following command exposes the Podman APIs on a UNIX socket:

$ sudo podman system service --time=0

  unix:///run/podman/podman.sock

After running this command, users can connect to the API service.

Having to run this command on a terminal window is not a handy approach. Instead, the best approach is to use a systemd socket (see man systemd.socket).

Socket units in systemd are special kinds of service activators: when a request reaches the pre-defined endpoint of the socket, systemd immediately spawns the homonymous service.

When Podman is installed, the podman.socket and podman.service unit files are created. podman.socket has the following content:

# cat /usr/lib/systemd/system/podman.socket

[Unit]

Description=Podman API Socket

Documentation=man:podman-system-service(1)

[Socket]

ListenStream=%t/podman/podman.sock

SocketMode=0660

[Install]

WantedBy=sockets.target

The ListenStream key holds the relative path of the socket, which is expanded to /run/podman/podman.sock:

The podman.service has the following content:

# cat /usr/lib/systemd/system/podman.service

[Unit]

Description=Podman API Service

Requires=podman.socket

After=podman.socket

Documentation=man:podman-system-service(1)

StartLimitIntervalSec=0

[Service]

Type=exec

KillMode=process

Environment=LOGGING="--log-level=info"

ExecStart=/usr/bin/podman $LOGGING system service

[Install]

WantedBy=multi-user.target

The ExecStart= field indicates the command to be launched by the service, which is the same podman system service command we showed previously.

The Requires= field indicates that the podman.service unit needs podman.socket to be activated.

So, what happens when we enable and start the podman.socket unit? systemd handles the socket and waits for a connection to the socket endpoint. When this event happens, it immediately starts the podman.service unit. After a period of inactivity, the service is stopped again.

To enable and start the socket unit, run the following command:

# systemctl enable --now podman.socket

We can test the results with a simple curl command:

# curl --unix-socket /run/podman/podman.sock   

  http://d/v3.0.0/libpod/info

The printed output will be a JSON payload that contains the container engine configuration.

What happened when we hit the URL? Under the hood, the service unit was immediately started and triggered by the socket when the connection was issued. Some of you may have noticed a slight delay (in the order of a 1/10th of a second) the very first time the command was executed.

After 5 seconds of inactivity, podman.service deactivates again. This is due to the default behavior of the podman system service command, which runs for 5 seconds only by default unless the –time option is passed to provide a different timeout (a value of 0 means forever).

Optional – customize Podman’s behavior

Podman’s default configuration works out of the box for most use cases, but its configuration is highly flexible. The following configuration files are available for customizing its behavior:

  • containers.conf: This TOML-formatted file holds Podman runtime configurations, as well as search paths for conmon and container runtime binaries. It is installed by default under the /usr/share/containers/ path and can be overridden by the /etc/containers/containers.conf and $HOME/.config/containers/containers.conf files for system-wide and user-wide settings, respectively.

This file can be used to customize the behavior of the engine. Users can influence how the container is created and its life cycle by customizing settings such as logging, DNS resolution, environment variables, shared memory usage, Cgroup management, and many others.

For a full list of settings, check out the related man page, which was installed along with the Podman package. (man containers.conf)

  • storage.conf: This TOML-formatted file is used to customize the storage settings that are used by the container engine. In particular, this file enables you to customize the default storage driver, as well as the read/write directory of the container storage (also known as the graph root), which is an additional driver storage option. By default, the driver is set to overlay.

The default path of this file is /usr/share/containers/storage.conf and overrides can be found or created under /etc/containers/storage.conf for system-wide customizations.

User-scoped configurations that impact rootless containers can be found under $XDG_CONFIG_HOME/containers/storage.conf or $HOME/.config/containers/storage.conf.

  • mounts.conf: This file defines the volume mounts that should be automatically mounted inside a container when it is started. This is useful, for example, to automatically pass secrets such as keys and certificates inside a container.

It can be found under /usr/share/containers/mounts.conf and overridden by a file located at /etc/containers/mounts.conf.

In rootless mode, the override file can be placed under $HOME/.config/containers/mounts.conf.

  • seccomp.json: This is a JSON file that lets users customize the allowed syscalls that a process inside a container can perform and define the blocked ones at the same time. This topic will be covered again in Chapter 11, Securing Containers, which will provide a deeper understanding of the security constraints of containers.

The default path for this file is /usr/share/containers/seccomp.json. The seccomp man page (man seccomp) provides an overview of how seccomp works on a Linux system.

  • policy.json: This is a JSON file that defines how Podman will perform signature verification. The default path of this file is /etc/containers/policy.json and can be overridden by the user-scoped $HOME/.config/containers/policy.json.

This config file accepts three kinds of policies:

  • insecureAcceptAnything: Accept any image from the specified registry.
  • reject: Reject any image from the specified registry.
  • signedBy: Accept only images signed by a specific, known entity.

The default configuration is to accept every image (the insecureAcceptAnything policy), but it can be modified to pull only trusted images that can be verified by a signature. Users can define custom GPG keys to verify the signatures and the identity that signed them. For extra details about the possible policies and configuration examples, please refer to the related man page (man containers-policy.json).

In this section, we discussed some basic configurations of Podman that are useful to know from when Podman is first installed. In the next section, we will cover our first container execution examples.

Running your first container

Now, it’s time to finally run our first container.

In the previous section, we uncovered how to install Podman on our favorite Linux distribution, as well as what’s included in the base packages once installed. Now, we can start using our daemonless container engine.

Running containers in Podman is handled through the podman run command, which accepts many options for controlling the behavior of the just ran container, its isolation, its communication, its storage, and so on.

The easiest and shortest Podman command for running a brand-new container is as follows:

$ podman run <imageID>

We have to replace the imageID string with the image name/location/tag we want to run. If the image is not present in the cache or we have not downloaded it before, Podman will pull the image for us from the respective container registry.

Interactive and pseudo-tty

To introduce this command and its options, let’s start simple and run the following command:

$ podman run -i -t fedora /bin/bash

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 ecfb9899f4ce done  

Copying config 37e5619f4a done  

Writing manifest to image destination

Storing signatures

[root@ec444ad299ab /]#

Let’s see what Podman did once we executed the previous command:

  1. It recognized the image’s name, fedora, as an alias for the latest Fedora container image.
  2. It then realized that the image was missing from the local cache because it was the first time that we tried to run it.
  3. It pulled down the image from the right registry. It chose the Fedora Project registry because it matched the aliases contained in the registries’ configurations.
  4. Finally, it started the container and presented us with an interactive shell, executing the Bash shell program that we requested.

The previous command prompted an interactive shell thanks to the two options that we can analyze, as follows:

  • --tty, -t: With this option, Podman allocates a pseudo-tty (see man pty) and attaches it to the container’s standard input.
  • --interactive, -i: With this option, Podman keeps stdin open and ready to be attached to the previous pseudo-tty.

As stated in the previous chapters, when a container is created, the isolated processes inside it will run on a writable root filesystem, as a result of a layered overlay.

This allows any process to write files, but don’t forget that they will last until the container is running, as containers are ephemeral by default.

Now, you can execute any command and check its output in the console we just brought up:

[root@ec444ad299ab /]# dnf install -y iputils iproute

Last metadata expiration check: 0:01:50 ago on Mon Sep 13 08:54:20 2021.

Dependencies resolved.

=============================================================================================================================================================================

Package                                           Architecture                      Version                                        Repository                          Size

=============================================================================================================================================================================

Installing:

iproute                                           x86_64                            5.10.0-2.fc34                                  fedora                             679 k

iputils                                           x86_64                            20210202-2.fc34                                fedora                             170 k

Installing dependencies:

...

[root@ec444ad299ab /]# ip r

default via 10.0.2.2 dev tap0

10.0.2.0/24 dev tap0 proto kernel scope link src 10.0.2.100

[root@ec444ad299ab /]# ping -c2 10.0.2.2

PING 10.0.2.2 (10.0.2.2) 56(84) bytes of data.

64 bytes from 10.0.2.2: icmp_seq=1 ttl=255 time=0.030 ms

64 bytes from 10.0.2.2: icmp_seq=2 ttl=255 time=0.200 ms

--- 10.0.2.2 ping statistics ---

2 packets transmitted, 2 received, 0% packet loss, time 1034ms

rtt min/avg/max/mdev = 0.030/0.115/0.200/0.085 ms

As you can see, in the previous example, we just installed two packages for inspecting the container’s network configuration and then executing a ping to the default router that’s assigned to the virtual networking of our running container. Again, if we stop this container, any changes will be lost.

To exit this interactive shell, we can just press Ctrl + D or execute the exit command. By doing this, the container will be terminated because the main running process we requested to execute (/bin/bash) will stop!

Now, let’s look at some other nice and useful options we can use with the podman run command.

Detaching from a running container

As we learned previously, Podman gives us the chance to attach an interactive shell to our running container. However, we will soon discover that this is not the preferred way to run our containers.

Once a container has been started, we can easily detach from it, even if we start it with an interactive tty attached:

$ podman run -i -t registry.fedoraproject.org/f29/httpd

Trying to pull registry.fedoraproject.org/f29/httpd:latest...

Getting image source signatures

Copying blob aaf5ad2e1aa3 done  

Copying blob 7692efc5f81c done  

Copying blob d77ff9f653ce done  

Copying config 25c76f9dcd done  

Writing manifest to image destination

Storing signatures

=> sourcing 10-set-mpm.sh ...

=> sourcing 20-copy-config.sh ...

=> sourcing 40-ssl-certs.sh ...

AH00558: httpd: Could not reliably determine the server’s fully qualified domain name, using 10.0.2.100. Set the ‘ServerName’ directive globally to suppress this message

[Tue Sep 14 09:26:05.691906 2021] [ssl:warn] [pid 1:tid 140416655523200] AH01882: Init: this version of mod_ssl was compiled against a newer library (OpenSSL 1.1.1b FIPS  26 Feb 2019, version currently loaded is OpenSSL 1.1.1 FIPS  11 Sep 2018) - may result in undefined or erroneous behavior

[Tue Sep 14 09:26:05.692610 2021] [ssl:warn] [pid 1:tid 140416655523200] AH01909: 10.0.2.100:8443:0 server certificate does NOT include an ID which matches the server name

AH00558: httpd: Could not reliably determine the server’s fully qualified domain name, using 10.0.2.100. Set the ‘ServerName’ directive globally to suppress this message

[Tue Sep 14 09:26:05.752028 2021] [ssl:warn] [pid 1:tid 140416655523200] AH01882: Init: this version of mod_ssl was compiled against a newer library (OpenSSL 1.1.1b FIPS  26 Feb 2019, version currently loaded is OpenSSL 1.1.1 FIPS  11 Sep 2018) - may result in undefined or erroneous behavior

[Tue Sep 14 09:26:05.752806 2021] [ssl:warn] [pid 1:tid 140416655523200] AH01909: 10.0.2.100:8443:0 server certificate does NOT include an ID which matches the server name

[Tue Sep 14 09:26:05.752933 2021] [lbmethod_heartbeat:notice] [pid 1:tid 140416655523200] AH02282: No slotmem from mod_heartmonitor

[Tue Sep 14 09:26:05.755334 2021] [mpm_event:notice] [pid 1:tid 140416655523200] AH00489: Apache/2.4.39 (Fedora) OpenSSL/1.1.1 configured -- resuming normal operations

[Tue Sep 14 09:26:05.755346 2021] [core:notice] [pid 1:tid 140416655523200] AH00094: Command line: ‘httpd -D FOREGROUND’

What now? To detach from our running container, we just need to press these special keyboard shortcuts: Ctrl + P, Ctrl + Q. With this sequence, we will return to our shell prompt while the container will keep running.

To recover our detached container’s tty, we must get the list of running containers:

$ podman ps

CONTAINER ID  IMAGE                                        COMMAND               CREATED        STATUS            PORTS       NAMES

685a339917e7  registry.fedoraproject.org/f29/httpd:latest  /usr/bin/run-http...  3 minutes ago  Up 3 minutes ago              clever_zhukovsky

We will explore this command in more detail in the next chapter, but for the moment, just take note of Container ID and then execute the following command to re-attach to the previous tty:

$ podman attach 685a339917e7

Note that we can easily start a container in detached mode by simply adding the -d option to podman run, like this:

$ podman run -d -i -t registry.fedoraproject.org/f29/httpd

In the next section, we’ll learn how to use the detach option for special purposes.

Network port publishing

As we mentioned in the previous chapters, Podman, like any other container engine, attaches a virtual network to a container in a running state that has been isolated from the original host network. For this reason, if we want to easily reach our container or even expose it outside our host network, we need to instruct Podman to do port mapping.

The Podman -p option publishes a container’s port to the host:

-p=ip:hostPort:containerPort

Both hostPort and containerPort could be a range of ports, and if the host IP is not set or it is set to 0.0.0.0, then the port will be bound to all the IP addresses of the host.

If we take back the command we used in the previous section, it becomes the following:

$ podman run -p 8080:8080 -d -i -t registry.fedoraproject.org/f29/httpd

Now, we can take note of what Container ID has been assigned to our running container:

$ podman ps

CONTAINER ID  IMAGE                                        COMMAND               CREATED         STATUS             PORTS                   NAMES

fc9d97642801  registry.fedoraproject.org/f29/httpd:latest  /usr/bin/run-http...  10 minutes ago  Up 10 minutes ago  0.0.0.0:8080->8080/tcp  confident_snyder

Then, we can look at the port mapping we just defined:

$ podman port fc9d97642801

8080/tcp -> 0.0.0.0:8080

Next, we can test whether this port mapping works using curl, an easy-to-use HTTP web client. Alternatively, you can point your favorite web browser to the same URL, as follows:

$ curl –s 127.0.0.1:8080 | head

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current

                                 Dload  Upload   Total   Spent    Left  Speed

100  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

4

6<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

5    <head>

0         <title>Test Page for the Apache HTTP Server on Fedora</title>

          <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

          <style type="text/css">

1               /*<![CDATA[*/

0               body {

0                     background-color: #fff;

Before concluding this chapter, let’s take a look at other interesting options that could be useful for managing configuration and container behavior at runtime.

Configuration and environment variables

The podman run command has tons of options for letting us configure the container behavior at runtime – we are talking about around 120 options at the time of writing this book.

For example, we have an option for changing the time zone of our running containers; that is, --tz:

$ date

Tue Sep 14 17:44:59 CEST 2021

$ podman run --tz=Asia/Shanghai fedora date

Tue Sep 14 23:45:11 CST 2021

We can change the DNS of our brand-new container with the --dns option:

$ podman run --dns=1.1.1.1 fedora cat /etc/resolv.conf

search lan

nameserver 1.1.1.1

We can also add a host to the /etc/hosts file to override a local internal address:

$ podman run --add-host=my.server.local:192.168.1.10

fedora cat /etc/hosts

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4

::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

192.168.1.10 my.server.local

We can even add an HTTP proxy to let our container use a proxy for HTTP requests. The default Podman behavior is to pass many environment variables from the host, some of which are http_proxy, https_proxy, ftp_proxy, and no_proxy.

On the other hand, we can also define custom environment variables that we can pass to our container thanks to the –env option:

$ podman run --env MYENV=podman fedora printenv

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

TERM=xterm

container=oci

DISTTAG=f34container

FGC=f34

MYENV=podman

HOME=/root

HOSTNAME=93f2541180d2

Adding and using environment variables with our containers is a best practice for passing configuration parameters to the application and influencing the service’s behavior from the operating system host. As we saw in Chapter 1, Introduction to Container Technology, containers are immutable and ephemeral by default. So, for this reason, we should leverage environment variables, as we did in the preceding example, to configure a container at runtime.

Summary

In this chapter, we started playing around with Podman’s basic commands, we learned how to run a container by looking at the most interesting options available, and we are now ready to move on to the next level: container management. To work as a system administrator in the container world, we must understand and learn about the management commands that let us inspect and check the health of our running containerized services; that’s what we saw in this chapter.

In the next chapter, which is deeply focused on container management, we are going to learn how to manage image and container life cycles with Podman. We will learn how to inspect and extract logs from running containers and will also introduce pods, how to create them, and how to run containers within them.

Further reading

For more information about the topics that were covered in this chapter, you can refer to the following resources:

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.178.240