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

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

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

Начать курс

Введение: Почему C# и Kubernetes — это мощная связка

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

В этом руководстве мы пройдём путь от готового приложения на C# до его полноценного деплоя в кластер Kubernetes. Вы узнаете, как создать Docker-образ, написать манифесты для развертывания и сервиса, а затем запустить всё с помощью kubectl. Никакой магии — только практика.

Шаг 1: Подготовка .NET приложения и контейнеризация

1.1 Создание простого веб-API на C#

Для демонстрации мы создадим минимальный ASP.NET Core Web API. Откройте терминал и выполните:

dotnet new webapi -n MyK8sApp
cd MyK8sApp

По умолчанию проект уже содержит контроллер WeatherForecastController. Убедимся, что приложение запускается локально:

dotnet run

Перейдите по адресу http://localhost:5000/weatherforecast — вы должны увидеть JSON-ответ. Теперь наше приложение готово к упаковке.

1.2 Создание Dockerfile

Деплой в Kubernetes невозможен без контейнеризации. Создадим файл Dockerfile в корне проекта:

# Используем официальный образ для сборки
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /app

# Копируем файлы проекта и восстанавливаем зависимости
COPY *.csproj .
RUN dotnet restore

# Копируем остальные файлы и собираем приложение
COPY . .
RUN dotnet publish -c Release -o out

# Финальный образ — только runtime
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime
WORKDIR /app
COPY --from=build /app/out .
ENTRYPOINT ["dotnet", "MyK8sApp.dll"]

Обратите внимание: мы используем многоступенчатую сборку (multi-stage build) — это уменьшает итоговый размер образа и повышает безопасность.

1.3 Сборка и проверка Docker-образа

Соберите образ и запустите его локально:

docker build -t myk8sapp:latest .
docker run -d -p 8080:80 --name myapp myk8sapp:latest

Проверьте работу: http://localhost:8080/weatherforecast. Если всё работает — отлично. Остановите контейнер:

docker stop myapp && docker rm myapp

Шаг 2: Основы Kubernetes — что нужно знать для деплоя

Прежде чем писать манифесты, разберёмся с ключевыми понятиями Kubernetes:

  • Pod — минимальная единица развертывания. Содержит один или несколько контейнеров.
  • Deployment — управляет состоянием Pod'ов: масштабирование, обновления, восстановление после сбоев.
  • Service — абстракция, которая обеспечивает сетевой доступ к Pod'ам. Обычно используется типа ClusterIP (внутренний) или LoadBalancer (внешний).
  • ConfigMap / Secret — для хранения конфигурации и чувствительных данных.

Мы будем использовать minikube для локального тестирования. Установите его по официальной инструкции.

Запустите кластер:

minikube start

Шаг 3: Создание манифестов Kubernetes для C# приложения

3.1 Манифест Deployment

Создайте файл deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myk8sapp-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myk8sapp
  template:
    metadata:
      labels:
        app: myk8sapp
    spec:
      containers:
      - name: myk8sapp
        image: myk8sapp:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        env:
        - name: ASPNETCORE_ENVIRONMENT
          value: "Production"

Здесь мы указываем:

  • replicas: 3 — запустим 3 копии приложения для отказоустойчивости.
  • image: myk8sapp:latest — наш образ. Важно: для minikube образ должен быть доступен локально (см. ниже).
  • containerPort: 80 — приложение слушает порт 80 (как в Dockerfile).

Важно! Чтобы minikube использовал локальный образ, выполните:

minikube image load myk8sapp:latest

Либо укажите imagePullPolicy: Never.

3.2 Манифест Service

Создайте файл service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: myk8sapp-service
spec:
  type: NodePort
  selector:
    app: myk8sapp
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 30080

Тип NodePort позволяет обратиться к приложению через IP узла кластера и порт 30080. Для продакшена обычно используют LoadBalancer или Ingress.

Шаг 4: Развертывание и тестирование

4.1 Применение манифестов

Убедитесь, что вы находитесь в папке с deployment.yaml и service.yaml. Выполните команды:

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

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

Блоги

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