Qingular

Extension Interfaces (CNI/CSI/CRI)

·CKAk8sPractice

The three major extension interfaces of Kubernetes: Container Network Interface (CNI), Container Storage Interface (CSI), and Container Runtime Interface (CRI), which are the core mechanisms enabling Kubernetes extensibility.

← Back to CKA Practice Index

Overview

Kubernetes achieves a pluggable, extensible architecture through three standard interfaces: CNI (Container Network Interface), CSI (Container Storage Interface), and CRI (Container Runtime Interface). These interfaces decouple core control logic from specific implementations, allowing clusters to flexibly choose networking, storage, and runtime solutions. The CKA exam requires understanding the role and common implementations of each interface.


1. Overview of the Three Interfaces

InterfaceFull NameRoleProblem Solved
CNIContainer Network InterfaceContainer networkingPod network connectivity and IP allocation
CSIContainer Storage InterfaceContainer storagePersistent storage volume management
CRIContainer Runtime InterfaceContainer runtimeContainer creation and lifecycle management
┌─────────────────────────────────────────────────┐
│                   Kubernetes                      │
│  ┌───────────────────────────────────────────┐   │
│  │          API Server / Controller           │   │
│  │              ────────                      │   │
│  │        CRI       │      CNI      CSI       │   │
│  │         │        │        │        │       │   │
│  │    ┌────▼────┐ ┌─▼────┐ ┌─▼──────┐        │   │
│  │    │containerd│ │Calico│ │  CSI   │        │   │
│  │    │  CRI-O   │ │Flannel│ │ Driver │        │   │
│  │    │          │ │Cilium │ │(AWS,EBS│        │   │
│  │    └─────────┘ └──────┘ │  ...)  │        │   │
│  └─────────────────────────┴─────────┘        │   │
└─────────────────────────────────────────────────┘

2. CNI -- Container Network Interface

2.1 Overview

CNI defines the specification for container network configuration. When a Pod is created, Kubelet calls the CNI plugin to assign an IP address, configure network interfaces and routing rules, and ensure inter-Pod network connectivity.

2.2 CNI Plugin Responsibilities

FunctionDescription
IP Address Management (IPAM)Assigns unique IP addresses to Pods
Network ConnectivityEnsures Pods on the same node and across nodes can communicate
Network PoliciesImplements NetworkPolicy access control (some plugins)
Service ProxySome CNI plugins integrate kube-proxy alternatives

2.3 Common CNI Plugin Comparison

PluginFeaturesNetwork ModeNetwork PolicyPerformance
CalicoFeature-rich, supports BGPPure L3 routing (vxlan/ipip/bgp)SupportedExcellent
FlannelSimple and easy, decent performanceOverlay (vxlan/host-gw)Not supportedModerate
CiliumeBPF-driven, high performanceeBPF (vxlan/direct)Supported (enhanced)Very high
WeaveSimple deployment, encrypted communicationOverlay (weave mesh)SupportedModerate
MultusMultiple network interfacesAdditional interfacesDepends on meta-plugin--

2.4 CNI Configuration

# CNI configuration directory
/etc/cni/net.d/

# View the currently used CNI plugin
ls /etc/cni/net.d/
cat /etc/cni/net.d/10-calico.conflist
cat /etc/cni/net.d/10-flannel.conflist

# CNI binary directory
/opt/cni/bin/
ls /opt/cni/bin/
# Common CNI binaries:
# bridge, host-local, loopback, portmap, bandwidth, tuning
# plus plugin-specific binaries (calico, flannel, cilium, etc.)

# View CNI version
/opt/cni/bin/bridge --version

2.5 CNI Configuration Example

{
  "cniVersion": "0.3.1",
  "name": "k8s-pod-network",
  "plugins": [
    {
      "type": "calico",
      "datastore_type": "kubernetes",
      "ipam": {
        "type": "calico-ipam",
        "assign_ipv4": "true",
        "assign_ipv6": "false"
      },
      "policy": {
        "type": "k8s"
      }
    },
    {
      "type": "portmap",
      "capabilities": {"portMappings": true}
    },
    {
      "type": "bandwidth",
      "capabilities": {"bandwidth": true}
    }
  ]
}

