Дизайн платформы

Темы для обсуждения и принятия решений

Темы для обсуждения и принятия решений

Дата создания

2025-11-29


1. Backend Инфраструктурный - Управление K8s

Вопрос

Каким способом Backend Инфраструктурный будет управлять развёртываниями в Kubernetes?

Варианты решения

Вариант A: Python Kubernetes Client (прямой API)

Описание: Использование официального Python клиента для K8s API.

from kubernetes import client, config

# Создание пода
api = client.CoreV1Api()
pod = client.V1Pod(
    metadata=client.V1ObjectMeta(name="lab-xxx"),
    spec=client.V1PodSpec(containers=[...])
)
api.create_namespaced_pod(namespace="labs", body=pod)

Плюсы:

  • ✅ Максимальная гибкость
  • ✅ Прямой контроль над всеми ресурсами K8s
  • ✅ Не требует внешних зависимостей (Terraform, Helm)
  • ✅ Легко интегрируется с FastAPI/Celery
  • ✅ Быстрая обработка (меньше оверхеда)

Минусы:

  • ❌ Необходимо самостоятельно писать всю логику управления
  • ❌ Больше кода для поддержки
  • ❌ Нет декларативного подхода "из коробки"

Подходит для:

  • Динамических развёртываний (каждая лабораторная работа уникальна)
  • Быстрого создания/удаления ресурсов
  • Программной генерации манифестов на основе конфигурации

Вариант B: Terraform

Описание: Использование Terraform для управления K8s ресурсами.

resource "kubernetes_pod" "lab" {
  metadata {
    name      = "lab-xxx"
    namespace = "labs"
  }
  spec {
    container {
      image = "lab-image:latest"
      name  = "lab-container"
    }
  }
}

Плюсы:

  • ✅ Декларативный подход (Infrastructure as Code)
  • ✅ State management (отслеживание состояния)
  • ✅ Хорошо подходит для статичной инфраструктуры
  • ✅ Удобное планирование изменений (terraform plan)

Минусы:

  • ❌ Оверхед на запуск Terraform для каждой операции
  • ❌ Требуется хранение state файлов
  • ❌ Сложнее для динамических задач (создание/удаление сотен подов)
  • ❌ Медленнее, чем прямой API

Подходит для:

  • Управления базовой инфраструктурой (namespace, ingress, statefulsets)
  • Развёртывания стабильных компонентов (не лабораторных работ)

Вариант C: Helm

Описание: Использование Helm charts для развёртывания лабораторных работ.

helm install lab-xxx ./lab-chart --set student=student1

Плюсы:

  • ✅ Шаблонизация (переиспользование конфигураций)
  • ✅ Управление версиями (rollback)
  • ✅ Широкая поддержка сообществом

Минусы:

  • ❌ Оверхед на запуск Helm CLI
  • ❌ Необходимость создания chart для каждого типа лабораторной работы
  • ❌ Сложнее для полностью динамических конфигураций

Подходит для:

  • Стандартизированных лабораторных работ с параметризацией
  • Управления версиями конфигураций

Вариант D: Гибридный подход

Описание: Комбинация разных инструментов для разных задач.

Примерное разделение:

  • Terraform: Базовая инфраструктура (namespace, ingress, statefulsets данных)
  • Python K8s Client: Динамические лабораторные работы (pods, services в namespace: labs)
  • Helm (опционально): Стандартные компоненты (monitoring, rabbitmq)

Плюсы:

  • ✅ Используем лучшие инструменты для конкретных задач
  • ✅ Terraform для стабильной инфраструктуры
  • ✅ Python API для быстрых динамических операций

Минусы:

  • ❌ Сложность поддержки нескольких инструментов
  • ❌ Необходимость знать все инструменты

Рекомендация (для обсуждения)

Предлагаю Вариант D (Гибридный):

┌─────────────────────────────────────────┐
│ Terraform (Infrastructure as Code)     │
│ - Namespace (platform, data, labs, etc) │
│ - Ingress Controller                    │
│ - StatefulSets (PostgreSQL, Redis)      │
│ - RabbitMQ, Zitadel                     │
└─────────────────────────────────────────┘
                    ↓
        Разовое развёртывание при инициализации

┌─────────────────────────────────────────┐
│ Python Kubernetes Client (Dynamic)     │
│ - Поды лабораторных работ              │
│ - Services для лабораторных работ      │
│ - Network Policies (динамические)      │
│ - PersistentVolumeClaims               │
└─────────────────────────────────────────┘
                    ↓
        Постоянные операции (создание/удаление лаб)

