Despliegue de Rust en Kubernetes: guía básica
El desarrollo moderno en la nube requiere que las aplicaciones tengan alto rendimiento, seguridad y uso eficiente de recursos. Rust, con su sistema de ownership y abstracciones de costo cero, es ideal para crear microservicios que se ejecutan en orquestadores de contenedores. Kubernetes, por su parte, proporciona un potente conjunto de herramientas para gestionar aplicaciones containerizadas. En esta guía, analizaremos paso a paso cómo preparar una aplicación Rust para su despliegue en Kubernetes, crear una imagen Docker y desplegarla en un clúster.
1. Preparación de la aplicación Rust
Antes de desplegar la aplicación en Kubernetes, es necesario containerizarla. Para la demostración, crearemos una aplicación HTTP simple basada en el framework actix-web, que responderá a las solicitudes y devolverá información básica del sistema.
Creemos un nuevo proyecto:
cargo new rust-k8s-appcd rust-k8s-appAñadamos las dependencias en Cargo.toml:
[dependencies]actix-web = "4"serde = { version = "1.0", features = ["derive"] }tokio = { version = "1", features = ["full"] }Escribamos una aplicación simple en src/main.rs:
use actix_web::{get, web, App, HttpResponse, HttpServer, Responder};use serde::Serialize;
#[derive(Serialize)]struct HealthResponse { status: String, version: String,}
#[get("/health")]async fn health_check() -> impl Responder { HttpResponse::Ok().json(HealthResponse { status: "ok".to_string(), version: env!("CARGO_PKG_VERSION").to_string(), })}
#[get("/")]async fn index() -> impl Responder { HttpResponse::Ok().body("Rust on Kubernetes! 🚀")}
#[actix_web::main]async fn main() -> std::io::Result<()> { let host = std::env::var("HOST").unwrap_or_else(|_| "0.0.0.0".to_string()); let port: u16 = std::env::var("PORT") .unwrap_or_else(|_| "8080".to_string()) .parse() .expect("PORT must be a number");
println!("Starting server at {}:{}", host, port);
HttpServer::new(|| { App::new() .service(health_check) .service(index) }) .bind((host.as_str(), port))? .run() .await}Verifiquemos que la aplicación se compila y se ejecuta localmente:
cargo build --releasecargo run --releaseDespués de la ejecución, abra el navegador y vaya a la dirección http://localhost:8080/health — debería ver un JSON con la respuesta.
2. Creación de la imagen Docker para la aplicación Rust
Para minimizar el tamaño de la imagen y acelerar la compilación, utilizaremos una compilación multi-etapa (multi-stage build). La primera etapa es la compilación de la aplicación, la segunda es la creación de una imagen mínima basada en scratch o alpine.
Cree un archivo Dockerfile en la raíz del proyecto:
# Etapa 1: CompilaciónFROM rust:1.75-slim-buster 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
# Etapa 2: Imagen mínimaFROM debian:buster-slim
RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/*COPY --from=builder /app/target/release/rust-k8s-app /usr/local/bin/rust-k8s-app
EXPOSE 8080CMD ["rust-k8s-app"]Construya la imagen:
docker build -t rust-k8s-app:latest .Verifique que la imagen funciona:
docker run -p 8080:8080 rust-k8s-app:latestLuego, envíe la imagen a Docker Hub u otro registro de contenedores, reemplazando username con su nombre de usuario:
docker tag rust-k8s-app:latest username/rust-k8s-app:latestdocker push username/rust-k8s-app:latest