2.6 CNI Debugging Commands

# View Pod network interfaces
kubectl exec <pod-name> -- ip addr show
kubectl exec <pod-name> -- ip route

# View node network interfaces (usually bridges or routes created by CNI)
ip link show
ip route show

# View CNI plugin logs
# Calico
kubectl logs -n calico-system -l k8s-app=calico-node
# Flannel
kubectl logs -n kube-flannel -l app=flannel
# Cilium
kubectl logs -n kube-system -l k8s-app=cilium

# Test inter-Pod connectivity
kubectl exec pod-a -- ping <pod-b-ip>

# View IPAM allocation status
# Calico
calicoctl ipam show
# Cilium
cilium ip list

3. CSI -- Container Storage Interface

3.1 Overview

CSI defines a standard interface for storage systems, allowing Kubernetes to seamlessly integrate with various storage backends. With CSI, the Kubernetes core code does not need to include storage drivers for each cloud provider.

3.2 CSI Architecture Components

┌──────────────────────────────────────────────┐
│               Kubernetes Node                   │
│  ┌────────────────┐     ┌─────────────────┐   │
│  │   kubelet       │     │  CSI Driver     │   │
│  │  ────           │     │  ──────────     │   │
│  │  CSI Interface──┼─────┤  CSI Node       │   │
│  │                 │     │    Service      │   │
│  └────────────────┘     └────────┬────────┘   │
└──────────────────────────────────┼────────────┘
                                   │
┌──────────────────────────────────┼────────────┐
│         Control Plane            │            │
│  ┌────────────────┐     ┌───────▼────────┐   │
│  │  CSI Controller │     │  External      │   │
│  │  Sidecar        │     │  Provisioner   │   │
│  │  (Attacher,     │     │  (Storage      │   │
│  │   Resizer,      │     │   Backend)     │   │
│  │   Snapshotter)  │     │                │   │
│  └────────────────┘     └────────────────┘   │
└──────────────────────────────────────────────┘

3.3 CSI Core Components

ComponentSidecarFunction
Provisionercsi-provisionerWatches PVCs and automatically creates storage volumes
Attachercsi-attacherMounts storage volumes to nodes
Resizercsi-resizerResizes storage volumes online
Snapshottercsi-snapshotterCreates and manages volume snapshots
DriverCore driverActually communicates with the storage backend (binary)
Node Driver Registrarnode-driver-registrarRegisters the CSI driver with kubelet

3.4 Common CSI Drivers

Storage TypeCSI DriverUse Case
AWS EBSebs.csi.aws.comAWS block storage
AWS EFSefs.csi.aws.comAWS file storage
GCE PDpd.csi.storage.gke.ioGoogle Cloud persistent disk
Azure Diskdisk.csi.azure.comAzure managed disk
NFSnfs.csi.k8s.ioGeneral-purpose NFS shared storage
Ceph/Rookrook-ceph.cephfs.csi.ceph.comCeph distributed storage
Longhorndriver.longhorn.ioRancher lightweight distributed storage
HostPathBuilt-in (non-CSI)Local storage (testing only)

3.5 StorageClass Example Using CSI

# StorageClass using a CSI driver
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ebs-sc
provisioner: ebs.csi.aws.com
parameters:
  type: gp3
  fsType: ext4
  encrypted: "true"
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
reclaimPolicy: Delete
# View CSI drivers in the cluster
kubectl get csidrivers

# View detailed information about a CSI driver
kubectl describe csidriver ebs.csi.aws.com

# View cluster StorageClasses
kubectl get storageclass
kubectl describe storageclass ebs-sc

# View CSI controller Pods
kubectl get pods -n kube-system | grep csi

# View PV driver information
kubectl get pv -o yaml | grep -A5 "csi:"

4. CRI -- Container Runtime Interface

4.1 Overview

CRI is the interface protocol between kubelet and the container runtime. It allows kubelet to communicate with any CRI-compliant runtime through a standard gRPC API, without directly depending on Docker or other specific runtimes.

4.2 CRI Architecture