Логика:

  1. Terraform настраивает базовую инфраструктуру один раз (или при изменениях)
  2. Backend Инфраструктурный использует Python Kubernetes Client для управления жизненным циклом лабораторных работ

2. GitLab и CI/CD

Вопрос 2.1: Где размещать GitLab?

Вариант A: GitLab внутри K8s

Плюсы:

  • ✅ Единая инфраструктура
  • ✅ Легче управлять через K8s манифесты
  • ✅ Использование PersistentVolumes для данных

Минусы:

  • ❌ Высокое потребление ресурсов (GitLab тяжёлый)
  • ❌ Усложнение кластера (12-24 CPU может не хватить)
  • ❌ Зависимость: если кластер падает, CI/CD тоже

Требования ресурсов GitLab:

  • Минимум: 4 CPU, 8 GB RAM
  • Рекомендуется: 8 CPU, 16 GB RAM

Вариант B: GitLab вне K8s (отдельная VM)

Плюсы:

  • ✅ Независимость от K8s кластера
  • ✅ Не тратит ресурсы кластера
  • ✅ Проще восстановление при проблемах с кластером

Минусы:

  • ❌ Требуется отдельный сервер/VM
  • ❌ Ещё одна инфраструктура для поддержки

Вопрос 2.2: Как GitLab Runner деплоит в K8s?

Вариант A: kubectl apply

Описание: GitLab Runner напрямую применяет манифесты через kubectl.

# .gitlab-ci.yml
deploy:
  script:
    - kubectl apply -f k8s/manifests/

Плюсы:

  • ✅ Простота
  • ✅ Прямой контроль

Минусы:

  • ❌ Нет управления версиями
  • ❌ Сложно делать rollback

Вариант B: Helm

Описание: GitLab Runner использует Helm для деплоя.

# .gitlab-ci.yml
deploy:
  script:
    - helm upgrade --install backend-platform ./helm/backend-platform

Плюсы:

  • ✅ Управление версиями
  • ✅ Легко делать rollback
  • ✅ Параметризация

Минусы:

  • ❌ Требуется создание Helm charts

Вариант C: ArgoCD (GitOps)

Описание: ArgoCD автоматически синхронизирует состояние кластера с Git репозиторием.

Git Repository → ArgoCD → K8s Cluster
    (Source of Truth)

Плюсы:

  • ✅ Декларативный GitOps подход
  • ✅ Автоматическая синхронизация
  • ✅ Удобный UI для мониторинга
  • ✅ Автоматический rollback

Минусы:

  • ❌ Дополнительный компонент в кластере
  • ❌ Требует изучения нового инструмента

Рекомендация (для обсуждения)

Для начала (MVP):

  • GitLab: Вне K8s (отдельная VM, экономим ресурсы кластера)
  • Деплой: kubectl apply (простота, быстрый старт)

Для будущего:

  • Переход на Helm или ArgoCD для production окружения

3. Хранение Docker образов

Вопрос

Где хранить Docker образы для лабораторных работ и сервисов платформы?

Варианты решения

Вариант A: GitLab Container Registry

Плюсы:

  • ✅ Встроенный в GitLab
  • ✅ Интеграция с CI/CD
  • ✅ Бесплатный (self-hosted)

Минусы:

  • ❌ Требует GitLab (зависимость)

Вариант B: Harbor (CNCF проект)

Плюсы:

  • ✅ Специализированный registry
  • ✅ Vulnerability scanning
  • ✅ Репликация, access control

Минусы:

  • ❌ Дополнительный компонент для установки
  • ❌ Потребляет ресурсы

Вариант C: Minio (как Docker registry)

Описание: Minio может использоваться как backend для Docker registry.

Плюсы:

  • ✅ Уже используем Minio
  • ✅ S3-совместимый

Минусы:

  • ❌ Требуется настройка Docker Registry с S3 backend
  • ❌ Сложнее интеграция

Вариант D: DockerHub / внешний registry

Плюсы:

  • ✅ Не требует собственной инфраструктуры
  • ✅ Высокая доступность

Минусы:

  • ❌ Зависимость от внешнего сервиса
  • ❌ Ограничения rate limit (DockerHub)
  • ❌ Возможные проблемы с приватными образами

