# How cube-agent Manages Container Lifecycle Inside MicroVMs as PID 1

> Discover how cube-agent, as PID 1 in CubeSandbox MicroVMs, manages container lifecycles by translating host commands into containerd-shim operations.

- Repository: [Tencent Cloud/CubeSandbox](https://github.com/TencentCloud/CubeSandbox)
- Tags: internals
- Published: 2026-07-03

---

**cube-agent acts as the init process (PID 1) inside CubeSandbox MicroVMs, mounting filesystems, hosting a ttrpc server over vsock, and translating host-side container lifecycle commands into containerd-shim operations.**

CubeSandbox uses `cube-agent` as the guest-side init system to bridge the gap between host orchestration and in-VM container execution. When a MicroVM boots, the statically-linked `cube-agent` binary—packaged at `/sbin/init` during the VM image build—runs as PID 1 to initialize the system and establish a communication channel with the host. This enables full container lifecycle management via ttrpc over vsock, allowing the host-side CubeShim to create, start, and stop containers inside the MicroVM.

## Initialization as PID 1 in MicroVMs

When the MicroVM boots, `cube-agent` determines whether it should run in init mode by checking its process ID. In [`agent/src/main.rs`](https://github.com/TencentCloud/CubeSandbox/blob/main/agent/src/main.rs), lines 58–60, the code verifies if it is PID 1:

```rust
let init_mode = unistd::getpid() == Pid::from_raw(1);   // agent/src/main.rs:L58-L60

```

If `init_mode` is true, `cube-agent` performs essential system initialization before transitioning into its agent role. This includes mounting the necessary filesystems (proc, sys, dev), setting the hostname, and calling `init_agent_as_init` to assume the responsibilities of the system init process. The binary is injected into the guest image as `/sbin/init` by the build script at [`deploy/one-click/build-vm-assets.sh`](https://github.com/TencentCloud/CubeSandbox/blob/main/deploy/one-click/build-vm-assets.sh) (line 117), ensuring it launches automatically as the first process.

## ttrpc Communication Over Vsock

After initialization, `cube-agent` establishes the communication channel that allows the host to manage containers inside the VM. It opens a **vsock** listener on a port defined by the `log_vport` configuration parameter and starts a ttrpc server. In [`agent/src/main.rs`](https://github.com/TencentCloud/CubeSandbox/blob/main/agent/src/main.rs) around lines 96–98, the `start_sandbox` function invokes `rpc::start` to begin listening on the VM's vsock interface:

```rust
// Start ttrpc server on vsock
rpc::start(vsock_listener).await?;

```

The ttrpc protocol definitions reside in `libs/protocols/protos/`, providing the structured communication format between the host and the guest agent. This vsock-based communication bypasses traditional network stacks, offering secure, hypervisor-mediated channels between the host and MicroVM.

## Container Lifecycle Forwarding from CubeShim

The host-side **CubeShim** component acts as the client to `cube-agent`'s ttrpc server. CubeShim implements the standard container shim API—including `CreateContainer`, `StartContainer`, `Exec`, `Kill`, and `Delete`—and forwards each request over the vsock connection to the in-VM `cube-agent`.

According to the CubeShim documentation ([`CubeShim/README.md`](https://github.com/TencentCloud/CubeSandbox/blob/main/CubeShim/README.md), lines 24–48), the forwarding logic operates as follows:

- **CubeShim** connects to the vsock address `VMADDR_CID_ANY` on the configured port
- Each container lifecycle operation is serialized as a ttrpc request
- The request travels over vsock into the MicroVM where `cube-agent` receives it

This architecture decouples the orchestration logic on the host from the container runtime inside the MicroVM, allowing CubeSandbox to maintain a minimal guest footprint while supporting standard container operations.

## Creating Containers Inside the VM

When `cube-agent` receives a `CreateContainer` request via ttrpc, it translates the high-level shim API into actual container operations using the **containerd-shim-cube-rs** runtime. The handler in [`agent/src/rpc/mod.rs`](https://github.com/TencentCloud/CubeSandbox/blob/main/agent/src/rpc/mod.rs) processes the request and spawns the container's init process, setting up namespaces, cgroups, and mounting the rootfs.

Here is how the host-side CubeShim (Go) creates a container inside the MicroVM:

```go
// Host-side shim (Go) – create a container in the VM
func createContainer(ctx context.Context, vmID string, spec *rspec.Spec) error {
    // 1. Connect to the VM's vsock (port is stored in the VM metadata)
    conn, err := vsock.Dial(vsock.CidAny, uint32(vmPort))
    if err != nil { return err }

    // 2. Build a ttrpc client for the cube-agent service
    client := ttrpc.NewClient(conn)
    defer client.Close()

    // 3. Call the CreateContainer RPC (defined in libs/protocols/protos/)
    req := &api.CreateContainerRequest{
        Id:   containerID,
        Spec: spec,
    }
    resp, err := api.NewCubeAgentServiceClient(client).CreateContainer(ctx, req)
    if err != nil { return err }

    // 4. The agent now runs containerd-shim-cube-rs to launch the container inside the VM
    fmt.Printf("Container created, PID %d inside VM\n", resp.Pid)
    return nil
}

```

Inside the VM, `cube-agent` (Rust) handles the RPC:

```rust
// agent/src/rpc/mod.rs – handles CreateContainer RPC
async fn create_container(
    &self,
    req: CreateContainerRequest,
) -> Result<CreateContainerResponse, RpcError> {
    // Translate the request into a containerd-shim call
    let shim = containerd_shim_cube_rs::Shim::new();
    let pid = shim.create_container(req.spec).await?;
    Ok(CreateContainerResponse { pid })
}

```

This end-to-end flow demonstrates how `cube-agent` bridges the gap between the host's orchestration commands and the in-VM container runtime.

## Graceful VM Shutdown

When containers finish execution or the control plane requests VM termination, `cube-agent` ensures a clean shutdown. In [`agent/src/main.rs`](https://github.com/TencentCloud/CubeSandbox/blob/main/agent/src/main.rs) (lines 1003–1006), the agent calls the Linux reboot system call to power off the MicroVM:

```rust
libc::reboot(LINUX_REBOOT_CMD_POWER_OFF);

```

This ensures that the MicroVM shuts down cleanly after all container processes have terminated, preventing resource leaks and ensuring proper cleanup of the guest environment.

## Summary

- **PID 1 Detection**: `cube-agent` checks `unistd::getpid()` in [`agent/src/main.rs`](https://github.com/TencentCloud/CubeSandbox/blob/main/agent/src/main.rs) to determine if it should run as the init process, mounting filesystems and initializing the system when true.
- **Vsock Communication**: The agent starts a ttrpc server on a vsock listener, enabling secure host-to-VM communication without traditional networking.
- **Lifecycle Proxy**: CubeShim forwards container operations (Create, Start, Kill, Delete) over ttrpc/vsock to `cube-agent`, which translates them into containerd-shim calls.
- **Runtime Integration**: Inside the VM, `cube-agent` uses `containerd-shim-cube-rs` to create containers, configure namespaces, and manage cgroups.
- **Clean Shutdown**: When work completes, `cube-agent` calls `reboot(LINUX_REBOOT_CMD_POWER_OFF)` to power off the MicroVM gracefully.

## Frequently Asked Questions

### What happens if cube-agent is not running as PID 1?

If `cube-agent` detects it is not PID 1 via the `getpid()` check in [`agent/src/main.rs`](https://github.com/TencentCloud/CubeSandbox/blob/main/agent/src/main.rs), it skips the init-specific setup routines (filesystem mounting, hostname configuration) and runs in a reduced agent mode. However, in standard CubeSandbox deployments, the build script ([`build-vm-assets.sh`](https://github.com/TencentCloud/CubeSandbox/blob/main/build-vm-assets.sh)) ensures the binary is placed at `/sbin/init`, guaranteeing it launches as PID 1.

### How does cube-agent communicate with the host?

`cube-agent` communicates with the host via **ttrpc over vsock**. It opens a vsock listener on a port configured by `log_vport` and starts a ttrpc server (`rpc::start` in [`agent/src/main.rs`](https://github.com/TencentCloud/CubeSandbox/blob/main/agent/src/main.rs)). The host-side CubeShim connects to this vsock endpoint using `VMADDR_CID_ANY`, allowing bidirectional RPC communication for container lifecycle management.

### What container runtime does cube-agent use?

`cube-agent` uses the **containerd-shim-cube-rs** runtime to actually create and manage containers. When `cube-agent` receives a ttrpc request like `CreateContainer`, it translates the request into calls to this internal shim runtime, which handles the low-level details of process spawning, namespace configuration, and cgroup setup.

### How does cube-agent handle MicroVM shutdown?

When containers finish or the host requests termination, `cube-agent` initiates a clean shutdown by calling `libc::reboot(LINUX_REBOOT_CMD_POWER_OFF)` (see [`agent/src/main.rs`](https://github.com/TencentCloud/CubeSandbox/blob/main/agent/src/main.rs) lines 1003–1006). This system call signals the kernel to power off the VM, ensuring all resources are properly released and the MicroVM exits cleanly.