A Deep Dive into Containerization with Buildah: Building OCI Containers Efficiently

Posted by Andrew Denner on November 22, 2024 · 12 mins read

This post is created from a presentation I originally gave to the St Louis Linux Users Group My slide deck and Video

A Deep Dive into Containerization with Buildah: Building OCI Containers Efficiently

By Andrew Denner

Table of Contents

  1. Introduction
  2. Understanding Containerization
  3. The Evolution of Containerization Tools
  4. Exploring Buildah
  5. Getting Started with Buildah
  6. Building OCI Containers with Buildah
  7. Security Considerations
  8. Podman and Buildah Integration
  9. Challenges and Workarounds
  10. Conclusion

Introduction

In the ever-evolving landscape of software development and deployment, containerization has emerged as a pivotal technology. It offers a solution to the age-old problem of inconsistent environments across different stages of development, testing, and production. Among the plethora of tools available, Buildah stands out as a powerful utility for building Open Container Initiative (OCI) compliant images without the need for a container daemon.

In this blog post, we’ll delve deep into Buildah, how it compares to other tools like Docker and Podman, and explore detailed examples to help you efficiently build and manage your OCI containers.

Understanding Containerization

Containerization encapsulates an application and its dependencies into a single package, ensuring consistency across different environments. It abstracts the operating system’s kernel and provides a lightweight, portable environment for applications to run consistently.

Containers vs. Virtual Machines

Before diving into containers, it’s essential to understand how they differ from virtual machines (VMs).

Virtual Machines:

  • Isolation: VMs encapsulate the entire operating system, including the kernel. Each VM runs on a hypervisor, which virtualizes the hardware.
  • Resource Intensive: VMs are heavyweight since they replicate the hardware and OS layers. This means more resources are required per VM.
  • Portability: While VMs are portable, moving them can be resource-intensive due to their size.

Containers:

  • Isolation: Containers share the host OS kernel but have isolated user spaces. This means they are more lightweight compared to VMs.
  • Resource Efficient: Since they share the host kernel, they consume fewer resources, allowing for higher density on the same hardware.
  • Portability: Containers are highly portable across environments that support the container runtime.

The Evolution of Containerization Tools

Docker

Docker revolutionized containerization by making it accessible and user-friendly. It introduced:

  • Easy Image Building: Using Dockerfile scripts.
  • Docker Daemon: A background service managing containers.
  • Docker Hub: A centralized registry for container images.

However, over time, Docker Inc. made changes that included licensing adjustments and feature limitations, which led the open-source community to seek alternatives.

Kubernetes

Kubernetes is an orchestration platform that automates container deployment, scaling, and management across clusters. It became the de-facto standard for managing containerized applications at scale. Kubernetes abstracts containers into units called “pods” and provides advanced features like load balancing, rollouts, and rollbacks.

Podman and Buildah

Podman and Buildah emerged from the need for Docker alternatives that address specific concerns:

  • Daemonless Operation: Unlike Docker, both Podman and Buildah do not require a running daemon.
  • Rootless Containers: They support running containers without root privileges, enhancing security.
  • Compatibility: Podman aims to be Docker-compatible, allowing users to transition with minimal changes.

Exploring Buildah

Buildah is a command-line tool that facilitates building OCI-compliant container images. It focuses exclusively on image building, separating the concerns of image creation and container management.

Why Use Buildah?

  • Daemonless: No need for a background service, reducing overhead and potential security risks.
  • Rootless Builds: Build images without root privileges.
  • Scripting Flexibility: Use shell scripts and Buildah commands to construct images, providing more control than traditional Dockerfiles.
  • Integration: Works seamlessly with Podman for running and managing containers.

Buildah vs. Docker Build

  • Daemonless Operation:
    • Docker Build: Requires the Docker daemon.
    • Buildah: Doesn’t require a daemon.
  • Root Privileges:
    • Docker Build: Typically operates with root privileges due to the daemon.
    • Buildah: Supports rootless operation.
  • Scripting:
    • Docker Build: Uses Dockerfile.
    • Buildah: Can use Dockerfile or Buildah commands in scripts for more granular control.

Getting Started with Buildah

Installation

On Fedora/CentOS/RHEL:

sudo dnf install buildah

On Ubuntu/Debian:

Since Buildah is included in the repositories for newer versions:

sudo apt update
sudo apt install buildah

For older versions, you may need to add the PPA:

sudo apt update
sudo apt install software-properties-common
sudo add-apt-repository ppa:projectatomic/ppa
sudo apt update
sudo apt install buildah

On Windows:

