Установка CodeScoring.Save в Kubernetes

CodeScoring.Save устанавливается с помощью Helm-чарта save. Один и тот же чарт поддерживает два сценария развертывания:

  • стандартную установку в Kubernetes с PostgreSQL, Redis, а также поддержкой S3-совместимого объектного хранилища;
  • hosted-установку в одноузловом кластере k3s с SQLite и файловым хранилищем.

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

Установка с помощью Helm-чарта

Адреса Helm-репозитория и реестра контейнерных образов, а также учетные данные предоставляет вендор. В командах ниже используются следующие обозначения:

  • HELM_REPOSITORY_URL — адрес Helm-репозитория;
  • REGISTRY_URL — адрес реестра контейнерных образов;
  • USERNAME и PASSWORD — учетные данные для доступа;
  • CHART_VERSION — версия Helm-чарта и CodeScoring.Save.
  1. Создайте namespace:

    kubectl create namespace codescoring-save
  2. Создайте Secret для доступа к приватному реестру контейнерных образов:

    kubectl create secret docker-registry codescoring-regcred \
      --namespace codescoring-save \
      --docker-server=REGISTRY_URL \
      --docker-username=USERNAME \
      --docker-password=PASSWORD

    Имя Secret должно совпадать со значениями image.pullSecrets и osa-proxy.imagePullSecrets в values.yaml.

  3. Установите Helm и добавьте репозиторий CodeScoring.Save:

    helm repo add codescoring-save HELM_REPOSITORY_URL \
      --username USERNAME \
      --password PASSWORD
    helm repo update
  4. Скачайте и распакуйте чарт:

    helm pull codescoring-save/save \
      --version CHART_VERSION \
      --untar \
      --untardir codescoring-save-src
    cd codescoring-save-src/save

Настройка параметров Helm-чарта

Важно

Внесите необходимые изменения до первой установки. Перед обновлением установленной системы создайте резервные копии PostgreSQL и объектного хранилища.

Вся конфигурация инсталляции находится в values.yaml. Примеры ниже содержат только изменяемые фрагменты: остальные параметры из поставляемого файла необходимо сохранить.

Контейнерные образы

Основные компоненты используют общие реестр, тег и Secret для скачивания образов:

image:
  registry: REGISTRY_URL/save-docker
  tag: CHART_VERSION
  pullSecrets:
    - name: codescoring-regcred

OSA Proxy поставляется как зависимость чарта и имеет отдельные настройки образа:

osa-proxy:
  image:
    repository: REGISTRY_URL/save-docker/osa-proxy
    tag: OSA_PROXY_VERSION
  imagePullSecrets:
    - name: codescoring-regcred

Используйте версии образов, указанные в поставляемом values.yaml. Они проверены на совместимость с выбранной версией чарта.

Секреты приложения

Конфиденциальные параметры backend, worker, scheduler и auth находятся в secrets.save-secrets.data:

secrets:
  save-secrets:
    enabled: true
    data:
      SECRETS_ENCRYPTION_KEY: <STABLE_ENCRYPTION_KEY>
      DATABASE_NAME: save_db
      DATABASE_USER: save_user
      DATABASE_PASSWORD: <DATABASE_PASSWORD>
      REDIS_PASSWORD: ""
      S3_ACCESS_KEY: <S3_ACCESS_KEY>
      S3_SECRET_KEY: <S3_SECRET_KEY>
      AUTH_INTERNAL_SECRET: <AUTH_INTERNAL_SECRET>
      AUTH_ADMIN_PASSWORD: <ADMIN_PASSWORD>

SECRETS_ENCRYPTION_KEY используется для шифрования сохраненных учетных данных. Сгенерируйте его один раз, например командой openssl rand -base64 32, сохраните в защищенном хранилище и не меняйте при обновлениях. После смены ключа ранее сохраненные данные невозможно расшифровать.

Не храните рабочие пароли и ключи в системе контроля версий. Для продуктивной установки используйте защищенный файл значений или External Secrets.

PostgreSQL и Redis из Helm-чарта

По умолчанию чарт создает PostgreSQL и Redis как StatefulSet. Включите эти ресурсы и настройте PersistentVolumeClaim:

statefulSets:
  save-postgresql:
    enabled: true
  save-redis:
    enabled: true

services:
  redis:
    enabled: true

pvcs:
  save-postgresql:
    enabled: true
    accessModes:
      - ReadWriteOnce
    size: 20Gi
    storageClassName: "default"
  save-redis:
    enabled: true
    accessModes:
      - ReadWriteOnce
    size: 2Gi
    storageClassName: "default"

Замените storageClassName и размеры томов в соответствии с конфигурацией кластера и ожидаемым объемом данных.

