Chapter 1. Starting with containers
Chapter 1. Starting with containers Linux containers have emerged as a key open source application packaging and delivery technology, combining lightweight application isolation with the flexibility of image-based deployment methods. Red Hat Enterprise Linux implements Linux containers using core technologies such as: Control groups (cgroups) for resource management Namespaces for process isolation SELinux for security Secure multi-tenancy These technologies reduce the potential for security exploits and provide you with an environment for producing and running enterprise-quality containers. Red Hat OpenShift provides powerful command-line and Web UI tools for building, managing, and running containers in units referred to as pods. Red Hat allows you to build and manage individual containers and container images outside of OpenShift. This guide describes the tools provided to perform those tasks that run directly on RHEL systems. Unlike other container tools implementations, the tools described here do not center around the monolithic Docker container engine and docker command. Instead, Red Hat provides a set of command-line tools that can operate without a container engine. These include: podman - for directly managing pods and container images ( run , stop , start , ps , attach , exec , and so on) buildah - for building, pushing, and signing container images skopeo - for copying, inspecting, deleting, and signing images runc - for providing container run and build features to podman and buildah crun - an optional runtime that can be configured and gives greater flexibility, control, and security for rootless containers Because these tools are compatible with the Open Container Initiative (OCI), they can be used to manage the same Linux containers that are produced and managed by Docker and other OCI-compatible container engines. However, they are especially suited to run directly on Red Hat Enterprise Linux, in single-node use cases. For a multi-node container platform, see OpenShift and Using the CRI-O Container Engine for details. 1.1. Characteristics of Podman, Buildah, and Skopeo The Podman, Skopeo, and Buildah tools were developed to replace Docker command features. Each tool in this scenario is more lightweight and focused on a subset of features. The main advantages of Podman, Skopeo and Buildah tools include: Running in rootless mode - rootless containers are much more secure, as they run without any added privileges No daemon required - these tools have much lower resource requirements at idle, because if you are not running containers, Podman is not running. Docker, conversely, have a daemon always running Native systemd integration - Podman allows you to create systemd unit files and run containers as system services The characteristics of Podman, Skopeo, and Buildah include: Podman, Buildah, and the CRI-O container engine all use the same back-end store directory, /var/lib/containers , instead of using the Docker storage location /var/lib/docker , by default. Although Podman, Buildah, and CRI-O share the same storage directory, they cannot interact with each other's containers. Those tools can share images. To interact programmatically with Podman, you can use the Podman v2.0 RESTful API, it works in both a rootful and a rootless environment. For more information, see Using the container-tools API chapter. Additional resources Say "Hello" to Buildah, Podman, and Skopeo Podman and Buildah for Docker users Buildah: A tool for building OCI container images Podman: A tool for managing OCI containers and pods Skopeo: A tool for copying and inspecting container images 1.2. Common Podman commands You can manage images, containers, and container resources with the podman utility by using the following basic commands. To display a full list of all Podman commands, use podman -h . attach Attach to a running container. commit Create new image from changed container. container checkpoint Checkpoint one or more running containers. container restore Restore one or more containers from a checkpoint. build Build an image using Containerfile instructions. create Create, but do not start, a container. diff Inspect changes on container's filesystems. exec Run a process in a running container. export Export container's filesystem contents as a tar archive. help, h Show a list of commands or help for one command. healthcheck Run a container healthcheck. history Show history of a specified image. images List images in local storage. import Import a tarball to create a filesystem image. info Display system information. inspect Display the configuration of a container or image. kill Send a specific signal to one or more running containers. kube generate Generate Kubernetes YAML based on containers, pods or volumes. kube play Create containers, pods and volumes based on Kubernetes YAML. load Load an image from an archive. login Login to a container registry. logout Logout of a container registry. logs Fetch the logs of a container. mount Mount a working container's root filesystem. pause Pause all the processes in one or more containers. ps List containers. port List port mappings or a specific mapping for the container. pull Pull an image from a registry. push Push an image to a specified destination. restart Restart one or more containers. rm Remove one or more containers from the host. Add -f if running. rmi Remove one or more images from local storage. run Run a command in a new container. save Save image to an archive. search Search registry for image. start Start one or more containers. stats Display percentage of CPU, memory, network I/O, block I/O and PIDs for one or more containers. stop Stop one or more containers. tag Add an additional name to a local image. top Display the running processes of a container. umount, unmount Unmount a working container's root filesystem. unpause Unpause the processes in one or more containers. version Display podman version information. wait Block on one or more containers. Additional resources Podman Basics Cheat Sheet 5 Podman features to try now 1.3. Running containers without Docker Red Hat removed the Docker container engine and the docker command from RHEL 9. If you still want to use Docker in RHEL, you can get Docker from different upstream projects, but it is unsupported in RHEL 9. You can install the podman-docker package, every time you run a docker command, it actually runs a podman command. Podman also supports the Docker Socket API, so the podman-docker package also sets up a link between /var/run/docker.sock and /var/run/podman/podman.sock . As a result, you can continue to run your Docker API commands with docker-py and docker-compose tools without requiring the Docker daemon. Podman will service the requests. The podman command, like the docker command, can build container images from a Containerfile or Dockerfile . The available commands that are usable inside a Containerfile and a Dockerfile are equivalent. Options to the docker command that are not supported by podman include network, node, plugin ( podman does not support plugins), rename (use rm and create to rename containers with podman ), secret, service, stack, and swarm ( podman does not support Docker Swarm). The container and image options are used to run subcommands that are used directly in podman . Additional resources Podman and Buildah for Docker users 1.4. Choosing a RHEL architecture for containers Red Hat provides container images and container-related software for the following computer architectures: AMD64 and Intel 64 (base and layered images; no support for 32-bit architectures) PowerPC 8 and 9 64-bit (base image and most layered images) 64-bit IBM Z (base image and most layered images) ARM 64-bit (base image only) Although not all Red Hat images were supported across all architectures at first, nearly all are now available on all listed architectures. Additional resources Universal Base Images (UBI): Images, repositories, and packages 1.5. Getting container tools This procedure shows how you can install the container-tools meta-package which contains the Podman, Buildah, Skopeo, CRIU, Udica, and all required libraries. Note The stable streams are not available on RHEL 9. To receive stable access to Podman, Buildah, Skopeo, and others, use the RHEL EUS subscription. Procedure Install RHEL. Register RHEL: Enter your user name and password. The user name and password are the same as your login credentials for Red Hat Customer Portal: Subscribe to RHEL. To auto-subscribe to RHEL: To subscribe to RHEL by Pool ID: Install the container-tools meta-package: You can also install podman , buildah , and skopeo individually if you prefer. Optional: Install the podman-docker package: The podman-docker package replaces the Docker command-line interface and docker-api with the matching Podman commands instead. 1.6. Setting up rootless containers Running the container tools such as Podman, Skopeo, or Buildah as a user with superuser privileges (root user) is the best way to ensure that your containers have full access to any feature available on your system. However, with the feature called "Rootless Containers" generally available as of Red Hat Enterprise Linux 8.1, you can work with containers as a regular user. Although container engines, such as Docker, let you run Docker commands as a regular (non-root) user, the Docker daemon that carries out those requests runs as root. As a result, regular users can make requests through their containers that can harm the system. By setting up rootless container users, system administrators prevent potentially damaging container activities from regular users, while still allowing those users to safely run most container features under their own accounts. This procedure describes how to set up your system to use Podman, Skopeo, and Buildah tools to work with containers as a non-root user (rootless). It also describes some of the limitations you will encounter, because regular user accounts do not have full access to all operating system features that their containers might need to run. Prerequisites You need to become a root user to set up your RHEL system to allow non-root user accounts to use container tools. Procedure Install RHEL. Install the podman package: Create a new user account: The user is automatically configured to be able to use rootless Podman. The useradd command automatically sets the range of accessible user and group IDs automatically in the /etc/subuid and /etc/subgid files. If you change the /etc/subuid or /etc/subgid manually, you have to run the podman system migrate command to allow the new changes to be applied. Connect to the user: Note Do not use su or su - commands because these commands do not set the correct environment variables. Pull the registry.access.redhat.com/ubi9/ubi container image: Run the container named myubi and display the OS version: Additional resources Rootless containers with Podman: The basics podman-system-migrate man page on your system 1.7. Upgrading to rootless containers To upgrade to rootless containers from Red Hat Enterprise Linux 7, you must configure user and group IDs manually. Here are some things to consider when upgrading to rootless containers from Red Hat Enterprise Linux 7: If you set up multiple rootless container users, use unique ranges for each user. Use 65536 UIDs and GIDs for maximum compatibility with existing container images, but the number can be reduced. Never use UIDs or GIDs under 1000 or reuse UIDs or GIDs from existing user accounts (which, by default, start at 1000). Prerequisites The user account has been created. Procedure Run the usermod command to assign UIDs and GIDs to a user: The usermod --add-subuid command manually adds a range of accessible user IDs to the user's account. The usermod --add-subgids command manually adds a range of accessible user GIDs and group IDs to the user's account. Verification Check that the UIDs and GIDs are set properly: 1.8. Special considerations for rootless containers There are several considerations when running containers as a non-root user: The path to the host container storage is different for root users ( /var/lib/containers/storage ) and non-root users ( USDHOME/.local/share/containers/storage ). Users running rootless containers are given special permission to run as a range of user and group IDs on the host system. However, they have no root privileges to the operating system on the host. If you change the /etc/subuid or /etc/subgid manually, you have to run the podman system migrate command to allow the new changes to be applied. If you need to configure your rootless container environment, create configuration files in your home directory ( USDHOME/.config/containers ). Configuration files include storage.conf (for configuring storage) and containers.conf (for a variety of container settings). You could also create a registries.conf file to identify container registries that are available when you use Podman to pull, search, or run images. There are some system features you cannot change without root privileges. For example, you cannot change the system clock by setting a SYS_TIME capability inside a container and running the network time service ( ntpd ). You have to run that container as root, bypassing your rootless container environment and using the root user's environment. For example: Note that this example allows ntpd to adjust time for the entire system, and not just within the container. A rootless container cannot access a port numbered less than 1024. Inside the rootless container namespace it can, for example, start a service that exposes port 80 from an httpd service from the container, but it is not accessible outside of the namespace: However, a container would need root privileges, using the root user's container environment, to expose that port to the host system: The administrator of a workstation can allow users to expose services on ports numbered lower than 1024, but they should understand the security implications. A regular user could, for example, run a web server on the official port 80 and make external users believe that it was configured by the administrator. This is acceptable on a workstation for testing, but might not be a good idea on a network-accessible development server, and definitely should not be done on production servers. To allow users to bind to ports down to port 80 run the following command: Additional resources Shortcomings of Rootless Podman 1.9. Using modules for advanced Podman configuration You can use Podman modules to load a predetermined set of configurations. Podman modules are containers.conf files in the Tom's Obvious Minimal Language (TOML) format. These modules are located in the following directories, or their subdirectories: For rootless users: USDHOME/.config/containers/containers.conf.modules For root users: /etc/containers/containers.conf.modules , or /usr/share/containers/containers.conf.modules You can load the modules on-demand with the podman --module <your_module_name> command to override the system and user configuration files. Working with modules involve the following facts: You can specify modules multiple times by using the --module option. If <your_module_name> is the absolute path, the configuration file will be loaded directly. The relative paths are resolved relative to the three module directories mentioned previously. Modules in USDHOME override those in the /etc/ and /usr/share/ directories. Additional resources Upstream documentation 1.10. Additional resources A Practical Introduction to Container Terminology
subscription-manager register Registering to: subscription.rhsm.redhat.com:443/subscription Username: <username> Password: <password> subscription-manager attach --auto subscription-manager attach --pool <PoolID> dnf install container-tools dnf install podman-docker dnf install podman -y useradd -c "Joe Jones" joe passwd joe ssh joe@server.example.com podman pull registry.access.redhat.com/ubi9/ubi podman run --rm --name=myubi registry.access.redhat.com/ubi9/ubi cat /etc/os-release NAME="Red Hat Enterprise Linux" VERSION="9 (Plow)" usermod --add-subuids 200000-201000 --add-subgids 200000-201000 <username> grep <username> /etc/subuid /etc/subgid /etc/subuid: <username> :200000:1001 /etc/subgid: <username> :200000:1001 podman run -d --cap-add SYS_TIME ntpd podman run -d httpd podman run -d -p 80:80 httpd echo 80 > /proc/sys/net/ipv4/ip_unprivileged_port_start