You use Rust with Kubernetes primarily by building high-performance custom controllers or CRDs using the kube-rs client library, or by compiling your Rust applications into static binaries to run as lightweight, dependency-free containers. This approach leverages Rust's safety and performance while integrating seamlessly with the Kubernetes API and container ecosystem.
For building custom controllers, kube-rs is the standard tool. It provides a type-safe, ergonomic client that handles the Kubernetes API, including support for the Operator pattern, leader election, and resource reconciliation. Here is a minimal example of a controller that watches for ConfigMap resources and logs changes:
use kube::{
api::{Api, ListParams, Patch, PatchParams},
runtime::{controller, Config, Controller},
Client, ResourceExt,
};
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize, Clone, Debug)]
struct MyConfigMap {
data: std::collections::HashMap<String, String>,
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let client = Client::try_default().await?;
let config_maps: Api<MyConfigMap> = Api::default_namespaced(client);
let controller = Controller::new(config_maps, ListParams::default())
.run(
|cm, _ctx| async move {
println!("Observed ConfigMap: {}", cm.name_any());
Ok(())
},
Default::default(),
)
.await;
controller.await?;
Ok(())
}
To run your Rust application as a standard workload, you must compile it as a static binary to avoid needing a complex base image with glibc. Use cross to build for Linux targets from your development machine, then package it in a minimal container like scratch or alpine.
First, ensure your Cargo.toml includes the panic = "abort" setting for smaller binaries and use cross to build:
# Build a static binary for Linux x86_64
cross build --release --target x86_64-unknown-linux-gnu
# Create a minimal Dockerfile
# FROM scratch
# COPY target/x86_64-unknown-linux-gnu/release/my-app /my-app
# CMD ["/my-app"]
This results in a container image under 5MB, significantly reducing attack surface and startup time compared to standard Linux distributions. For more complex scenarios involving CRDs, you can use kubebuilder or controller-gen to generate the necessary Go-based scaffolding, then replace the Go controller logic with your Rust implementation using kube-rs.