Деплой C# на Kubernetes: базовое руководство на практике

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Деплой C# на Kubernetes: практическое руководство для .NET разработчиков

Современная разработка на C# (.NET) всё чаще требует не просто написания качественного кода, но и умения правильно развернуть приложение в production-среде. Kubernetes (K8s) стал стандартом де-факто для оркестрации контейнеров. В этой статье мы разберем пошаговый процесс деплоя C# приложения на Kubernetes — от контейнеризации до настройки Ingress.

1. Подготовка .NET приложения и Docker-образ

Прежде чем попасть в Kubernetes, ваше C# приложение должно быть упаковано в Docker-образ. Рассмотрим простой ASP.NET Core Web API.

Создайте проект:

dotnet new webapi -n MyK8sApp
cd MyK8sApp

Добавьте простой endpoint (файл Program.cs):

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", () => "Hello from C# on Kubernetes!");

app.Run();

Теперь создадим Dockerfile в корне проекта:

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
EXPOSE 8080

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["MyK8sApp.csproj", "."]
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "MyK8sApp.dll"]

Соберите и запушите образ в Docker Hub или локальный registry:

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

Важно: В ASP.NET Core 8+ по умолчанию приложение слушает порт 8080, что идеально для Kubernetes.

2. Основные YAML-манифесты для Kubernetes

Kubernetes управляет ресурсами через YAML-файлы. Для запуска C# приложения нам понадобятся как минимум Deployment и Service.

2.1. Deployment (deployment.yaml)

Deployment отвечает за поддержание нужного количества реплик Pod'ов.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-k8s-app-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-k8s-app
  template:
    metadata:
      labels:
        app: my-k8s-app
    spec:
      containers:
      - name: my-k8s-app
        image: yourdockerhub/my-k8s-app:v1
        ports:
        - containerPort: 8080
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 10

Ключевые моменты:

  • replicas: 3 — 3 экземпляра приложения
  • livenessProbe — проверка здоровья (рекомендуется добавить endpoint /health в C#)
  • Ресурсы requests/limits помогают планировщику K8s

2.2. Service (service.yaml)

Service обеспечивает стабильную точку входа к Pod'ам.

apiVersion: v1
kind: Service
metadata:
  name: my-k8s-app-service
spec:
  selector:
    app: my-k8s-app
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080
  type: ClusterIP

ClusterIP — внутренний сервис, доступный только внутри кластера. Для внешнего доступа используем Ingress.

3. Настройка Ingress и ConfigMap

3.1. Ingress (ingress.yaml)

Ingress открывает доступ к сервису извне по доменному имени.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-k8s-app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-k8s-app-service
            port:
              number: 80

Для работы Ingress необходим Ingress Controller (например, NGINX Ingress Controller), который нужно установить в кластер отдельно.

3.2. ConfigMap для конфигурации

Хранить строки подключения и настройки в коде — плохая практика. Используем ConfigMap.

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  appsettings.json: |
    {
      "Logging": {
        "LogLevel": {
          "Default": "Information"
        }
      },
      "ConnectionStrings": {
        "Default": "Server=db;Database=mydb;User=sa;Password=Your_password123;"
      }
    }

В Deployment монтируем ConfigMap как volume:

volumes:
- name: config
  configMap:
    name: app-config
containers:
- name: my-k8s-app
  volumeMounts:
  - name: config
    mountPath: /app/config

В C# коде читаем конфигурацию стандартным способом через IConfiguration.

4. Деплой и проверка

Примените все манифесты в кластер (например, Minikube или облачный K8s):

kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl apply -f ingress.yaml
kubectl apply -f configmap.yaml

Проверьте статус:

kubectl get pods
kubectl get svc
kubectl get ingress

Для тестирования локально (Minikube):

minikube tunnel
# Затем в браузере: http://myapp.example.com

Если всё настроено верно, вы увидите: "Hello from C# on Kubernetes!"

Заключение

Мы рассмотрели полный цикл деплоя C# (.NET) приложения в Kubernetes: от создания Docker-образа до настройки Ingress. Этот процесс — основа для построения масштабируемых, отказоустойчивых микросервисов на C#.

Блоги

Рекомендаций по книгам