Kubernetes Container Runtime 筆記

Container Runtime

Container Runtime 是 K8s cluster 中負責管理並執行 container 的角色,每個 Node 都需要安裝 Container Runtime 才能夠執行 Pod。

常見的 Container Runtime 有 containerd、CRI-O 等。

Container Runtime Interface

Container Runtime Interface (CRI) 用來定義 kubelet 怎麼和 Container Runtime 溝通,讓 K8s 可以透過統一介面使用不同的 runtime。

CRI 本身是一份以 gRPC 定義的介面規範,runtime 必須實作相容的 CRI API,並在 Node 上完成設定,才能讓 K8s 使用。

補充:早期 K8s 透過內建的 dockershim 支援 Docker Engine,dockershim 負責將 CRI 請求轉接給 Docker Engine。從 v1.24 起移除了內建的 dockershim。

Container Sandbox

containerd 等 runtime 會透過底層 runtime 執行 container,常見的搭配是 runc。

為了加強 Node 中 workload 的隔離,發展出了 gVisor、Kata Containers 等 sandbox runtime。它們和 runc 的主要差別,在於隔離邊界,以及應用程式接觸 host kernel 的方式:runc 共用 host kernel,gVisor 在中間加入 application kernel,Kata Containers 則使用 VM 和獨立的 guest kernel。

而在 K8s 中可以透過 RuntimeClass,讓每個 Pod 選用不同的 runtime 設定。RuntimeClass 的 handler 對應到 Node 上 CRI runtime 已設定好的 handler。沒有指定 runtimeClassName 時,就使用預設 handler,實際使用哪個 runtime 取決於 Node 的設定。

建立 RuntimeClass 不會自動安裝 runtime,必須先在 Node 上安裝並設定好對應的 runtime。若只有部分 Node 支援,還需要透過 RuntimeClass 的 scheduling.nodeSelector 等排程設定,讓 Pod 被排到支援的 Node。

1
2
3
4
5
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: gvisor
handler: runsc # 對應 Node 上設定的 handler 名稱

Pod 可以這樣設定:

1
2
3
# Pod
spec:
runtimeClassName: gvisor

gVisor

gVisor 提供的 OCI runtime 叫做 runsc,其中處理應用程式 syscall 的 user-space kernel 叫做 Sentry。應用程式的 syscall 由 Sentry 攔截並處理,不會直接轉交給 host kernel;但 Sentry 本身仍會透過受限制的 syscall 使用 host 資源。

這樣可以減少應用程式直接接觸 host kernel 的攻擊面,代價是額外的處理成本與相容性限制,實際效能影響會依 workload 而不同。

Kata Containers

在 K8s 情境中,通常是一個 Pod 對應一台輕量 VM,同一個 Pod 裡的多個 container 共用這台 VM 與 guest kernel。透過硬體虛擬化增加一道隔離邊界,代價則是 VM 帶來的啟動時間與記憶體開銷,實際成本取決於設定和 workload。

runc

常見的 OCI runtime,透過 Linux namespaces 隔離資源視圖、cgroups 管理資源使用,container 直接共用 host kernel。沒有額外的 application kernel 或 VM 層,通常執行開銷較低,但應用程式也更直接接觸 host kernel 造成一些風險。

References


Kubernetes Container Runtime 筆記
https://weiblog.me/2026-09-23/2026-k8s-container-runtime-notes/
Author
wei
Posted on
September 23, 2026
Licensed under