Container runtimes
Syself Autopilot ships three runtime classes. A workload can select the runtimeclass that fits it. This page describes what each one is, when to use it, and how to set it.
What is a runtime class?
A RuntimeClass is a Kubernetes object that selects the runtime a pod runs on. Syself Autopilot ships three of them: standard, runc, and secure. A pod picks one with the runtimeClassName field, and a pod that sets nothing runs on standard. The three differ in the runtime behind them and in how far each pod is isolated from the node, from a shared kernel up to a private virtual machine.
Container runtimes
Each runtime class below lists what it is and a case where it fits.
standard
standard is the default runtime class. Behind it is crun, a lightweight OCI runtime written in C. Most Kubernetes clusters run runc, which is written in Go. Syself uses crun because it starts containers faster and uses less memory per container. It runs on every node type, cloud and bare metal, and a pod that sets no runtimeClassName uses it.
This covers the large majority of workloads, from stateless APIs and web servers to background workers and batch Jobs. Unless a workload has a specific reason to change, such as an image that misbehaves on crun or code that needs VM isolation, leave it on standard.
runc
runc is the reference OCI runtime, the one most Kubernetes clusters run by default. On Syself Autopilot it is a fallback. A small number of container images behave differently on crun, and runc exists for those cases. Like standard, it shares the node's kernel and runs on every node type.
Use runc when a specific image does not start or misbehaves under standard. A third-party image built and tested only against runc, for example, might fail on crun. Setting runtimeClassName: runc runs it on the runtime it expects, without changing anything else about the workload.
secure
secure runs each pod in its own lightweight virtual machine with its own kernel, using Kata Containers. If a process escapes the container it stays inside that VM and cannot reach the host or a neighbouring pod, even through a kernel-level bug. This is a stronger boundary than the shared-kernel runtimes, and it costs more, because each pod carries the VM's startup time and a fixed amount of CPU and memory overhead. Kata needs hardware virtualization (KVM), which on Hetzner exists only on bare-metal nodes , so secure pods do not schedule on cloud VMs. The runtime class carries its own node selector, so a secure pod with no capable node stays Pending instead of falling back to a shared kernel. A pod that sets hostNetwork: true or runs as privileged cannot use secure, since neither is compatible with the VM boundary.
Use secure for code you do not trust, or cannot afford to have escape onto the node. A platform that runs customer-supplied builds, or executes code its own users submit, can place each of those workloads on secure so a breakout is contained to its own VM instead of reaching the kernel that every other pod on the node shares.
Why crun is the default
Syself chose crun over runc, the more common default, for two reasons that show up at scale. crun is written in C rather than Go, so it starts containers faster, which shortens the gap between a pod being scheduled and its container running when you scale up. It also uses less memory per container, so each node keeps more memory free for your workloads. Both effects grow with the number of pods on a node, which is why crun is the cluster-wide default rather than something you opt into.
Select a runtime class
Select a runtime class per workload with the runtimeClassName field on the pod spec. A pod that sets nothing runs on standard, so you set this field only to switch to runc or secure.
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
replicas: 2
selector:
matchLabels:
app: app
template:
metadata:
labels:
app: app
spec:
runtimeClassName: secure # standard (default), runc, or secure
containers:
- name: app
image: nginx:stable
Secure runtime requirements and overhead
secure schedules only on bare-metal nodes with hardware virtualization, and adds roughly 250m CPU and 160Mi memory of VM overhead per pod on top of the container's own requests. Account for that when you schedule workloads and set resource requests.
Related
Run virtual machines with KubeVirt
Run full virtual machines next to your containers with KubeVirt on bare-metal nodes, and plan for node churn so a VM disk backed by local NVMe survives.
Overview
The ways to isolate and harden a workload on Syself Autopilot, from a shared kernel up to a per-pod VM, and where to configure each one.