┌─────────────────────┐
│      kubelet        │
│    ──────────       │
│    gRPC Client      │
│    CRI API          │
└────────┬────────────┘
         │ gRPC (unix socket)
         ▼
┌─────────────────────┐
│   CRI Shim/Service  │
│  ────────────────   │
│   containerd        │
│   CRI-O             │
│   Docker via cri-dockerd │
└────────┬────────────┘
         │
         ▼
┌─────────────────────┐
│    Container         │
│    (runc / gVisor /  │
│     Kata Containers) │
└─────────────────────┘

4.3 CRI Runtime Comparison

RuntimeFeaturesSocket PathStatus
containerdLightweight, high performance, Kubernetes defaultunix:///var/run/containerd/containerd.sockRecommended
CRI-OOptimized specifically for Kubernetesunix:///var/run/crio/crio.sockStable
Docker (cri-dockerd)Legacy solution, requires adapterunix:///var/run/cri-dockerd.sockDeprecated
gVisorSandbox isolation, enhanced securityunix:///var/run/gvisor/gvisor.sockSpecial scenarios
Kata ContainersLightweight VM-level isolationunix:///var/run/kata-containers/kata.sockSpecial scenarios

4.4 Common CRI Operation Commands

# Use crictl to manage containers (recommended)
crictl version
crictl info

# View containers
crictl ps
crictl ps -a              # Including stopped
crictl ps --name nginx    # Filter by name

# View images
crictl images
crictl images -v

# Pull/remove images
crictl pull nginx:latest
crictl rmi nginx:latest

# View Pods
crictl pods
crictl pods --name nginx

# View container logs
crictl logs <container-id>
crictl logs -f <container-id>  # Live logs

# Execute commands
crictl exec -it <container-id> /bin/sh

# View container stats
crictl stats

# View detailed container information
crictl inspect <container-id>
crictl inspectp <pod-id>

# Configure crictl
cat /etc/crictl.yaml
# runtime-endpoint: unix:///var/run/containerd/containerd.sock
# image-endpoint: unix:///var/run/containerd/containerd.sock
# timeout: 10
# debug: false

4.5 Viewing CRI Configuration

# View the CRI configuration used by kubelet
kubectl get nodes -o json | jq '.items[].status.nodeInfo.containerRuntimeVersion'

# View containerd configuration
cat /etc/containerd/config.toml

# View CRI-O configuration
cat /etc/crio/crio.conf

# View kubelet CRI socket configuration
ps aux | grep kubelet | grep container-runtime-endpoint
# or
cat /var/lib/kubelet/kubeadm-flags.env

5. Summary of How the Three Interfaces Work

Pod Creation Flow (involving the three interfaces):

1. API Server creates the Pod
2. Scheduler assigns it to a node
3. kubelet receives the Pod creation request
   │
   ├── CRI (Container Runtime)
   │    └── Creates the container via containerd/CRI-O
   │
   ├── CNI (Network)
   │    └── Calls CNI plugin to assign IP address, configure network
   │
   └── CSI (Storage, if PVC present)
        └── Mounts the storage volume via CSI driver

CKA Exam Key Points

  1. CRI: crictl commands -- In the exam, use crictl instead of docker commands to manage containers
  2. CRI Socket configuration -- kubelet specifies the socket via --container-runtime-endpoint
  3. CNI configuration directories -- Know the two directories: /etc/cni/net.d/ and /opt/cni/bin/
  4. CSI resource objects -- Understand the relationships between StorageClass, PV, PVC, and CSIDriver
  5. Common plugin names -- Calico, Flannel, Cilium (CNI); Ceph/Rook, Longhorn (CSI); containerd, CRI-O (CRI)

🧪 Complete Hands-on Example: Verifying Cluster CNI/CSI/CRI Configuration

Scenario Description

In a running cluster, inspect the currently used CNI network plugin, CSI storage driver, and CRI container runtime, mastering the troubleshooting methods for the three extension interfaces.

Prerequisites

  • A running Kubernetes cluster
  • kubectl configured and able to access the cluster
  • Node sudo access (optional)

Steps

Step 1: Check CRI container runtime

