Replies: 6 comments 1 reply
-
I believe a second shared-storage-based cubecow backend needs to be implemented, but it would be best to abstract it into a generic interface that allows for easy implementation of different shared-storage backends.
Of course, this is part of our plan. We will utilize shared storage to implement volume semantics, enable cross-node pause and resume, and achieve cross-node exception recovery from the sandbox.
In our design, each disk clone can exist independently, without any snapshot chain. Ideally, clones based on shared storage should also operate in this manner.
I am not familiar with Ceph, perhaps we can discuss this issue in more specific scenario details |
Beta Was this translation helpful? Give feedback.
-
|
Thanks for confirming the direction 🙏. Quick update: we've built a working PoC on a real Ceph cluster (two nodes) and validated the core pieces — volume create/map, cross-node cold migration, crash consistency, O_DIRECT, and exclusive-lock/fencing behavior. A few directions I'd like to align on: 1) Generic interface — Agreed. cubecow already has a backend-agnostic 2) Cross-node pause/resume and failover — Good to hear this is on your roadmap; it's exactly what we're hoping to build on. We've validated cross-node cold recovery at the disk layer, and cross-node resume looks like a natural extension (the memory artifact goes on shared storage too). Since how you approach cross-node resume and failover shapes what the storage layer needs to provide, we'd like to understand your current thinking there — it likely affects some of our design choices, and we're glad to share what we've validated so far. 3) Clone model — Following your "each clone independent, no chain" design, both mappings below give independent, chain-free clones; they differ only in how a committed template is stored, and we'd like your call:
Either works on our side — which fits your model better? 4) krbd exclusive-lock / fencing — We've worked through the Ceph-side behavior in the PoC, so we're happy to cover that part. One thing worth surfacing, since it touches your failover plans: dual-write safety isn't something the storage layer can fully guarantee on its own. RBD gives the tools — an exclusive-lock, and fencing a stale owner during failover — but One more thing we'd like to understand: you mentioned volume semantics as part of the shared-storage plan — how do you see this cubecow shared-storage backend relating to the CubeVolume work in #470 (same layer, or complementary)? We'd like to make sure we build in the right place. Is anyone already building a shared-storage backend for cubecow? We'd like to avoid duplicating effort. Once we've aligned on (1) the interface and (3) the clone model, how would you prefer the contribution to land — one PR, or split by component? |
Beta Was this translation helpful? Give feedback.
-
I think we can implement it first, and then optimize the architecture here based on subsequent developments.
We are preparing to implement cross-node pause and resume based on S3 (object storage), just like E2B and AgentSubstrate do. Of course, I think it would be best if the backend shared storage implementation was pluggable, and could be based on various shared storage systems, such as NFS, S3, Ceph, JuiceFS, etc. The first step is to upload and download the corresponding snapshot from the shared storage to the local, and the best way is to implement lazy loading directly based on the remote shared storage.
I think the best approach is not to change the core logic or the semantics of the framework; it's better to implement it very independently. For the Cow implementation of shared storage, we can divide it into two categories: The first is shared storage that natively supports flat snapshots (completely independent data block indexes, shared actual data blocks, similar to XFS reflink and LVM thin clones); the second type is shared storage that natively does not support flat snapshots (simulated through full copy or chain merging).
I think a more appropriate approach would be to ensure disk exclusivity within the Cube's work flow, without relying on any assumptions about the storage layer.
I believe Cubecow focuses more on cross-node design for snapshots/rollbacks/cloning/pauses/resumes within the sandbox lifecycle, balancing storage and runtime efficiency. Volume, on the other hand, provides persistent storage decoupled from the sandbox lifecycle. While their focuses differ, they likely rely on the same shared storage. Could some standardization be achieved in the pluggable design (similar to CSI) of the shared storage backend?
As far as I know, not yet.
The best approach is one PR per feature, which can be fully compiled and tested, with a complete test report attached. |
Beta Was this translation helpful? Give feedback.
-
|
@kinwin-ustc Thanks for the detailed answers earlier. Following the "implement the backend first, refine the architecture later" direction, I've built the RBD backend and opened a draft PR: #990 What this does:
This PR is only the storage backend; cross-node orchestration (lease / fencing / shared-storage) and memory snapshot / warm start belong to the cross-node/failover roadmap and are left out here. Two things I'd like to ask:
|
Beta Was this translation helpful? Give feedback.
-
We will support Volume capabilities(https://e2b.dev/docs/volumes) in the upcoming 0.6.0, providing a separate persistent storage abstraction decoupled from the sandbox lifecycle, and offering CSI-like custom backend plugin capabilities.
Pursuing the ultimate in cost and performance is our core objective, so to achieve these capabilities, we will definitely use the most reasonable method. |
Beta Was this translation helpful? Give feedback.
-
|
Following up on the incremental-diff point from earlier in this thread: I've open-sourced that piece as cowdiff — a reflink-aware incremental binary diff (Go library + CLI). It works directly against cubecow's reflink layout, since volumes and snapshots are FICLONE siblings: FIEMAP finds the diverged extents, so a diff reads only what actually changed, and Could be a ready-made building block for incremental snapshot export / cross-node distribution when the Volume work lands. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
We run long-lived agent sandboxes: each instance owns a persistent workspace, stays mostly resident on one node (paused when idle, resumed on demand), and is created/migrated infrequently. Two requirements keep surfacing that node-local storage can't meet:
Sketch — what would change and what wouldn't:
cow.backend.kind = "rbd"— theEnginetrait explicitly anticipates sibling backends. Per-sandbox writable layers, committed template/snapshot rootfs and data volumes become RBD images (activate →rbd map).Node failure then degrades to: re-map the image on any healthy node and cold boot from the crash-consistent disk. This looks complementary to the reliability items already on the roadmap (sandbox failover, node drain with migration) — an opt-in deployment mode rather than a replacement for the local fast path.
Questions for the maintainers:
writableflag oncreate_snapshotwould enable native mapping (version points as realrbd snap, half the chain depth). Would you take such a trait change, or prefer the zero-change mapping?If the direction sounds right, we'd like to help drive it.
Beta Was this translation helpful? Give feedback.
All reactions