Учетные данные встроенной PostgreSQL задаются отдельно и должны совпадать с параметрами DATABASE_NAME, DATABASE_USER и DATABASE_PASSWORD в secrets.save-secrets.data:

secrets:
  postgresql-secrets:
    enabled: true
    data:
      POSTGRES_DB: save_db
      POSTGRES_USER: save_user
      POSTGRES_PASSWORD: <DATABASE_PASSWORD>

Параметры подключения приложения к PostgreSQL и Redis находятся в ConfigMap save-backend-envs:

configMaps:
  save-backend-envs:
    enabled: true
    data:
      DATABASE_DRIVER: "postgres"
      DATABASE_HOST: "save-postgresql"
      DATABASE_PORT: "5432"
      REDIS_ENABLED: "true"
      REDIS_ADDR: "save-redis:6379"
      REDIS_DB: "0"

ConfigMap и Secret уже подключены к компонентам через deploymentsGeneral.envConfigmaps и deploymentsGeneral.envSecrets. При изменении полного values.yaml сохраните эти ссылки:

deploymentsGeneral:
  envConfigmaps:
    - save-backend-envs
  envSecrets:
    - save-secrets

Внешние PostgreSQL и Redis

Для внешней PostgreSQL отключите встроенный StatefulSet и его PVC, затем измените параметры подключения:

statefulSets:
  save-postgresql:
    enabled: false

pvcs:
  save-postgresql:
    enabled: false

configMaps:
  save-backend-envs:
    data:
      DATABASE_DRIVER: "postgres"
      DATABASE_HOST: "postgresql.example.com"
      DATABASE_PORT: "5432"

secrets:
  save-secrets:
    data:
      DATABASE_NAME: save_db
      DATABASE_USER: save_user
      DATABASE_PASSWORD: <DATABASE_PASSWORD>

База данных и пользователь должны быть созданы до установки CodeScoring.Save.

Для внешнего Redis отключите встроенные StatefulSet, Service и PVC:

statefulSets:
  save-redis:
    enabled: false

services:
  redis:
    enabled: false

pvcs:
  save-redis:
    enabled: false

configMaps:
  save-backend-envs:
    data:
      REDIS_ENABLED: "true"
      REDIS_ADDR: "redis.example.com:6379"
      REDIS_DB: "0"

secrets:
  save-secrets:
    data:
      REDIS_PASSWORD: <REDIS_PASSWORD>

S3-совместимое объектное хранилище

Текущий чарт не разворачивает S3-хранилище. Для стандартной Kubernetes-инсталляции заранее создайте бакет во внешнем S3-совместимом хранилище и укажите параметры подключения:

configMaps:
  save-backend-envs:
    data:
      STORAGE_TYPE: "s3"
      S3_REGION: "us-east-1"
      S3_BUCKET: "save"
      S3_ENDPOINT: "https://s3.example.com"
      S3_FORCE_PATH_STYLE: "true"

secrets:
  save-secrets:
    data:
      S3_ACCESS_KEY: <S3_ACCESS_KEY>
      S3_SECRET_KEY: <S3_SECRET_KEY>

Для хранилища, которое поддерживает virtual-hosted-style URL, установите S3_FORCE_PATH_STYLE: "false".

Hosted-установка в k3s

Hosted-вариант предназначен для односерверной установки в k3s и использует SQLite для метаданных и локальную файловую систему для артефактов.

Установите k3s и настройте доступ к кластеру:

curl -sfL https://get.k3s.io | sh -
sudo systemctl status k3s

mkdir -p ~/.kube
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown "$USER:$USER" ~/.kube/config
export KUBECONFIG=~/.kube/config

kubectl get nodes

Чтобы переключить стандартный профиль чарта на hosted, измените три переменные в configMaps.save-backend-envs.data:

configMaps:
  save-backend-envs:
    data:
      DATABASE_DRIVER: "sqlite"
      DATABASE_SQLITE_PATH: "./data/repository_manager.db"
      STORAGE_TYPE: "filesystem"

ConfigMap save-backend-envs подключен к backend, worker, scheduler и auth, поэтому дополнительные ConfigMap создавать не требуется. Остальные параметры из поставляемого values.yaml сохраните без изменений.

Компоненты worker и scheduler требуют PostgreSQL и не поддерживают работу с SQLite. В hosted-инсталляции обязательно отключите оба deployment:

deployments:
  worker:
    enabled: false
  scheduler:
    enabled: false

Постоянное хранение данных

Для hosted-установки нужны три отдельных постоянных тома:

  • db-data — база SQLite backend;
  • auth-data — база SQLite auth;
  • storage — файловое хранилище артефактов.

