Cloud Native 10 min read

Introduction to OCI: Image, Distribution, and Runtime Specifications in the Code‑to‑Container Workflow

This article explains the Open Container Initiative (OCI) standards—Image-spec, Distribution-spec, and Runtime-spec—detailing how code is built into OCI images, pushed to registries, and executed via Kubernetes components such as kubelet, containerd/CRI‑O, and runc or kata‑containers, ensuring portable, interoperable containers.

System Architect Go
System Architect Go
System Architect Go
Introduction to OCI: Image, Distribution, and Runtime Specifications in the Code‑to‑Container Workflow

OCI Introduction

In the evolution of containerization technology, OCI (Open Container Initiative) provides a set of standardized specifications that help unify container building, distribution, and execution.

OCI Image-spec : defines the structure of container images, ensuring they can be recognized and managed by various tools.

OCI Distribution-spec : defines how container images are distributed, guaranteeing that images can interact with image registries via a standardized HTTP API.

OCI Runtime-spec : defines the runtime standards for containers, ensuring a unified execution and lifecycle management.

The following sections combine a complete CICD pipeline from code to container to explain the specific role of each OCI specification.

From Code to Container

1. Code → OCI Image

After code integration, you can use docker , podman / buildah , or kaniko and other tools to build container images.

At this point, the OCI Image-spec plays an important role; it defines the composition of an image so that different tools can recognize and use the same image across platforms.

Because Docker has a strong industry influence, some practitioners mistakenly think an image is a Docker image, but in fact Docker is just one of many tools—any image built with any tool should be called an OCI image.

The OCI Image-spec defines that an image must contain at least:

• Manifest : metadata file describing the components of the image.

• Layers : stacked layers where each layer represents an incremental filesystem change.

• Configuration : config file describing environment variables, entrypoint, working directory, etc.

Let’s look at the structure of the busybox image:

The diagram shows the manifest metadata file, config file, and layer files are all present.

An image is essentially a collection of files and directories.

2. OCI Image → Registry

After the image is built, it needs to be pushed to an image registry. The OCI Distribution-spec defines how images are stored, pulled, and distributed in a registry via a standard HTTP API.

The OCI Distribution-spec ensures that different registries and clients can use a unified API for image distribution, allowing the use of public registries (e.g., Docker Hub) or private ones (e.g., Harbor).

3. Kube‑API‑Server → Kubelet → Containerd/CRI‑O

Once the image is uploaded, an application can be created or updated. All requests first go to the kube‑api‑server , then the scheduler assigns the Pod to a node, and the node’s kubelet handles the subsequent processing.

The kubelet communicates with components such as containerd or CRI‑O via the CRI gRPC interface, and those components download the image and create the container.

4. Containerd/CRI‑O → runc/Kata‑containers

Containerd and CRI‑O do not create or run containers directly; they interact with the OCI Runtime-spec and underlying execution tools runc or kata‑containers to perform the actual container launch.

runc is the most common container runtime, interacting directly with the Linux kernel using cgroups and namespaces. kata‑containers runs containers inside lightweight virtual machines, offering stronger isolation while still adhering to the OCI runtime-spec.

The OCI runtime-spec defines:

• Container configuration via a config.json file describing processes, mounts, hooks, resource limits, etc.

• Execution environment: how the image is unpacked into a filesystem bundle.

• Lifecycle: detailed steps from container creation to termination.

To view the OCI runtime-spec config.json for a running pod, you can:

• Locate the node where the pod runs and SSH into it.

• Use a CRI tool such as crictl ps to find the container ID.

• For containerd , the file is at /run/containerd/io.containerd.runtime.v2.task/k8s.io/<container-id>/config.json ; for CRI‑O it may be at /run/containers/storage/<container-id>/userdata/config.json .

I created a busybox container and its OCI runtime-spec config.json looks like the image below:

The OCI runtime-spec config.json is generated by containerd or CRI‑O from the Pod definition (commands, arguments, environment variables, resource limits, etc.) and the surrounding context.

Summary

From code to actual container execution, many components and standards work together tightly. This article focused on the three core OCI specifications— image‑spec , distribution‑spec , and runtime‑spec —which ensure container compatibility and portability across environments, embodying the meaning of the Open Container Initiative.

(Follow me for ad‑free technical content, no sensationalism.)

References

https://opencontainers.org/about/overview/

https://github.com/opencontainers/image-spec/blob/main/spec.md

https://github.com/opencontainers/runtime-spec/blob/main/spec.md

https://github.com/opencontainers/distribution-spec/blob/main/spec.md

https://github.com/opencontainers/runc

cloud-nativekubernetesContainerOCIdistribution-specimage-specruntime-spec
System Architect Go
Written by

System Architect Go

Programming, architecture, application development, message queues, middleware, databases, containerization, big data, image processing, machine learning, AI, personal growth.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.