Deploying Rust on Kubernetes: A Practical Basic Guide

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction

\n\n

Rust is a modern systems programming language that combines the high performance of C/C++ with compile-time memory safety. Thanks to the absence of a garbage collector and low resource consumption, Rust applications are ideal for running in containerized environments. Kubernetes (K8s) is the de facto standard for container orchestration. In this guide, we will practically walk through how to build a simple web application in Rust, package it into a Docker image, and deploy it in a Kubernetes cluster.

\n\n

The article is intended for developers who are already familiar with the basics of Rust and have a basic understanding of Docker and Kubernetes. We will not delve into theory, but will focus on a step-by-step guide with real code examples and commands.

\n\n

1. Preparing the Rust Application

\n\n

As an example, we will create a minimal HTTP server using the popular actix-web framework. It will respond to GET requests and return a JSON response.

\n\n

Create a new project:

\n\n
cargo new rust-k8s-app\ncd rust-k8s-app
\n\n

Add dependencies to Cargo.toml:

\n\n
[dependencies]\nactix-web = "4"\nserde = { version = "1.0", features = ["derive"] }\nserde_json = "1.0"
\n\n

Now let's write the server code in src/main.rs:

\n\n
use actix_web::{get, web, App, HttpResponse, HttpServer, Responder};\nuse serde::Serialize;\n\n#[derive(Serialize)]\nstruct HealthResponse {\n    status: String,\n    message: String,\n}\n\n#[get("/health")]\nasync fn health_check() -> impl Responder {\n    HttpResponse::Ok().json(HealthResponse {\n        status: "ok".to_string(),\n        message: "Service is running".to_string(),\n    })\n}\n\n#[get("/")]\nasync fn index() -> impl Responder {\n    HttpResponse::Ok().json(serde_json::json!({\n        "service": "rust-k8s-app",\n        "version": env!("CARGO_PKG_VERSION")\n    }))\n}\n\n#[actix_web::main]\nasync fn main() -> std::io::Result<()> {\n    let host = std::env::var("HOST").unwrap_or_else(|_| "0.0.0.0".to_string());\n    let port: u16 = std::env::var("PORT")\n        .unwrap_or_else(|_| "8080".to_string())\n        .parse()\n        .expect("PORT must be a number");\n\n    println!("Server started on {}:{}", host, port);\n\n    HttpServer::new(|| {\n        App::new()\n            .service(health_check)\n            .service(index)\n    })\n    .bind((host.as_str(), port))?\n    .run()\n    .await\n}
\n\n

Note: we have moved the host and port to environment variables. This is a standard practice for containerized applications — configuration should come from outside.

\n\n

Check that the application builds and runs locally:

\n\n
cargo build --release\n./target/release/rust-k8s-app
\n\n

Open your browser at http://localhost:8080/health — you should see a JSON response.

\n\n

2. Building the Docker Image

\n\n

To deploy in Kubernetes, we need to package the application into a Docker image. We will use a multi-stage build to minimize the final image size.

\n\n

Create a Dockerfile in the project root:

\n\n
# Build stage\nFROM rust:1.75-slim-bookworm AS builder\n\nWORKDIR /app\n\n# Copy only Cargo.toml for caching dependencies\nCOPY Cargo.toml Cargo.lock ./\nRUN mkdir src && echo "fn main() {}" > src/main.rs\nRUN cargo build --release 2>/dev/null || true\n\n# Now copy the actual source code\nCOPY src ./src\nRUN cargo build --release\n\n# Final image\nFROM debian:bookworm-slim\n\nRUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/*\n\nCOPY --from=builder /app/target/release/rust-k8s-app /usr/local/bin/rust-k8s-app\n\nEXPOSE 8080\n\nCMD ["rust-k8s-app"]
\n\n

Build the image:

\n\n
docker build -t rust-k8s-app:latest .
\n\n

Check the image size

Blogs

Book Recommendations