Рекомендация (для обсуждения)

GitLab Container Registry (если GitLab будет использоваться)

Логика хранения:

  • GitLab Container Registry: Образы сервисов платформы (backend, frontend, celery)
  • Minio: Конфигурации лабораторных работ (YAML, scripts, Dockerfiles)

Вопрос: Нужно ли хранить готовые образы лабораторных работ или строить их на лету из конфигураций в Minio?


4. PersistentVolumes для переиспользования

Вопрос

Как хранить volumes лабораторных работ для переиспользования?

Контекст

Преподаватель запускает лабу, студенты работают, лаба останавливается. При повторном запуске нужно восстановить состояние (файлы, изменения).

Варианты решения

Вариант A: PersistentVolumeClaims (PVC)

Описание: Использование стандартных K8s PVC для хранения volumes.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: lab-xxx-student1-volume
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi

Плюсы:

  • ✅ Стандартный K8s подход
  • ✅ Быстрый доступ (локальное хранилище на нодах)
  • ✅ Автоматическое управление lifecycle

Минусы:

  • ❌ Занимает место на нодах
  • ❌ Сложно переносить между кластерами

Вариант B: Minio (архивация)

Описание: После остановки лабы volumes архивируются (tar.gz) и загружаются в Minio.

# Остановка лабы
tar -czf lab-xxx-student1-volume.tar.gz /path/to/volume
mc cp lab-xxx-student1-volume.tar.gz minio/labs/volumes/

# Восстановление
mc cp minio/labs/volumes/lab-xxx-student1-volume.tar.gz ./
tar -xzf lab-xxx-student1-volume.tar.gz

Плюсы:

  • ✅ Не занимает место в кластере
  • ✅ Легко переносить между кластерами
  • ✅ Долгосрочное хранение

Минусы:

  • ❌ Медленнее восстановление (распаковка архива)
  • ❌ Требует ручной логики архивации/восстановления

Вариант C: Гибридный

Логика:

  • Короткий срок (активные лабы): PVC остаются в кластере
  • Долгий срок (завершённые лабы): Архивация в Minio, удаление PVC

Плюсы:

  • ✅ Оптимизация ресурсов
  • ✅ Быстрый доступ для активных лаб

Рекомендация (для обсуждения)

Вариант C (Гибридный):

  1. Активные лабораторные работы → PVC
  2. Завершённые лабораторные работы → Архивация в Minio, удаление PVC
  3. Политика TTL (Time To Live): через N дней автоматическая архивация

5. Что такое PersistentVolume (Персистентность)?

Объяснение

Проблема без персистентности:

Pod создан → Данные записаны в контейнер → Pod удалён → Данные ПОТЕРЯНЫ

С персистентностью (PersistentVolume):

Pod создан → Данные записаны в PersistentVolume → Pod удалён → Данные СОХРАНЕНЫ

Пример: PostgreSQL хранит данные в /var/lib/postgresql/data.

  • Без PV: При перезапуске пода база данных пустая.
  • С PV: При перезапуске пода данные восстанавливаются.

Для лабораторных работ: Студент работает, создаёт файлы → Лаба останавливается → При следующем запуске файлы должны быть на месте.


6. Структура образов и builds для лабораторных работ

Вопрос

Как организовать хранение, билд и развёртывание образов для лабораторных работ?

Варианты решения

Вариант A: Готовые образы в Registry

Процесс:

  1. Преподаватель создаёт Dockerfile
  2. Образ билдится и пушится в GitLab Container Registry
  3. Конфигурация лабораторной работы (YAML) хранится в Minio
  4. Backend Инфраструктурный создаёт pod с указанием образа из registry

Плюсы:

  • ✅ Быстрое развёртывание (образ уже собран)
  • ✅ Стандартный подход

Минусы:

  • ❌ Требуется предварительный билд
  • ❌ Занимает место в registry

Вариант B: Dockerfile в Minio, билд на лету

Процесс:

  1. Преподаватель загружает Dockerfile и зависимости в Minio
  2. Backend Инфраструктурный скачивает Dockerfile
  3. Образ билдится через BuildKit / Kaniko в кластере
  4. Временный образ используется для создания пода

Плюсы:

  • ✅ Не требуется предварительный билд
  • ✅ Гибкость (быстрые изменения)

Минусы:

  • ❌ Медленнее (билд при каждом запуске)
  • ❌ Сложность реализации

