This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
# Build
cargo build # Debug build (fast iteration)
cargo build --release # Release build
# Test
cargo test # All workspace tests
cargo test -p rusternetes-api-server # Single crate
cargo test test_name # Single test by name
cargo test test_name -- --nocapture # With stdout
# Lint & Format
cargo fmt --all # Format
cargo clippy --all-targets --all-features -- -D warnings # Lint
make pre-commit # Format + clippy + test (run before commits)
# Cluster (Podman or Docker)
export KUBELET_VOLUMES_PATH=$(pwd)/.rusternetes/volumes
podman compose build # Build images (~1 hour first build, faster with cache)
podman compose up -d # Start cluster
podman compose down # Stop cluster
bash scripts/bootstrap-cluster.sh # Create CoreDNS, services, SA tokens
# Conformance testing
bash scripts/run-conformance.sh # Full conformance lifecycle
bash scripts/conformance-progress.sh # Monitor pass/fail progress
# e2e output is in /tmp/sonobuoy/results/e2e.log inside the e2e containerKUBECONFIG: ~/.kube/rusternetes-config
Rust reimplementation of Kubernetes. Workspace with 10 crates:
common- Shared resource types (Pod, Deployment, Service, etc.), error types, utilities. All resource structs live insrc/resources/. Error type insrc/error.rsmaps to Kubernetes StatusReason and implements Axum'sIntoResponse.api-server- Axum-based REST API. Routes insrc/router.rs(~9400 lines). One handler file per resource type insrc/handlers/. State insrc/state.rsholds storage, auth, IP allocator, webhook manager, watch cache.storage-Storagetrait insrc/lib.rswith etcd backend (src/etcd.rs), SQLite backend via rhino (src/rhino.rs, behindsqlitefeature), and memory backend (src/memory.rs).StorageBackendenum dispatches to the selected backend. Keys follow/registry/{resource_type}/{namespace}/{name}. Resource versions map to backend revision numbers.controller-manager- 31 controllers insrc/controllers/. Each has a struct withstorage: Arc<S>+interval: Duration, an infiniterun()loop, andreconcile_one()per resource.kubelet- Container runtime via bollard (Docker API). Manages pod lifecycle, volumes, probes, networking.kube-proxy- iptables-based service routing. Runs in host network mode. Reads both Endpoints and EndpointSlices.scheduler- Pod scheduling with affinity, taints/tolerations, priority/preemption. Plugins insrc/plugins/.kubectl- CLI tool. Commands insrc/commands/.cloud-providers- AWS/GCP/Azure integrations.rusternetes- All-in-one binary. Spawns api-server, scheduler, controller-manager, kubelet, and kube-proxy as concurrent tokio tasks sharing oneStorageBackend. Defaults to embedded SQLite.
- All resource structs use
#[serde(rename_all = "camelCase")] - Optional fields use
#[serde(skip_serializing_if = "Option::is_none")] - TypeMeta is flattened:
#[serde(flatten)] pub type_meta: TypeMeta - camelCase abbreviations follow K8s style:
podIPnotpodIp,hostIPnothostIp,containerIDnotcontainerId
- Define struct in
crates/common/src/resources/{type}.rs - Add handlers in
crates/api-server/src/handlers/{type}.rs - Register route in
crates/api-server/src/router.rs - Add controller in
crates/controller-manager/src/controllers/if needed
pub struct FooController<S: Storage> {
storage: Arc<S>,
interval: Duration,
}
impl<S: Storage> FooController<S> {
pub async fn run(&self) -> Result<()> {
loop {
self.reconcile_all().await?;
tokio::time::sleep(self.interval).await;
}
}
}- Async tests:
#[tokio::test] - Use
MemoryStorage(not etcd) for unit tests - Serial tests when needed:
#[serial_test::serial]
Conventional Commits: feat:, fix:, docs:, test:, refactor:, chore:
Services: etcd, api-server (port 6443 with TLS), scheduler, controller-manager, 2x kubelet (node-1, node-2), kube-proxy (host network).
- TLS certs in
.rusternetes/certs/, generated byscripts/generate-certs.sh - Cert SANs must include bridge IPs (172.18.0.2-5)
- kube-proxy needs
CAP_NET_ADMINfor iptables; runs host network mode KUBERNETES_SERVICE_HOST_OVERRIDEenv var sets the API server address for pods- CoreDNS ClusterIP pinned to 10.96.0.10