Introducción: Por qué Go y Kubernetes son la pareja ideal
\n\nEl desarrollo moderno se apoya cada vez más en la arquitectura de microservicios y la contenerización. El lenguaje Go (Golang), gracias a su rendimiento, simplicidad y soporte nativo para la concurrencia, se ha convertido en uno de los líderes para escribir servicios backend. Al mismo tiempo, Kubernetes (K8s) es el estándar de facto para la orquestación de contenedores.
\n\nDesplegar una aplicación Go en Kubernetes es un proceso que puede parecer complejo para los principiantes. Sin embargo, siguiendo una guía paso a paso, podrás configurar un pipeline de CI/CD y ejecutar tu servicio en cuestión de minutos. En este artículo, analizaremos la creación de una imagen Docker, la escritura de manifiestos para Kubernetes, la configuración de servicios e Ingress, y daremos consejos prácticos para la optimización.
\n\n1. Preparación de la aplicación Go y el Dockerfile
\n\nAntes de desplegar la aplicación en el clúster, es necesario empaquetarla en un contenedor. En Go, esto es especialmente conveniente gracias a la compilación estática.
\n\n1.1. Ejemplo de un servidor HTTP simple en Go
\n\nCreemos un servidor mínimo que responda a las solicitudes. Este es un microservicio típico para demostración.
\n\n// main.go\npackage main\n\nimport (\n "fmt"\n "net/http"\n "os"\n)\n\nfunc main() {\n port := os.Getenv("PORT")\n if port == "" {\n port = "8080"\n }\n\n http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {\n fmt.Fprintf(w, "¡Hola desde Go en Kubernetes!")\n })\n\n http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {\n w.WriteHeader(http.StatusOK)\n w.Write([]byte("OK"))\n })\n\n fmt.Printf("El servidor se está ejecutando en el puerto %s\\n", port)\n http.ListenAndServe(":"+port, nil)\n}\n\n\n1.2. Compilación multi-etapa del Dockerfile
\n\nUsamos compilación multi-etapa (multi-stage build) para minimizar el tamaño de la imagen final. Esto es crítico para una carga rápida en el clúster.
\n\n# ---- Primera etapa: compilación del binario ----\nFROM golang:1.21-alpine AS builder\n\nWORKDIR /app\nCOPY go.mod go.sum ./\nRUN go mod download\n\nCOPY . .\nRUN CGO_ENABLED=0 GOOS=linux go build -o /app/server .\n\n# ---- Segunda etapa: imagen mínima ----\nFROM alpine:latest\n\nRUN apk --no-cache add ca-certificates\n\nWORKDIR /root/\nCOPY --from=builder /app/server .\n\nEXPOSE 8080\n\nCMD ["./server"]\n\n\nImportante: la bandera CGO_ENABLED=0 desactiva CGO, lo que permite compilar un binario completamente estático que no requiere bibliotecas externas.
2. Creación de manifiestos de Kubernetes
\n\nAhora que tenemos la imagen, debemos describir cómo Kubernetes gestionará nuestra aplicación. Los objetos principales son: Deployment (para gestionar réplicas) y Service (para acceso de red).
\n\n2.1. Deployment
\n\nEl Deployment garantiza que la cantidad necesaria de pods con nuestra aplicación esté siempre en ejecución. Es importante configurar liveness y readiness probes para la recuperación automática.
\n\n// deployment.yaml\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: go-app\n labels:\n app: go-app\nspec:\n replicas: 2\n selector:\n matchLabels:\n app: go-app\n template:\n metadata:\n labels:\n app: go-app\n spec:\n containers:\n - name: go-app\n image: your-dockerhub-username/go-app:latest\n ports:\n - containerPort: 8080\n env:\n - name: PORT\n value: "8080"\n livenessProbe:\n httpGet:\n path: /health\n port: 8080\n initialDelaySeconds: 5\n periodSeconds: 10\n readinessProbe:\n httpGet:\n path: /health\n port: 8080\n initialDelaySeconds: 3\n periodSeconds: 5\n resources:\n requests:\n memory: "64Mi"\n