CRI, CNI, and CSI in Kubernetes – Explained

🔍 Introduction

Kubernetes has become the cornerstone of container orchestration in modern cloud-native infrastructure. But behind its abstraction lies a powerful, modular architecture designed to work with pluggable components. Three key interfaces—CRI (Container Runtime Interface), CNI (Container Network Interface), and CSI (Container Storage Interface)—are critical to this modularity.

In this blog, we’ll explore why these interfaces were introduced, how they work, and provide real-world examples and diagrams to help you grasp their importance.

🎯 The Backstory: Why CRI, CNI, and CSI?

When Kubernetes was first introduced, it tightly integrated specific components like Docker for containers, custom scripts for networking, and in-tree volumes for storage. This created major challenges:

  • Vendor Lock-in: Kubernetes couldn’t easily integrate with other container runtimes or storage/network providers.
  • Tightly Coupled Code: Every new addition or change requires modifying the Kubernetes core code.
  • Maintenance Complexity: Supporting new storage or runtime systems meant rebuilding large parts of Kubernetes.

✨ The Solution: Standardized Interfaces

To solve these issues, the Kubernetes community introduced standardized interfaces:

  • CRI in Kubernetes 1.5 (2016)
  • CNI was adopted via CNCF from CoreOS
  • CSI was introduced in Kubernetes 1.9 and promoted to GA in 1.13

These interfaces allow Kubernetes to delegate responsibilities to external plugins that conform to a specification.

🧱 CRI – Container Runtime Interface

🔧 What is CRI?

CRI defines how the Kubernetes kubelet communicates with a container runtime. It allows Kubernetes to use different runtimes like containerd, CRI-O instead of being locked to Docker.

🧪 Example

Let’s say you’re using containerd instead of Docker. The kubelet talks to containerd using the CRI gRPC protocol to:

  • Pull images
  • Create/stop containers
  • Manage pods

🧠 Architecture

Kubelet
|
└──> CRI gRPC API
├──> RuntimeService (createPodSandbox, startContainer, etc.)
└──> ImageService (pullImage, listImages)
|
containerd / CRI-O / any compliant runtime

🧯 Why CRI Matters

  • Docker deprecation in Kubernetes v1.20+ required a pluggable interface.
  • Encouraged ecosystem innovation (e.g., sandboxed runtimes, WASM).

🌐 CNI – Container Network Interface

🔧 What is CNI?

CNI is a standard for configuring networking for Linux containers. It’s how Kubernetes assigns IP addresses to pods, sets up routing, and enables communication between pods and services.

🧪 Example

You install Calico CNI in your cluster. Now, when a pod is scheduled:

  • Kubernetes asks Calico to set up a network namespace.
  • Calico assigns an IP, sets routes, and applies network policies.

🧠 Architecture

Kubelet
└──> Calls CNI plugin (e.g., Calico, Flannel)
├──> Creates veth pair (one in pod, one in host)
├──> Assigns IP from subnet
└──> Updates routing and iptables

🧯 Why CNI Matters

  • Allows you to choose the networking model: flat, overlay, or policy-based.
  • Makes it easy to support things like multi-tenancy, network policies, and encryption.
  • Plug-and-play architecture (just swap the CNI plugin).

📦 CSI – Container Storage Interface

🔧 What is CSI?

CSI is a standardized interface for storage vendors to expose volumes to Kubernetes. It replaces the older “in-tree” volume plugins (like AWS EBS, GCE PD, etc.).

🧪 Example

You’re using AWS. You install the EBS CSI driver. When your pod mounts a PVC:

  • Kubernetes asks the EBS CSI driver to create and attach a volume.
  • The volume is mounted inside the pod at runtime.

🧠 Architecture

Pod requests volume -> PVC -> StorageClass (uses CSI driver)
|
Kubelet calls CSI driver via gRPC
├──> CreateVolume
├──> AttachVolume
├──> MountVolume
└──> UnmountVolume

🧯 Why CSI Matters

  • No more hardcoded volume support inside Kubernetes.
  • Dynamic provisioning, resizing, and snapshotting are supported natively.
  • Encourages innovation from storage vendors.

📊 Comparison Table

InterfaceFull FormScopePurposePopular Implementations
CRIContainer Runtime InterfaceComputeRun and manage containerscontainerd, CRI-O
CNIContainer Network InterfaceNetworkingConfigure networking for podsCalico, Flannel, Cilium
CSIContainer Storage InterfaceStorageAttach and manage storage volumesAWS EBS, OpenEBS

Kubernetes is powerful because it lets others do the heavy lifting:

  • CRI talks to container runtimes.
  • CNI handles all network wiring.
  • CSI manages external storage.

By breaking things into clean interfaces, Kubernetes became a modular, extensible, and cloud-native superhero.

🧩 Visualizing the Whole Picture

Here’s how all three interfaces fit together in a Kubernetes node:

cri-cni-csi

🧠 Final Thoughts

In order to liberate Kubernetes from monolithic architecture and let it grow and develop in a plugin-powered, vendor-neutral ecosystem, CRI, CNI, and CSI were created out of necessity. These interfaces now serve as the foundation of Kubernetes’ flexibility, scalability, and popularity.

You can design better infrastructure and embrace new technologies more quickly if you understand these interfaces, whether you’re creating a cluster from scratch or debugging production issues.

📚 Read More

Enjoyed this post? You can check out more Kubernetes stories and deep dives on
👉 techyen.com/kubernetes

Share

Subscribe to our Newsletter

Please susbscribe

Leave a Comment

×