Подключите PVC к deployments через volumes и volumeMounts. Для auth также задайте пустое значение initContainers, чтобы удалить унаследованный init-контейнер wait-for-postgres:

deployments:
  save:
    containers:
      save:
        volumeMounts:
          - name: db-data
            mountPath: /app/data
          - name: storage
            mountPath: /app/storage
    volumes:
      - name: db-data
        type: pvc
      - name: storage
        type: pvc

  auth:
    initContainers:
    containers:
      auth:
        volumeMounts:
          - name: auth-data
            mountPath: /app/data
    volumes:
      - name: auth-data
        type: pvc

Backend и auth используют одинаковое значение DATABASE_SQLITE_PATH, но отдельные PVC, поэтому каждый сервис хранит собственную базу в своем каталоге /app/data. Значение STORAGE_ROOT_PATH по умолчанию — ./storage, что соответствует точке монтирования /app/storage при рабочем каталоге /app.

При использовании Dynamic Volume Provisioning укажите StorageClass для каждого PVC. Соответствующие PV будут созданы автоматически:

pvcs:
  db-data:
    accessModes:
      - ReadWriteOnce
    storageClassName: "default"
    size: 5Gi
  auth-data:
    accessModes:
      - ReadWriteOnce
    storageClassName: "default"
    size: 1Gi
  storage:
    accessModes:
      - ReadWriteOnce
    storageClassName: "default"
    size: 10Gi

Размеры томов и storageClassName необходимо подобрать с учетом нагрузки и конфигурации кластера.

Также можно использовать заранее созданные PV любого поддерживаемого Kubernetes типа. В этом случае создайте PV самостоятельно или опишите их в секции pvs, а в каждом PVC задайте пустой storageClassName и соответствующий volumeName, например:

pvs:
  db-data:
    accessModes:
      - ReadWriteMany
    size: 5Gi
    storageClassName: ""
    mountOptions:
      - nfsvers=4.2
    nfs:
      server: nfs.example.com
      path: /exports/codescoring-save/db-data

pvcs:
  db-data:
    accessModes:
      - ReadWriteMany
    storageClassName: ""
    volumeName: codescoring-save-db-data
    size: 5Gi

В примере для Helm-релиза codescoring-save чарт создает PV codescoring-save-db-data из секции pvs.db-data, а PVC явно привязывается к нему через volumeName. Замените адрес NFS-сервера и путь экспорта значениями своей инфраструктуры.

Аналогично создайте и привяжите тома auth-data и storage. Конкретный источник тома может быть NFS, CSI, локальным диском или другим хранилищем; параметры зависят от инфраструктуры кластера.

Опциональный Redis

Redis не обязателен для hosted-установки. Чтобы запустить Save без Redis, выключите его в конфигурации приложения и отключите связанные StatefulSet, Service и PVC:

configMaps:
  save-backend-envs:
    data:
      REDIS_ENABLED: "false"

statefulSets:
  save-redis:
    enabled: false

services:
  redis:
    enabled: false

pvcs:
  save-redis:
    enabled: false

Если Redis используется, сохраните REDIS_ENABLED: "true", оставьте его StatefulSet, Service и PVC включенными.

SQLite рассчитана на работу одной реплики. Не увеличивайте deploymentsGeneral.replicas и отключите автоматическое масштабирование backend и worker:

deploymentsGeneral:
  replicas: 1

hpas:
  save:
    enabled: false
  worker:
    enabled: false

После переключения приложение не использует PostgreSQL. Чтобы не создавать неиспользуемые ресурсы, можно дополнительно отключить StatefulSet и PVC:

statefulSets:
  save-postgresql:
    enabled: false

pvcs:
  save-postgresql:
    enabled: false
Важно

SQLite и файловое хранилище подходят только для односерверной установки. Каталоги с базами SQLite и артефактами должны находиться на сохраняемом диске k3s и регулярно копироваться. Не используйте этот профиль для многорепличного развертывания.

Ingress

По умолчанию Ingress выключен. Чтобы открыть веб-интерфейс и API, включите его и замените доменное имя:

ingresses:
  ingress:
    enabled: true
    ingressClassName: nginx
    hosts:
      - hostname: save.example.com
        paths:
          - path: /
            serviceName: frontend
            servicePort: 8081
    tls:
      - hosts:
          - save.example.com
        secretName: save-tls

configMaps:
  save-frontend-envs:
    data:
      NGINX_HOST: "save.example.com"
      NGINX_PORT: "8081"

Если TLS завершается на внешнем балансировщике, настройте tls и аннотации Ingress в соответствии с инфраструктурой кластера.