Вариант C: Гибридный (кэширование)

Процесс:

  1. Преподаватель загружает конфигурацию (Dockerfile или ссылка на образ)
  2. При первом запуске:
    • Если Dockerfile → билд и сохранение в registry
    • Если образ → использование напрямую
  3. При повторных запусках → использование закэшированного образа

Плюсы:

  • ✅ Гибкость + производительность
  • ✅ Кэш для частых лабораторных работ

Рекомендация (для обсуждения)

Вариант A (Готовые образы) для MVP:

  • Преподаватель готовит образы заранее
  • Конфигурация (YAML) в Minio указывает на образ

Будущее:

  • Добавить билд на лету (Вариант C) для динамических сценариев

7. Доступ к лабораторным работам

Вопрос

Как студенты будут подключаться к лабораторным работам?

Варианты решения

Вариант A: SSH

Процесс:

  1. Backend Инфраструктурный создаёт pod с SSH сервером
  2. Kubernetes Service (NodePort или LoadBalancer) открывает доступ
  3. Студенты получают: ssh user@<IP>:<PORT> + пароль/ключ

Плюсы:

  • ✅ Универсальность (работает для любых лабораторных)
  • ✅ Студенты могут использовать свои SSH клиенты
  • ✅ Поддержка SCP/SFTP для передачи файлов

Минусы:

  • ❌ Требует настройки SSH в каждом образе лабораторной работы
  • ❌ Управление ключами/паролями

Вариант B: Web-терминал (browser-based)

Технологии: ttyd, Wetty, Guacamole

Процесс:

  1. Pod с web-терминалом
  2. Ingress предоставляет доступ через URL: https://ksailab.ru/lab/xxx/terminal
  3. Студенты открывают браузер и работают

Плюсы:

  • ✅ Не требует SSH клиента (работает в браузере)
  • ✅ Упрощённый доступ для студентов

Минусы:

  • ❌ Меньше гибкости (нет SCP, нельзя использовать свои редакторы)
  • ❌ Зависимость от браузера

Вариант C: VNC/RDP (для графических лаб)

Для лабораторных с GUI (например, анализ малвари в Windows).

Технологии: noVNC, Apache Guacamole

Плюсы:

  • ✅ Полноценный GUI
  • ✅ Доступ через браузер

Минусы:

  • ❌ Высокое потребление ресурсов
  • ❌ Сложность настройки

Рекомендация (для обсуждения)

Основной способ: SSH (Вариант A)

  • Универсальность, гибкость

Дополнительно: Web-терминал (Вариант B)

  • Для упрощённых лабораторных работ

Будущее: VNC/RDP (Вариант C)

  • Для специфических GUI лабораторных

8. Сетевая изоляция лабораторных работ

Вопрос

Как реализовать переключаемый доступ в интернет и изоляцию?

Решение: Kubernetes Network Policies

Пример: Запрет доступа в интернет

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: lab-xxx-no-internet
  namespace: labs
spec:
  podSelector:
    matchLabels:
      lab: lab-xxx
  policyTypes:
  - Egress
  egress:
  - to:
    - podSelector: {}  # Только внутри namespace

Пример: Разрешить доступ в интернет

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: lab-xxx-internet-allowed
  namespace: labs
spec:
  podSelector:
    matchLabels:
      lab: lab-xxx
  policyTypes:
  - Egress
  egress:
  - to:
    - namespaceSelector: {}
    - podSelector: {}
  - to:
    - ipBlock:
        cidr: 0.0.0.0/0  # Весь интернет

Конфигурация в YAML лабораторной работы:

lab:
  name: "SQL Injection Lab"
  network:
    internet_access: false  # true/false
    isolation: "student"    # student / group / shared

Следующие шаги

  1. Обсудить каждую тему и принять решения
  2. Обновить architecture-overview.md с принятыми решениями
  3. Создать детальные технические спецификации для каждого компонента
  4. Разработать прототипы для критичных компонентов (управление K8s, изоляция лаб)

Приоритизация обсуждения

Критичные (для MVP):

  1. ✅ Backend Инфраструктурный - Управление K8s
  2. ✅ Хранение Docker образов
  3. ✅ Доступ к лабораторным работам (SSH vs Web)

Важные (для функциональности):

  1. PersistentVolumes для переиспользования
  2. GitLab размещение

Можно отложить:

  1. Детальная структура билдов
  2. VNC/RDP доступ