Deploying C# on Kubernetes: A Basic Practical Guide

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Deploying C# on Kubernetes: A Practical Guide for .NET Developers

\n\n

Modern development in C# (.NET) increasingly requires not just writing quality code, but also the ability to properly deploy an application in a production environment. Kubernetes (K8s) has become the de facto standard for container orchestration. In this article, we will walk through the step-by-step process of deploying a C# application on Kubernetes — from containerization to configuring Ingress.

\n\n

1. Preparing the .NET Application and Docker Image

\n\n

Before getting into Kubernetes, your C# application must be packaged into a Docker image. Let's consider a simple ASP.NET Core Web API.

\n\n

Create the project:

\n
dotnet new webapi -n MyK8sApp\ncd MyK8sApp
\n\n

Add a simple endpoint (file Program.cs):

\n
var builder = WebApplication.CreateBuilder(args);\nvar app = builder.Build();\n\napp.MapGet("/", () => "Hello from C# on Kubernetes!");\n\napp.Run();
\n\n

Now let's create a Dockerfile in the project root:

\n
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\n

Build and push the image to Docker Hub or a local registry:

\n
docker build -t yourdockerhub/my-k8s-app:v1 .\ndocker push yourdockerhub/my-k8s-app:v1
\n\n

Important: In ASP.NET Core 8+, the application listens on port 8080 by default, which is ideal for Kubernetes.

\n\n

2. Basic YAML Manifests for Kubernetes

\n\n

Kubernetes manages resources through YAML files. To run a C# application, we will need at least a Deployment and a Service.

\n\n

2.1. Deployment (deployment.yaml)

\n

The Deployment is responsible for maintaining the desired number of Pod replicas.

\n
apiVersion: 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\n

Key points:

\n
    \n
  • replicas: 3 — 3 instances of the application
  • \n
  • livenessProbe — health check (it is recommended to add a /health endpoint in C#)
  • \n
  • requests/limits resources help the K8s scheduler
  • \n
\n\n

2.2. Service (service.yaml)

\n

The Service provides a stable entry point to the Pods.

\n
apiVersion: 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\n

ClusterIP is an internal service, accessible only within the cluster. For external access, we use Ingress.

\n\n

3. Configuring Ingress and ConfigMap

\n\n

3.1. Ingress (ingress.yaml)

\n

Ingress provides external access to the service via a domain name.

\n
apiVersion: 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                

Blogs

Book Recommendations