Thank you for your interest in contributing to Rusternetes. This is a Rust reimplementation of Kubernetes spanning 10 crates, 216,000+ lines of code, and 3,100+ tests. This document covers everything you need to get started.
- Rust (stable toolchain)
- Docker and Docker Compose (for integration testing)
make(for convenience targets)
Run these before every commit:
cargo fmt --all
cargo clippy --all-targets --all-features -- -D warnings
cargo testOr run all three at once:
make pre-commitFollow Conventional Commits:
feat:-- New featurefix:-- Bug fixdocs:-- Documentation changestest:-- Test changesrefactor:-- Code refactoringchore:-- Maintenance tasks
- Fork and clone the repository.
- Create a feature branch from
main. - Make your changes, add tests, and run
make pre-commit. - Push and open a Pull Request.
All async tests use #[tokio::test]. Unit tests should use MemoryStorage rather than etcd.
When tests must run sequentially, annotate them with #[serial_test::serial].
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_feature_works() {
let storage = MemoryStorage::new();
let result = your_function(&storage).await;
assert!(result.is_ok());
}
}To run tests for a single crate (note: use underscores in the package name):
cargo test -p rusternetes-api-serverTo run a single test with output:
cargo test test_name -- --nocaptureThese are critical for Kubernetes API compatibility. Every resource struct must follow them:
#[serde(rename_all = "camelCase")]on all resource structs#[serde(skip_serializing_if = "Option::is_none")]on optional fields#[serde(flatten)]on theTypeMetafield- Kubernetes-style camelCase abbreviations:
podIP(notpodIp),hostIP(nothostIp),containerID(notcontainerId)
- Define the struct in
crates/common/src/resources/{type}.rs - Add handlers in
crates/api-server/src/handlers/{type}.rs - Register routes in
crates/api-server/src/router.rs - Add a controller in
crates/controller-manager/src/controllers/if the resource needs reconciliation
Controllers follow a standard reconciliation loop pattern:
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;
}
}
}New controllers go in crates/controller-manager/src/controllers/ and are registered in the controller manager startup.
For integration testing against a full cluster:
export KUBELET_VOLUMES_PATH=$(pwd)/.rusternetes/volumes
podman compose build # or: docker compose build
podman compose up -d # or: docker compose up -d
bash scripts/bootstrap-cluster.shThen interact with it:
export KUBECONFIG=~/.kube/rusternetes-config
kubectl get pods -AThe cluster runs etcd, the API server (port 6443 with TLS), a scheduler, a controller manager, two kubelets, and kube-proxy.
bash scripts/run-conformance.sh
bash scripts/conformance-progress.shThe e2e log is written to /tmp/sonobuoy/results/e2e.log inside the e2e container.
| Crate | Purpose |
|---|---|
common |
Shared resource types, error types, utilities |
api-server |
Axum-based REST API with per-resource handler files |
storage |
Pluggable storage: etcd, SQLite (rhino), and in-memory backends |
controller-manager |
31 controllers following the reconciliation loop pattern |
kubelet |
Container runtime via bollard, pod lifecycle, volumes, probes |
kube-proxy |
iptables-based service routing |
scheduler |
Pod scheduling with affinity, taints, tolerations, preemption |
kubectl |
CLI tool |
rusternetes |
All-in-one binary (all components as tokio tasks, embedded SQLite) |
cloud-providers |
AWS, GCP, and Azure integrations |
- Follow Rust standard naming conventions.
- Use
cargo fmtfor formatting andcargo clippyfor linting. - Write clear, self-documenting code. Add comments for complex logic.
- Keep functions focused. Prefer small, testable units.
- Avoid
unsafecode unless absolutely necessary.
- Ensure
make pre-commitpasses with no errors. - Provide a clear description of the changes and any related issues.
- Include the testing you performed.
- Address review feedback promptly.
By contributing to Rusternetes, you agree that your contributions will be licensed under the Apache-2.0 License.