OCI containers
From the perspective of the System Administrator (SAs)
🧱 1. Foundational Concept
"OCI containers are a formalized, standardized way to run isolated processes on a Linux system, with predictable configuration and lifecycle semantics."
🔐 2. Parallels with Familiar Concepts
Traditional Concept | OCI Container Equivalent |
---|---|
chroot jail |
Filesystem isolation (rootfs ) |
cgroups |
Resource constraints |
namespaces |
Network, PID, IPC, and UTS isolation |
RPM/DEB packages | Image layers with filesystem diffs |
systemd service | Container runtime process lifecycle |
📦 3. OCI = Open Standard
OCI (Open Container Initiative) defines:
- Image Format – How container images are packaged and stored.
- Runtime Specification – How containers are executed from images (e.g., via
runc
). - Distribution Specification – How images are shared over registries (e.g.,
docker pull
/podman pull
).
"Think of OCI as the 'POSIX' for containers. It's what makes runtimes like Docker, Podman, and containerd interoperate cleanly."
🚀 4. Why It Matters to SAs
- Standardized Deployment: Build once, run anywhere across Docker, Kubernetes, CRI-O, etc.
- Immutable Infrastructure: Container images are versioned, reproducible, and verifiable.
- Lifecycle Integration: You can plug containers into
systemd
, CI/CD pipelines, or even CRON jobs. - Security Boundaries: SELinux/AppArmor, seccomp, and user namespaces offer defense-in-depth.
🛠 5. Common Tools Using OCI
- Docker/Podman: Build/run containers.
- containerd/cri-o: Runtime daemons used by Kubernetes.
- Kubernetes: Schedules and manages OCI-compliant containers.
🧪 6. Example Explanation
"An OCI container is just a process on the host that’s running in a constrained environment: a chrooted rootfs, with limited CPU/memory, no access to host PID or network unless configured. What makes it powerful is that the environment is described in a portable, declarative JSON file, and the image that backs it is versioned and shareable."
🧪 Hands-on: Running a Container with runc
Goal: Run
/bin/sh
from a busybox image inside a minimal OCI container usingrunc
.
🔧 1. Pre-reqs
sudo dnf install -y runc # or apt install runc
Make a working directory:
mkdir ~/runc-test && cd ~/runc-test
📦 2. Create a Root Filesystem
Extract it from the image (in cache else pulls it first):
mkdir -p rootfs
docker export $(docker create busybox) |tar -C rootfs -xvf -
🧾 3. Generate Default OCI Config
runc spec
config.json
This creates a file called config.json
. It’s the OCI Runtime Spec, describing how to run the container.
✏️ 4. Edit the config.json
Open in your favorite editor:
vi config.json
Change the following fields:
process.args
:"args": ["sh"]
Optional (to drop privileges):
"root": { "path": "rootfs", "readonly": false }
Optional (to set hostname):
"hostname": "runc-demo"
🚀 5. Run the Container
sudo runc run demo
You’ll be dropped into a shell (sh
) inside the container. You can confirm isolation:
hostname # should be "runc-demo"
ps # only shows minimal PID tree
ls / # comes from BusyBox
Type exit
to leave.
🧠 Summary
rootfs/
contains the filesystem.config.json
is the OCI Runtime Spec.runc run <container-id>
creates an isolated process from that spec.- Nothing about registries, Docker, or Kubernetes is required—this is bare-metal containerization.