How Containerd ShimV2 Simplifies Integrating Kata Containers with Kubernetes
This article explains the challenges of CRI integration with multiple container runtimes, introduces Containerd ShimV2 as a standardized interface, and provides step‑by‑step instructions for configuring Kata Containers as a Kubernetes runtime using RuntimeClass or untrusted_workload_runtime methods.
Introduction
From the article "CRI shim: how kubelet interacts with container runtimes (Part 1)" we learned three key points:
CRI is designed for Kubernetes, not OCI, so integrating VM‑based runtimes such as gVisor or Kata Containers often mismatches CRI assumptions and APIs.
Maintaining many CRI implementations (e.g., RedHat's cri‑o, containerd) is difficult because they all ultimately rely on runC, requiring separate shims for each runtime.
Multiple container runtimes serve different purposes, for example using a virtualized engine for untrusted or multi‑tenant workloads while using Docker for system components that cannot be virtualized.
These issues motivate the creation of Containerd ShimV2.
Containerd ShimV2
In 2018, the containerd community introduced the shimv2 API, which builds on CRI to provide a more mature and convenient way for users to integrate their own container runtimes.
ShimV2 adds a standardized layer between the CRI shim and the underlying Containerd runtime. Instead of a direct CRI → Containerd → runC path, the flow becomes CRI → Containerd → ShimV2 → (runC | Kata Container).
The main advantage is that each Pod can specify its own Shim. Containerd now starts or stops a ShimV2 instance, and the implementation of these start/stop operations is left to the developer.
For example, a Kata Containers maintainer can launch a Containerd Shim when creating a sandbox, then reuse that sandbox for subsequent container operations, eliminating the need to start a new shim for each container.
In practice, you keep the original CRI Containerd (using runC) and add a Kata Container shim implementation (kata‑Containerd‑Shimv2) on top.
Providing kata-runtime to Kubernetes
To run containers with kata-runtime, you must first install Kata on each node and then tell Kubernetes which workloads should use it. The steps below assume a CentOS system.
<code>$ source /etc/os-release
$ yum -y install yum-utils
$ ARCH=$(arch)
$ BRANCH="${BRANCH:-master}"
$ yum-config-manager --add-repo "http://download.opensuse.org/repositories/home:/katacontainers:/releases:/${ARCH}:/${BRANCH}/CentOS_${VERSION_ID}/home:katacontainers:releases:${ARCH}:${BRANCH}.repo"
$ yum -y install kata-runtime kata-proxy kata-shim
</code>Verify hardware requirements (e.g., Intel VT‑x, ARM Hyp mode, IBM Power, IBM Z) and run the check command:
<code>$ kata-runtime kata-check
System is capable of running Kata Containers
System can currently create Kata Containers
</code>Install a Kubernetes cluster with kubeadm, then generate the default containerd configuration:
<code>containerd config default > /etc/containerd/config.toml
</code>Two methods can expose Kata to Kubernetes:
RuntimeClass – requires specific versions (Kata v1.5.0+, containerd v1.2.0+, Kubernetes v1.12.0+). Add the following to
config.toml:
<code>[plugins.cri.containerd]
no_pivot = false
[plugins.cri.containerd.runtimes]
[plugins.cri.containerd.runtimes.runc]
runtime_type = "io.containerd.runc.v1"
[plugins.cri.containerd.runtimes.runc.options]
NoPivotRoot = false
NoNewKeyring = false
ShimCgroup = ""
IoUid = 0
IoGid = 0
BinaryName = "runc"
Root = ""
CriuPath = ""
SystemdCgroup = false
[plugins.cri.containerd.runtimes.kata]
runtime_type = "io.containerd.kata.v2"
[plugins.cri.containerd.runtimes.katacli]
runtime_type = "io.containerd.runc.v1"
[plugins.cri.containerd.runtimes.katacli.options]
NoPivotRoot = false
NoNewKeyring = false
ShimCgroup = ""
IoUid = 0
IoGid = 0
BinaryName = "/usr/bin/kata-runtime"
Root = ""
CriuPath = ""
SystemdCgroup = false
</code>The
kataentry becomes the RuntimeClass handler.
untrusted_workload_runtime – for environments that do not meet the version requirements, add:
<code>[plugins.cri.containerd.untrusted_workload_runtime]
runtime_type = "io.containerd.runtime.v1.linux"
runtime_engine = "/usr/bin/kata-runtime"
</code>After editing, reload and restart containerd:
<code>$ systemctl daemon-reload
$ systemctl restart containerd
</code>Method 1: RuntimeClass
<code>kind: RuntimeClass
apiVersion: node.k8s.io/v1beta1
metadata:
name: kata-containers
handler: kata
</code>Create a pod that uses the RuntimeClass:
<code>apiVersion: v1
kind: Pod
metadata:
name: kata-nginx
spec:
runtimeClassName: kata-containers
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
</code> <code>$ kubectl apply -f kata-pod.yaml
$ kata-runtime list
</code>Method 2: untrusted_workload_runtime
Annotate the pod to request an untrusted workload:
<code>annotations:
io.kubernetes.cri.untrusted-workload: "true"
</code>Example pod definition:
<code>apiVersion: v1
kind: Pod
metadata:
name: kata-nginx-untrusted
annotations:
io.kubernetes.cri.untrusted-workload: "true"
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
</code> <code>$ kubectl apply -f kata-pod-untrusted.yaml
$ kata-runtime list
</code>Conclusion
Kubernetes achieves extensibility by modularizing core features through interfaces and plugins. CRI was the first successful plugin interface, and building on it, Containerd ShimV2 offers a new integration path for custom runtimes.
With ShimV2 you no longer need to write a full CRI shim for each runtime; you can reuse containerd’s CRI support and implement only the ShimV2 layer.
This approach has become the community’s mainstream way to connect lightweight or virtualized runtimes such as Kata Containers, gVisor, and Firecracker to Kubernetes.
References
https://blog.csdn.net/yuchunyu97/article/details/109241723 https://github.com/kata-containers/documentation/blob/master/install/centos-installation-guide.md https://ustack.io/2019-11-21-container%E7%9B%B8%E5%85%B3%E6%A6%82%E5%BF%B5%E6%A2%B3%E7%90%86.html https://github.com/kata-containers/documentation/blob/master/how-to/how-to-use-k8s-with-cri-containerd-and-kata.md https://github.com/kubernetes/kubernetes/issues/73189 https://blog.zufardhiyaulhaq.com/kubernetes-with-cri-containerd-and-kata-containers/ https://www.chenshaowen.com/blog/how-to-integrate-kata-in-kubernetes-cluster.html
Ops Development Stories
Maintained by a like‑minded team, covering both operations and development. Topics span Linux ops, DevOps toolchain, Kubernetes containerization, monitoring, log collection, network security, and Python or Go development. Team members: Qiao Ke, wanger, Dong Ge, Su Xin, Hua Zai, Zheng Ge, Teacher Xia.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.