Bereitstellung von C# auf Kubernetes: Ein praktischer Leitfaden für .NET-Entwickler
\n\nModerne C# (.NET)-Entwicklung erfordert zunehmend nicht nur das Schreiben von qualitativ hochwertigem Code, sondern auch die Fähigkeit, die Anwendung korrekt in einer Produktionsumgebung bereitzustellen. Kubernetes (K8s) ist zum De-facto-Standard für die Container-Orchestrierung geworden. In diesem Artikel werden wir den schrittweisen Prozess der Bereitstellung einer C#-Anwendung auf Kubernetes durchgehen – von der Containerisierung bis zur Konfiguration von Ingress.
\n\n1. Vorbereitung der .NET-Anwendung und des Docker-Images
\n\nBevor Ihre C#-Anwendung in Kubernetes gelangt, muss sie in ein Docker-Image verpackt werden. Betrachten wir eine einfache ASP.NET Core Web API.
\n\nErstellen Sie das Projekt:
\ndotnet new webapi -n MyK8sApp\ncd MyK8sApp\n\nFügen Sie einen einfachen Endpunkt hinzu (Datei Program.cs):
var builder = WebApplication.CreateBuilder(args);\nvar app = builder.Build();\n\napp.MapGet("/", () => "Hello from C# on Kubernetes!");\n\napp.Run();\n\nErstellen Sie nun ein Dockerfile im Projektstammverzeichnis:
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\nErstellen und pushen Sie das Image in Docker Hub oder eine lokale Registry:
\ndocker build -t yourdockerhub/my-k8s-app:v1 .\ndocker push yourdockerhub/my-k8s-app:v1\n\nWichtig: In ASP.NET Core 8+ lauscht die Anwendung standardmäßig auf Port 8080, was ideal für Kubernetes ist.
\n\n2. Grundlegende YAML-Manifeste für Kubernetes
\n\nKubernetes verwaltet Ressourcen über YAML-Dateien. Zum Ausführen einer C#-Anwendung benötigen wir mindestens ein Deployment und einen Service.
\n\n2.1. Deployment (deployment.yaml)
\nDas Deployment ist für die Aufrechterhaltung der gewünschten Anzahl von Pod-Replikaten verantwortlich.
\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: yourdockerhub/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\nWichtige Punkte:
\n- \n
replicas: 3— 3 Instanzen der Anwendung \n livenessProbe— Gesundheitsprüfung (es wird empfohlen, einen Endpunkt/healthin C# hinzuzufügen) \n - Ressourcen
requests/limitshelfen dem K8s-Scheduler \n
2.2. Service (service.yaml)
\nDer Service bietet einen stabilen Einstiegspunkt zu den 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 ist ein interner Service, der nur innerhalb des Clusters zugänglich ist. Für den externen Zugriff verwenden wir Ingress.
3. Konfiguration von Ingress und ConfigMap
\n\n3.1. Ingress (ingress.yaml)
\nIngress ermöglicht den Zugriff auf den Service von außen über einen Domainnamen.
\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: myapp.example.com\n http:\n paths:\n - path: /\n pathType: Prefix\n backend:\n ser