Déploiement de Rust sur Kubernetes : guide pratique de base
Rust est l'un des langages de programmation système les plus rapides et les plus sûrs. Kubernetes (k8s) est le standard de facto pour l'orchestration de conteneurs. Leur combinaison permet de créer des services extrêmement efficaces, légers et résilients. Dans cet article, nous allons parcourir le cycle complet de déploiement d'une application Rust dans un cluster Kubernetes : de la construction de l'image Docker à la mise à l'échelle.
Pourquoi Rust et Kubernetes forment une paire idéale
Rust se compile en un fichier binaire natif, ne nécessitant ni machine virtuelle (comme Java) ni interpréteur (comme Python). Cela donne une taille d'image minimale et une faible consommation de mémoire. Dans le contexte de Kubernetes, cela signifie :
- Démarrage rapide des pods (souvent moins d'une seconde).
- Économie des ressources du cluster.
- Moins de vulnérabilités grâce à l'absence d'environnements d'exécution lourds.
Étape 1 : Créer une application Rust simple
Pour l'exemple, nous allons écrire un serveur HTTP en utilisant le framework populaire actix-web. Créez un nouveau projet :
cargo new rust-k8s-democd rust-k8s-demoAjoutez les dépendances dans Cargo.toml :
[dependencies]actix-web = "4"serde = { version = "1", features = ["derive"] }Écrivons un gestionnaire simple dans src/main.rs :
use actix_web::{get, web, App, HttpServer, Responder};use std::env;
#[get("/")]async fn index() -> impl Responder { let message = env::var("MESSAGE").unwrap_or_else(|_| "Hello from Rust!".to_string()); format!("{{ \\"message\\": \\"{}\\" }}", message)}
#[actix_web::main]async fn main() -> std::io::Result<()> { let port = env::var("PORT").unwrap_or_else(|_| "8080".to_string()); let addr = format!("0.0.0.0:{}", port); println!("Starting server at {}", addr);
HttpServer::new(|| { App::new() .service(index) }) .bind(&addr)? .run() .await}L'application lit les variables d'environnement MESSAGE et PORT — cela sera utile pour la configuration via Kubernetes ConfigMap.
Étape 2 : Construction de l'image Docker
Nous utilisons une construction multi-étapes (multi-stage build) pour minimiser la taille de l'image. Créez un Dockerfile :
# Étape de constructionFROM rust:1.75-slim-bookworm AS builder
WORKDIR /appCOPY Cargo.toml Cargo.lock ./RUN mkdir src && echo "fn main() {}" > src/main.rsRUN cargo build --release 2>/dev/null || true
COPY src/ src/RUN cargo build --release
# Image finaleFROM debian:bookworm-slimRUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/*COPY --from=builder /app/target/release/rust-k8s-demo /usr/local/bin/rust-k8s-demo
EXPOSE 8080CMD ["rust-k8s-demo"]Construisez l'image et envoyez-la dans un registre (par exemple, Docker Hub) :
docker build -t yourusername/rust-k8s-demo:latest .docker push yourusername/rust-k8s-demo:latestÉtape 3 : Manifestes Kubernetes
Créons un dossier k8s et plaçons-y les manifestes.
3.1. ConfigMap pour la configuration
Créez le fichier k8s/configmap.yaml :
apiVersion: v1kind: ConfigMapmetadata: name: rust-app-configdata: MESSAGE: "Bonjour depuis Rust sur Kubernetes !" PORT: "8080"3.2. Deployment
Créez le fichier k8s/deployment.yaml :
apiVersion: apps/v1kind: Deploymentmetadata: name: rust-appspec: replicas: 3 selector: matchLabels: app: rust-app template: metadata: labels: app: rust-app spec: containers: - name: rust-app image: yourusername/rust-k8s-demo:latest ports: - containerPort: 8080 envFrom: - configMapRef: name: rust-app-config