Cargo: The Build Tool That Ships With the Language
Rust's built-in package manager and build tool is cargo. Unlike the fragmented ecosystem of C/C++ (CMake, Make, Autotools, Meson...), every Rust project uses cargo. It manages dependencies, compiles code, runs tests, generates documentation, runs benchmarks, and publishes packages — all with a consistent interface, covering the entire lifecycle from scaffolding a new project through adding a dependency to producing an optimized release binary.
Dependencies are declared in Cargo.toml and pinned exactly in Cargo.lock, giving you fully reproducible builds — a property that matters enormously for infrastructure tooling where "it worked last week" is not an acceptable debugging strategy.
Essential Infrastructure Crates
Rust's package registry is crates.io. Here are the crates you will encounter in almost every infrastructure project:
1. clap — Command Line Argument Parser
The standard for building CLI tools in Rust. You define your CLI interface as a Rust struct with annotations, and clap generates argument parsing, validation, and --help output at compile time:
use clap::Parser;
#[derive(Parser)]
#[command(name = "log-processor", about = "Processes JSON logs")]
struct Args {
#[arg(short, long)]
file: String,
#[arg(short, long, default_value_t = false)]
verbose: bool,
}
fn main() {
let args = Args::parse();
println!("Processing file: {}", args.file);
}
Running ./log-processor --help automatically produces a formatted help page. Running ./log-processor --file /var/log/app.json --verbose populates the struct.
2. tokio — Async Runtime
As covered earlier, Tokio is the standard async runtime. It's a dependency of almost every Rust network service.
3. serde + serde_json — Serialization/Deserialization
serde (SERialize-DEserialize) is the universal data serialization framework for Rust. You annotate your structs and serde generates optimized serialization code at compile time — no runtime reflection, no dynamic dispatch. This makes it significantly faster than equivalent libraries in Python or JavaScript.
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug)]
struct PodEvent {
name: String,
namespace: String,
phase: String,
}
fn main() {
let json = r#"{"name":"web-abc","namespace":"default","phase":"Running"}"#;
let event: PodEvent = serde_json::from_str(json).unwrap();
println!("Pod {} is {}", event.name, event.phase);
}
serde supports JSON, YAML, TOML, MessagePack, and dozens of other formats by swapping the format crate — the struct annotations stay the same.
4. reqwest — HTTP Client
The standard async HTTP client for Rust, built on Tokio. Used for calling Kubernetes APIs, cloud provider APIs, or any HTTP endpoint.
5. kube — Kubernetes Client
The official Rust client for the Kubernetes API. Supports watching resources, applying manifests, and building controllers — the Rust equivalent of client-go.