diff --git a/docs/design/architecture_4.0/README.md b/docs/design/architecture_4.0/README.md index e108d570c4..3f2b6322cc 100644 --- a/docs/design/architecture_4.0/README.md +++ b/docs/design/architecture_4.0/README.md @@ -12,7 +12,48 @@ By consolidating the entire runtime into a single, high-performance binary, Kata The Kata Containers Rust Runtime is designed to minimize resource overhead and startup latency. It achieves this by shifting from traditional process-based management to a more integrated, Rust-native control flow. -![architecture](./images/kata4.0-arch.png) +```mermaid +graph TD + containerd["containerd"] --> shimv2["containerd-shim-kata-v2 (shimv2)"] + + subgraph BuiltIn["Built-in VMM (Integrated Mode)"] + direction TD + subgraph shimv2_bi["shimv2 process (Single Process)"] + runtime_bi["shimv2 runtime"] + subgraph dragonball["Dragonball VMM (library)"] + helpers_bi["virtiofs / nydus\n(BuiltIn)"] + end + runtime_bi -->|"direct function calls"| dragonball + end + subgraph guestvm_bi["Guest VM"] + agent_bi["kata-agent"] + end + shimv2_bi -->|"hybrid-vsock"| guestvm_bi + end + + subgraph OptionalVMM["Optional VMM (External Mode)"] + direction TD + shimv2_ext["shimv2 process"] + imagesrvd_ext["virtiofsd / nydusd\n(Independent Process)"] + ext_vmm["External VMM process\n(QEMU / Cloud-Hypervisor / Firecracker)"] + subgraph guestvm_ext["Guest VM"] + agent_ext["kata-agent"] + end + shimv2_ext -->|"fork + IPC/RPC"| ext_vmm + shimv2_ext -->|"manages"| imagesrvd_ext + ext_vmm -->|"vsock / hybrid-vsock"| guestvm_ext + end + + shimv2 --> BuiltIn + shimv2 --> OptionalVMM + + classDef process fill:#d0e8ff,stroke:#336,stroke-width:1px + classDef vm fill:#d4edda,stroke:#155724,stroke-width:1px + classDef agent fill:#fff3cd,stroke:#856404,stroke-width:1px + class shimv2,runtime_bi,shimv2_ext,helpers_bi,imagesrvd_ext,ext_vmm process + class guestvm_bi,guestvm_ext vm + class agent_bi,agent_ext agent +``` The runtime employs a **flexible VMM strategy**, supporting both `built-in` and `optional` VMMs. This allows users to choose between a tightly integrated VMM (e.g., Dragonball) for peak performance, or external options (e.g., QEMU, Cloud-Hypervisor, Firecracker) for enhanced compatibility and modularity. @@ -56,9 +97,55 @@ In this mode, the runtime and the VMM operate as separate, decoupled processes. The legacy Kata 2.x architecture relied on inter-process communication (IPC) between the runtime and the VMM. This introduced context-switching latency and complex error-recovery requirements across process boundaries. In contrast, the built-in VMM approach embeds the VMM directly within the runtime's process space. This eliminates IPC overhead, allowing for direct function calls and shared memory access, resulting in significantly reduced startup times and improved performance. -![not_builtin_vmm](./images/not_built_in_vmm.png) +```mermaid +graph LR + subgraph HostProcess["Host Process:containerd-shim-kata-v2 (shimv2)"] + shimv2["shimv2 runtime"] + end -![builtin_vmm](./images/built_in_vmm.png) + imagesrvd["virtiofsd / nydusd\n(Independent Process)"] + + subgraph ExtVMMProc["External VMM Process (e.g., QEMU)"] + vmm["VMM\n(QEMU / Cloud-Hypervisor\n/ Firecracker)"] + end + + subgraph GuestVM["Guest VM"] + agent["kata-agent"] + end + + shimv2 -->|"fork + IPC / RPC"| vmm + shimv2 -->|"manages"| imagesrvd + vmm -->|"vsock / hybrid-vsock"| GuestVM + + classDef proc fill:#d0e8ff,stroke:#336,stroke-width:1px + classDef vm fill:#d4edda,stroke:#155724,stroke-width:1px + classDef ag fill:#fff3cd,stroke:#856404,stroke-width:1px + class shimv2,imagesrvd,vmm proc + class agent ag +``` + +```mermaid +graph LR + subgraph SingleProcess["Single Process: containerd-shim-kata-v2 (shimv2)"] + shimv2["shimv2 runtime"] + subgraph dragonball["Dragonball VMM (library)"] + helpers["virtiofs / nydus\n(BuiltIn)"] + end + shimv2 -->|"direct function calls"| dragonball + end + + subgraph GuestVM["Guest VM"] + agent["kata-agent"] + end + + dragonball -->|"hybrid-vsock"| GuestVM + + classDef proc fill:#d0e8ff,stroke:#336,stroke-width:1px + classDef vm fill:#d4edda,stroke:#155724,stroke-width:1px + classDef ag fill:#fff3cd,stroke:#856404,stroke-width:1px + class shimv2,helpers proc + class agent ag +``` By integrating Dragonball directly as a library, we eliminate the need for heavy IPC. @@ -69,7 +156,65 @@ By integrating Dragonball directly as a library, we eliminate the need for heavy The Kata 4.0 runtime utilizes a highly modular, layered architecture designed to decouple high-level service requests from low-level infrastructure execution. This design facilitates extensibility, allowing the system to support diverse container types and dragonball within a single, unified Rust binary and also support other hypervisors as optional VMMs. -![architecture](./images/architecture.png) +```mermaid +graph TD + subgraph L1["Layer 1 — Service & Orchestration Layer"] + TaskSvc["Task Service"] + ImageSvc["Image Service"] + OtherSvc["Other Services"] + Dispatcher["Message Dispatcher"] + TaskSvc --> Dispatcher + ImageSvc --> Dispatcher + OtherSvc --> Dispatcher + end + + subgraph L2["Layer 2 — Management & Handler Layer"] + subgraph RuntimeHandler["Runtime Handler"] + SandboxMgr["Sandbox Manager"] + ContainerMgr["Container Manager"] + end + subgraph ContainerAbstractions["Container Abstractions"] + LinuxContainer["LinuxContainer"] + VirtContainer["VirtContainer"] + WasmContainer["WasmContainer"] + end + end + + subgraph L3["Layer 3 — Infrastructure Abstraction Layer"] + subgraph HypervisorIface["Hypervisor Interface"] + Qemu["Qemu"] + CloudHV["Cloud Hypervisor"] + Firecracker["Firecracker"] + Dragonball["Dragonball"] + end + subgraph ResourceMgr["Resource Manager"] + Sharedfs["Sharedfs"] + Network["Network"] + Rootfs["Rootfs"] + Volume["Volume"] + Cgroup["Cgroup"] + end + end + + subgraph L4["Layer 4 — Built-in Dragonball VMM Layer"] + BuiltinDB["Builtin Dragonball"] + end + + Dispatcher --> RuntimeHandler + RuntimeHandler --> ContainerAbstractions + ContainerAbstractions --> HypervisorIface + ContainerAbstractions --> ResourceMgr + Dragonball --> BuiltinDB + + classDef svc fill:#cce5ff,stroke:#004085,stroke-width:1px + classDef handler fill:#d4edda,stroke:#155724,stroke-width:1px + classDef infra fill:#fff3cd,stroke:#856404,stroke-width:1px + classDef builtin fill:#f8d7da,stroke:#721c24,stroke-width:1px + class TaskSvc,ImageSvc,OtherSvc,Dispatcher svc + class SandboxMgr,ContainerMgr,LinuxContainer,VirtContainer,WasmContainer handler + class Qemu,CloudHV,Firecracker,Dragonball,Sharedfs,Network,Rootfs,Volume,Cgroup infra + class BuiltinDB builtin +``` #### Service & Orchestration Layer @@ -114,13 +259,91 @@ Representing the core of the high-performance runtime, the `Builtin Dragonball` The Kata Rust runtime features a modular design that supports diverse services, runtimes, and hypervisors. We utilize a registration mechanism to decouple service logic from the core runtime. At startup, the runtime resolves the required runtime handler and hypervisor types based on configuration. -![framework](./images/framework.png) +```mermaid +graph LR + API["API"] + + subgraph Services["Configurable Services"] + TaskSvc["Task Service"] + ImageSvc["Image Service"] + OtherSvc["Other Service"] + end + + Msg(["Message Dispatcher"]) + + subgraph Handlers["Configurable Runtime Handlers"] + WasmC["WasmContainer"] + VirtC["VirtContainer"] + LinuxC["LinuxContainer"] + end + + subgraph HVs["Configurable Hypervisors"] + DB["Dragonball"] + QEMU["QEMU"] + CH["Cloud Hypervisor"] + FC["Firecracker"] + end + + API --> Services + Services --> Msg + Msg --> Handlers + Handlers --> HVs + + classDef api fill:#d0e8ff,stroke:#336,stroke-width:1px + classDef svc fill:#e2d9f3,stroke:#6610f2,stroke-width:1px + classDef msg fill:#fff3cd,stroke:#856404,stroke-width:1px + classDef handler fill:#d4edda,stroke:#155724,stroke-width:1px + classDef hv fill:#f8d7da,stroke:#721c24,stroke-width:1px + class API api + class TaskSvc,ImageSvc,OtherSvc svc + class Msg msg + class WasmC,VirtC,LinuxC handler + class DB,QEMU,CH,FC hv +``` ### Modular Resource Manager Managing diverse resources—from Virtio-fs volumes to Cgroup V2—is handled by an abstracted resource manager. Each resource type implements a common trait, enabling uniform lifecycle hooks and deterministic dependency resolution. -![resource manager](./images/resourceManager.png) +```mermaid +graph LR + RM["Resource Manager"] + + subgraph SandboxRes["Sandbox Resources"] + Network["Network Entity"] + SharedFs["Shared FS"] + end + + subgraph ContainerRes["Container Resources"] + Rootfs["Rootfs"] + Cgroup["Cgroup"] + Volume["Volume"] + end + + RM --> Network + RM --> SharedFs + RM --> Rootfs + RM --> Cgroup + RM --> Volume + + Network --> Endpoint["endpoint\n(veth / physical)"] + Network --> NetModel["model\n(tcfilter / route)"] + SharedFs --> InlineVirtioFs["inline virtiofs"] + SharedFs --> StandaloneVirtioFs["standalone virtiofs"] + + Rootfs --> RootfsTypes["block / virtiofs / nydus"] + Cgroup --> CgroupVers["v1 / v2"] + Volume --> VolumeTypes["sharefs / shm / local\nephemeral / direct / block"] + + classDef rm fill:#e2d9f3,stroke:#6610f2,stroke-width:2px + classDef sandbox fill:#d0e8ff,stroke:#336,stroke-width:1px + classDef container fill:#d4edda,stroke:#155724,stroke-width:1px + classDef impl fill:#fff3cd,stroke:#856404,stroke-width:1px + class RM rm + class Network,SharedFs sandbox + class Rootfs,Cgroup,Volume container + class Endpoint,NetModel,InlineVirtioFs,StandaloneVirtioFs,RootfsTypes,CgroupVers,VolumeTypes impl +``` ### Asynchronous I/O Model diff --git a/docs/design/architecture_4.0/images/architecture.png b/docs/design/architecture_4.0/images/architecture.png deleted file mode 100644 index 9d7fd976ef..0000000000 Binary files a/docs/design/architecture_4.0/images/architecture.png and /dev/null differ diff --git a/docs/design/architecture_4.0/images/built_in_vmm.png b/docs/design/architecture_4.0/images/built_in_vmm.png deleted file mode 100644 index 91386c5eb6..0000000000 Binary files a/docs/design/architecture_4.0/images/built_in_vmm.png and /dev/null differ diff --git a/docs/design/architecture_4.0/images/framework.png b/docs/design/architecture_4.0/images/framework.png deleted file mode 100644 index 992afdfff5..0000000000 Binary files a/docs/design/architecture_4.0/images/framework.png and /dev/null differ diff --git a/docs/design/architecture_4.0/images/kata4.0-arch.png b/docs/design/architecture_4.0/images/kata4.0-arch.png deleted file mode 100644 index 9110f38332..0000000000 Binary files a/docs/design/architecture_4.0/images/kata4.0-arch.png and /dev/null differ diff --git a/docs/design/architecture_4.0/images/not_built_in_vmm.png b/docs/design/architecture_4.0/images/not_built_in_vmm.png deleted file mode 100644 index ad1d5b8e34..0000000000 Binary files a/docs/design/architecture_4.0/images/not_built_in_vmm.png and /dev/null differ diff --git a/docs/design/architecture_4.0/images/resourceManager.png b/docs/design/architecture_4.0/images/resourceManager.png deleted file mode 100644 index 7a8fcae0c7..0000000000 Binary files a/docs/design/architecture_4.0/images/resourceManager.png and /dev/null differ diff --git a/docs/design/architecture_4.0/images/source_code/kata_3.0_images.drawio b/docs/design/architecture_4.0/images/source_code/kata_3.0_images.drawio deleted file mode 100644 index 146143cb07..0000000000 --- a/docs/design/architecture_4.0/images/source_code/kata_3.0_images.drawio +++ /dev/null @@ -1 +0,0 @@ -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 \ No newline at end of file