Buildah can be used within WSL (Windows Subsystem for Linux). Ensure you have WSL2 installed with a supported Linux distribution and proceed with installation as per the Linux instructions.

Building OCI Containers with Buildah

Let’s explore building a container image using Buildah with a practical example.

Example: Building a Rust Application Container

We’ll build a simple Rust “Hello, World!” application and containerize it.

Prerequisites:

  • Rust installed on your system (rustc and cargo).
  • Buildah installed.

Step 1: Create a Rust Application

cargo new hello_world
cd hello_world

Edit src/main.rs if necessary. It should look like:

fn main() {
    println!("Hello, world!");
}

Step 2: Write a Dockerfile (Optional)

While Buildah can work without a Dockerfile, we’ll use one for familiarity.

# Stage 1: Builder
FROM rust:1.65 as builder
WORKDIR /app
COPY . .
RUN cargo build --release

# Stage 2: Runner
FROM debian:buster-slim
COPY --from=builder /app/target/release/hello_world /usr/local/bin/hello_world
CMD ["hello_world"]

Step 3: Build the Image with Buildah

buildah bud -t hello_world:latest .
  • bud is Buildah’s equivalent of docker build.
  • -t tags the image.

Step 4: Run the Container with Podman

podman run --rm hello_world:latest

You should see:

Hello, world!

Step 5: Rootless Operation

Ensure that you can build and run containers without root privileges.

buildah unshare ./build.sh

Multi-Stage Builds with Buildah

Multi-stage builds help reduce the final image size by separating the build environment from the runtime environment.

Explanation

In our example, the first stage (builder) compiles the Rust application. The second stage uses a minimal base image (e.g., debian:buster-slim) and only copies the compiled binary.

Benefits

  • Smaller Image Size: Only necessary files are included.
  • Reduced Attack Surface: Fewer packages mean fewer vulnerabilities.
  • Separation of Concerns: Build tools and dependencies are not present in the final image.

Squashing Layers

Buildah allows you to squash image layers, combining them into a single layer.

Why Squash Layers?

  • Security: Remove sensitive data from intermediate layers.
  • Size Reduction: Minimize the image size.
  • Clean History: Simplify the image history.

How to Squash Layers

After building your image:

buildah commit --squash $container $image_name

Alternatively, during the build:

buildah bud --squash -t $image_name .

Security Considerations

Security is paramount when building containers.

Reducing the Attack Surface

  • Use Minimal Base Images: Alpine Linux, Debian Slim, or scratch images.
  • Static Binaries: Compile applications statically to avoid runtime dependencies.
  • Regular Updates: Rebuild images frequently to include security patches.

Best Practices

  • Scan Images: Use tools like clair or trivy to scan for vulnerabilities.
  • Avoid Root: Use non-root users inside containers.
  • Limit Privileges: Use USER directives and avoid unnecessary capabilities.

Podman and Buildah Integration

Podman is a container runtime that works seamlessly with Buildah.

Benefits

  • Daemonless: No need for a daemon like the Docker daemon.
  • Rootless Containers: Enhanced security.
  • Docker-Compatible Commands: Many Docker commands work with Podman.

Example: Running a Buildah Image with Podman

podman run --rm hello_world:latest

Since Buildah produces OCI-compliant images, they are compatible with Podman.

Challenges and Workarounds

Docker Compose Compatibility

One of the challenges with moving away from Docker is compatibility with Docker Compose.

  • Current State: Docker Compose is tightly integrated with the Docker daemon.
  • Workaround: Use tools like podman-compose, but be aware of limitations.
  • Alternative: Transition to Kubernetes YAML files or use tools like kubectl for orchestration.

Command Syntax Differences

Buildah’s command-line syntax can be less intuitive compared to Docker commands.

  • Solution: Familiarize yourself with Buildah commands through practice and documentation.
  • Scripting: Automate complex commands using shell scripts.

Conclusion

Buildah offers a robust, secure, and efficient way to build OCI-compliant container images without the overhead of a container daemon. By leveraging Buildah and Podman together, developers can maintain a seamless workflow while enhancing security and control.

Transitioning to Buildah may come with challenges, especially concerning compatibility with Docker-centric tools. However, the benefits of a daemonless, rootless environment make it a compelling choice for modern containerization needs.

References:

About the Author:

Andrew Denner is the president of the Central Iowa Linux Users Group and a senior scientific software developer. With a passion for Linux and containerization technologies, he actively explores and shares knowledge about efficient software development and deployment practices.

Feel free to reach out with questions or share your experiences using Buildah and Podman!