Master the Art of Manual Container Creation in Linux : No Docker Needed
Introduction
Containerization has revolutionized how we develop, deploy, and manage applications, with Docker being one of the most popular tools in the space. However, containers are not dependent on Docker; they are a feature of the Linux kernel. In this blog, we’ll explore how to create a container manually in Linux without using Docker. Understanding the underlying mechanisms gives you a deeper appreciation for how containers work and offers flexibility in environments where Docker is not available or suitable.
Prerequisites
Before we begin, ensure you have a Linux system with root
or sudo
privileges. Additionally, you should have a basic understanding of Linux namespaces, control groups (cgroups), and chroot.
Key Concepts
Namespaces
Namespaces isolate the container's environment from the host system. The key namespaces we’ll use are:
UTS namespace: Isolates hostname and domain name.
PID namespace: Isolates process IDs.
Network namespace: Isolates network interfaces.
Mount namespace: Isolates filesystem mounts.
User namespace: Isolates user and group IDs.
Control Groups (cgroups)
Cgroups limit and prioritize resource usage (CPU, memory, disk I/O) for a collection of processes. This ensures that your container doesn’t consume more resources than allocated.
Chroot
Chroot changes the apparent root directory for a process, providing filesystem isolation.
Step-by-Step Guide to Creating a Container Manually
Step 1: Create a Root Filesystem
First, create a root filesystem for the container. You can use debootstrap
(Debian-based systems) or yum
/dnf
(Red Hat-based systems) to set up a minimal Linux environment.
mkdir /container
debootstrap --arch=amd64 focal /container http://archive.ubuntu.com/ubuntu/
This command sets up an Ubuntu Focal Fossa environment in the /container
directory.
Step 2: Set Up Namespaces
We will use the unshare
command to create and isolate namespaces. The following command isolates UTS, PID, network, and mount namespaces:
unshare --fork --pid --mount --net --uts /bin/bash
You are now inside a shell with isolated namespaces.
Step 3: Configure the Filesystem with Chroot
Next, use chroot
to change the root directory to the new filesystem we created:
chroot /container /bin/bash
This command changes the root to /container
and spawns a new Bash shell. You are now inside an isolated filesystem.
Step 4: Set Up the Hostname and Networking
Set a hostname for your container:
hostname container-1
To configure networking, you can either set up a virtual network interface using tools like ip
or brctl
or manually add entries to /etc/hosts
and /etc/resolv.conf
.
Step 5: Apply Resource Limits Using Cgroups
Create a cgroup for your container:
mkdir -p /sys/fs/cgroup/cpu/container
echo 50000 > /sys/fs/cgroup/cpu/container/cpu.cfs_quota_us
echo $$ > /sys/fs/cgroup/cpu/container/tasks
This limits the container’s CPU usage to 50%. You can similarly manage memory, I/O, and other resources.
Step 6: Start and Manage Processes in the Container
rom the isolated environment, you can now run processes that are separate from the host system:
/bin/bash
Any process you start here will be contained within the namespaces and cgroups you’ve set up.
Step 7: Clean Up
When done, exit the chroot environment and the namespaces:
exit
Unmount filesystems, delete cgroups, and clean up resources to ensure no leftover configurations.
Conclusion
Creating a container manually without Docker involves isolating the environment using Linux namespaces, restricting resources with cgroups, and isolating the filesystem using chroot. While Docker simplifies these steps, understanding how to create containers manually provides insight into the inner workings of containerization, allowing for more customized and granular control when needed.
This hands-on approach is valuable for those who want to delve deeper into Linux systems, develop custom container solutions, or work in environments where Docker is not viable.
Subscribe to my newsletter
Read articles from Mohammad Imran directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Mohammad Imran
Mohammad Imran
DevOps 👨💻 | Co-Founder & Community manager @ GrowInCommunity | AWS Community Builder | Open Source Advocate 🥑| Tech Blogger 👨💻| Cloud Computing | Cloud Native