HTTPRoute (Gateway API)

Если в кластере используется Kubernetes Gateway API, настройте маршрут к frontend через секцию httpRoutes. Ресурс Gateway, на который ссылается маршрут, должен существовать до установки CodeScoring.Save.

httpRoutesGeneral: {}
httpRoutes:
  save:
    gatewayName: codescoring-gateway
    gatewayNamespace: gateway-system
    gatewaySectionName: https
    gatewayKind: Gateway
    gatewayGroup: gateway.networking.k8s.io
    hostnames:
      - "save.example.com"
    rules:
      - matches:
          - path:
              type: PathPrefix
              value: /
        backendRefs:
          - name: codescoring-save-frontend
            port: 8081

configMaps:
  save-frontend-envs:
    data:
      NGINX_HOST: "save.example.com"
      NGINX_PORT: "8081"

Значения gatewayName, gatewayNamespace, gatewaySectionName и hostnames должны соответствовать Gateway и DNS-имени в вашем кластере.

Важно

Значение backendRefs.name формируется как {helm-release-name}-frontend. Например, для команды helm install codescoring-save ... необходимо указать name: codescoring-save-frontend.

OSA Proxy

OSA Proxy отключена по умолчанию. Для ее включения необходимо выставить поле osa-proxy.enabled в значение true. В существующем блоке osa-proxy.config.content замените значение codescoring.url на адрес инсталляции CodeScoring. Токен передайте через Secret osa-proxy:

osa-proxy:
  enabled: true
  secret:
    create: true
    stringData:
      CODESCORING_TOKEN: <CODESCORING_TOKEN>

Если проверка компонентов через OSA Proxy не требуется, отключите зависимость:

osa-proxy:
  enabled: false

osa-proxy.config.content содержит полную конфигурацию сервиса. При ее изменении сохраните остальные секции из поставляемого values.yaml.

Ограничения ресурсов

В поставляемом values.yaml ресурсы контейнеров не ограничены. Для продуктивной установки задайте requests и limits для каждого компонента по результатам нагрузочного тестирования:

deployments:
  save:
    containers:
      save:
        resources:
          requests:
            cpu: 500m
            memory: 1Gi
          limits:
            cpu: "2"
            memory: 4Gi
  worker:
    containers:
      worker:
        resources:
          requests:
            cpu: 500m
            memory: 1Gi
          limits:
            cpu: "2"
            memory: 4Gi

Аналогично настройте deployments.scheduler, deployments.auth, deployments.save-frontend, statefulSets.save-postgresql и statefulSets.save-redis. Для корректной работы HPA у масштабируемых контейнеров должны быть заданы CPU requests.

External Secrets

Чарт может получать секреты из внешнего хранилища через External Secrets Operator. В кластере должны быть заранее установлены оператор и SecretStore или ClusterSecretStore.

Включите нужный ресурс в секции vaults:

vaults:
  save-secrets-external:
    apiVersion: external-secrets.io/v1
    enabled: true
    store:
      name: vault-backend
      kind: ClusterSecretStore
    path: save-secrets

Затем подключите создаваемый Secret к deployments:

deploymentsGeneral:
  envConfigmaps:
    - save-backend-envs
  envSecrets:
    - save-secrets-external

Для встроенной PostgreSQL аналогично настройте vaults.postgresql-secrets-external и подключите Secret в statefulSets.save-postgresql.envSecrets.

Установка

Из каталога распакованного чарта выполните:

helm install codescoring-save . \
  --namespace codescoring-save \
  --values values.yaml \
  --atomic

Для обновления существующей инсталляции используйте ту же версию настроенного values.yaml:

helm upgrade codescoring-save . \
  --namespace codescoring-save \
  --values values.yaml \
  --atomic

Проверка установки

Проверьте состояние ресурсов:

kubectl get pods -n codescoring-save
kubectl get statefulset,pvc -n codescoring-save
kubectl get service,ingress -n codescoring-save

Все Pod должны перейти в состояние Running, а их контейнеры — быть готовы. Для диагностики используйте логи компонентов:

kubectl logs -n codescoring-save -l app=backend --tail=100
kubectl logs -n codescoring-save -l app=worker --tail=100
kubectl logs -n codescoring-save -l app=scheduler --tail=100
kubectl logs -n codescoring-save -l app=auth --tail=100
kubectl logs -n codescoring-save -l app=frontend --tail=100

После установки откройте адрес, указанный в Ingress, и войдите с паролем из AUTH_ADMIN_PASSWORD.

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

После успешной установки:

  1. Создайте первый репозиторий.
  2. Настройте политики очистки.
  3. Создайте пользователей и назначьте роли.
Страница была полезна?