Introducción: por qué C++ y Kubernetes son un tándem poderoso
La infraestructura en la nube moderna se construye cada vez más sobre arquitectura de microservicios y contenerización. Kubernetes se ha convertido en el estándar de facto para la orquestación de contenedores. Sin embargo, muchos desarrolladores creen erróneamente que Kubernetes es solo para lenguajes interpretados (Python, JavaScript) o JVM. En realidad, el despliegue de aplicaciones C++ en Kubernetes no solo es posible, sino que ofrece ventajas significativas: alto rendimiento, consumo mínimo de memoria y control total sobre los recursos.
En esta guía, analizaremos cómo empaquetar un servidor C++ en una imagen Docker, crear los manifiestos necesarios para Kubernetes y ejecutarlo en un clúster. Aprenderá cómo manejar configuraciones y secretos, así como cómo configurar correctamente Health Checks para un funcionamiento confiable de la aplicación.
1. Preparación de la aplicación C++ para contenerización
Antes de hablar de Kubernetes, debemos preparar la aplicación C++ en sí. Como ejemplo, tomemos un servidor HTTP simple basado en la biblioteca libmicrohttpd. Este servidor responderá a las solicitudes y leerá la configuración de las variables de entorno, un enfoque estándar para aplicaciones 12-factor.
1.1. Código de un servidor HTTP simple en C++
Creemos el archivo main.cpp:
#include <iostream>#include <string>#include <microhttpd.h>#include <cstdlib>
static enum MHD_Result answer_to_connection(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls) { const char *page = "<html><body>Hello from C++ on Kubernetes!</body></html>"; struct MHD_Response *response = MHD_create_response_from_buffer(strlen(page), (void*)page, MHD_RESPMEM_PERSISTENT); int ret = MHD_queue_response(connection, MHD_HTTP_OK, response); MHD_destroy_response(response); return ret == MHD_YES ? MHD_OK : MHD_NO;}
int main() { const char* port_str = std::getenv("PORT"); unsigned int port = port_str ? std::stoul(port_str) : 8080;
std::cout << "Starting server on port " << port << std::endl; struct MHD_Daemon *daemon = MHD_start_daemon(MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD, port, nullptr, nullptr, &answer_to_connection, nullptr, MHD_OPTION_END); if (nullptr == daemon) { std::cerr << "Failed to start daemon" << std::endl; return 1; }
// Espera infinita while (true) { sleep(1); }
MHD_stop_daemon(daemon); return 0;}Este código lee el puerto de la variable de entorno PORT (valor predeterminado: 8080) e inicia el servidor HTTP. Tenga en cuenta: usamos un bucle infinito para que el proceso no termine; esto es importante para el funcionamiento dentro del contenedor.
1.2. Compilación de la aplicación
Para la compilación necesitaremos CMake. Creemos CMakeLists.txt:
cmake_minimum_required(VERSION 3.10)project(cpp-k8s-server)
find_package(libmicrohttpd REQUIRED)
add_executable(server main.cpp)target_link_libraries(server ${LIBMICROHTTPD_LIBRARIES})target_include_directories(server PRIVATE ${LIBMICROHTTPD_INCLUDE_DIRS})Ahora la aplicación está lista para la contenerización.
2. Creación de la imagen Docker para la aplicación C++
Kubernetes trabaja con contenedores, por lo que necesitamos una imagen Docker. Para C