Despliegue de C# en Kubernetes: guía práctica para desarrolladores .NET
\n\nEl desarrollo moderno en C# (.NET) cada vez requiere no solo escribir código de calidad, sino también saber cómo desplegar correctamente la aplicación en un entorno de producción. Kubernetes (K8s) se ha convertido en el estándar de facto para la orquestación de contenedores. En este artículo, analizaremos el proceso paso a paso para desplegar una aplicación C# en Kubernetes, desde la contenerización hasta la configuración de Ingress.
\n\n1. Preparación de la aplicación .NET y la imagen Docker
\n\nAntes de llegar a Kubernetes, su aplicación C# debe estar empaquetada en una imagen Docker. Consideremos una API Web ASP.NET Core simple.
\n\nCree el proyecto:
\ndotnet new webapi -n MyK8sApp\ncd MyK8sApp\n\nAgregue un endpoint simple (archivo Program.cs):
var builder = WebApplication.CreateBuilder(args);\nvar app = builder.Build();\n\napp.MapGet("/", () => "¡Hola desde C# en Kubernetes!");\n\napp.Run();\n\nAhora creemos un Dockerfile en la raíz del proyecto:
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base\nWORKDIR /app\nEXPOSE 8080\n\nFROM mcr.microsoft.com/dotnet/sdk:8.0 AS build\nWORKDIR /src\nCOPY ["MyK8sApp.csproj", "."]\nRUN dotnet restore\nCOPY . .\nRUN dotnet publish -c Release -o /app/publish\n\nFROM base AS final\nWORKDIR /app\nCOPY --from=build /app/publish .\nENTRYPOINT ["dotnet", "MyK8sApp.dll"]\n\nConstruya y suba la imagen a Docker Hub o a un registro local:
\ndocker build -t tudockerhub/my-k8s-app:v1 .\ndocker push tudockerhub/my-k8s-app:v1\n\nImportante: En ASP.NET Core 8+, por defecto la aplicación escucha en el puerto 8080, lo cual es ideal para Kubernetes.
\n\n2. Manifiestos YAML principales para Kubernetes
\n\nKubernetes gestiona los recursos a través de archivos YAML. Para ejecutar una aplicación C#, necesitaremos al menos un Deployment y un Service.
\n\n2.1. Deployment (deployment.yaml)
\nEl Deployment se encarga de mantener el número deseado de réplicas de Pods.
\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: my-k8s-app-deployment\nspec:\n replicas: 3\n selector:\n matchLabels:\n app: my-k8s-app\n template:\n metadata:\n labels:\n app: my-k8s-app\n spec:\n containers:\n - name: my-k8s-app\n image: tudockerhub/my-k8s-app:v1\n ports:\n - containerPort: 8080\n resources:\n requests:\n memory: "64Mi"\n cpu: "250m"\n limits:\n memory: "128Mi"\n cpu: "500m"\n livenessProbe:\n httpGet:\n path: /health\n port: 8080\n initialDelaySeconds: 5\n periodSeconds: 10\n\nPuntos clave:
\n- \n
replicas: 3— 3 instancias de la aplicación \n livenessProbe— verificación de estado (se recomienda agregar un endpoint/healthen C#) \n - Los recursos
requests/limitsayudan al planificador de K8s \n
2.2. Service (service.yaml)
\nEl Service proporciona un punto de entrada estable a los Pods.
\napiVersion: v1\nkind: Service\nmetadata:\n name: my-k8s-app-service\nspec:\n selector:\n app: my-k8s-app\n ports:\n - protocol: TCP\n port: 80\n targetPort: 8080\n type: ClusterIP\n\nClusterIP es un servicio interno, accesible solo dentro del clúster. Para acceso externo, usamos Ingress.
3. Configuración de Ingress y ConfigMap
\n\n3.1. Ingress (ingress.yaml)
\nIngress permite el acceso externo al servicio mediante un nombre de dominio.
\napiVersion: networking.k8s.io/v1\nkind: Ingress\nmetadata:\n name: my-k8s-app-ingress\n annotations:\n nginx.ingress.kubernetes.io/rewrite-target: /\nspec:\n rules:\n - host: miapp.ejemplo.com\n http:\n paths:\n - path: /\n pathType: Prefix\n backend:\n ser