# View the container runtime used by the node
kubectl get nodes -o jsonpath='{.items[*].status.nodeInfo.containerRuntimeVersion}'
# containerd://1.7.x

# View kubelet's CRI socket configuration
cat /var/lib/kubelet/kubeadm-flags.env
# KUBELET_KUBEADM_ARGS="--container-runtime-endpoint=unix:///var/run/containerd/containerd.sock ..."

# Use crictl to view container runtime info
sudo crictl info | grep -E "runtimeName|runtimeVersion"
# "runtimeName": "containerd"
# "runtimeVersion": "1.7.x"

# View crictl configuration
cat /etc/crictl.yaml
# runtime-endpoint: unix:///var/run/containerd/containerd.sock
# image-endpoint: unix:///var/run/containerd/containerd.sock

Step 2: Check CNI network plugin

# View CNI plugin Pods (different CNIs are in different namespaces)
kubectl get pods --all-namespaces | grep -E "calico|flannel|cilium|weave"
# calico-system   calico-node-xxxxx                 1/1     Running   0   1h
# calico-system   calico-kube-controllers-xxxxx      1/1     Running   0   1h

# View CNI configuration directory
ls /etc/cni/net.d/
# 10-calico.conflist

# View CNI configuration details
cat /etc/cni/net.d/10-calico.conflist
# {
#   "name": "k8s-pod-network",
#   "cniVersion": "0.3.1",
#   "plugins": [
#     { "type": "calico", ... },
#     { "type": "portmap", ... }
#   ]
# }

# View CNI binary files
ls /opt/cni/bin/
# bandwidth  bridge  calico  calico-ipam  flush  host-local  loopback  portmap  tuning

Step 3: Check CSI driver

# View registered CSI drivers
kubectl get csidrivers
# NAME                          ATTACHREQUIRED   PODINFOONMOUNT   MODES        AGE
# ebs.csi.aws.com               true             false            Persistent   30d

# View StorageClasses in the cluster
kubectl get storageclass
# NAME            PROVISIONER                    RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
# ebs-sc          ebs.csi.aws.com                Delete          WaitForFirstConsumer   true                   30d
# standard        kubernetes.io/gce-pd           Delete          Immediate             false                  30d

# View CSI controller Pods
kubectl get pods -n kube-system | grep csi
# ebs-csi-controller-xxxxxxxxx-xxxxx       6/6     Running   0   30d
# ebs-csi-node-xxxxx                       3/3     Running   0   30d

# View CSI driver details
kubectl describe csidriver ebs.csi.aws.com

Step 4: Verify Pod networking and storage

# View Pod network interfaces
kubectl run net-test --image=busybox --rm -it --restart=Never -- ip addr show
# 1: lo: <LOOPBACK> ...
# 2: eth0@if...: <BROADCAST,MULTICAST,UP,LOWER_UP> ... inet 192.168.1.5/32  <-- IP assigned by CNI

# Check if a Pod has CSI-mounted volumes
kubectl get pod <pod-with-pvc> -o json | jq '.spec.volumes[] | select(.csi != null)'
# {
#   "name": "data",
#   "csi": {
#     "driver": "ebs.csi.aws.com",
#     "volumeHandle": "vol-xxxxxxxxx"
#   }
# }

Verification

# Summarize the status of the three interfaces
echo "=== CRI Runtime ==="
kubectl get nodes -o jsonpath='{.items[*].status.nodeInfo.containerRuntimeVersion}'
echo ""
echo "=== CNI Plugins ==="
ls /opt/cni/bin/ | tr '\n' ' '
echo ""
echo "=== CSI Drivers ==="
kubectl get csidrivers -o name

Exam Tips

  • CRI: Use crictl commands to manage containers (similar to docker), crictl ps, crictl images, crictl logs
  • CNI: Configuration in /etc/cni/net.d/ (config files), binaries in /opt/cni/bin/
  • CSI: Use kubectl get csidrivers to view registered drivers, referenced in the StorageClass provisioner field
  • When troubleshooting network issues, first confirm CNI Pods are running normally: kubectl get pods -n calico-system
  • When troubleshooting storage issues, follow this order: StorageClass -> PVC -> PV -> CSI Driver

Official Documentation