Running CodeScoring in Kubernetes
Installation with a Helm chart
Installation procedure:
-
Create a namespace.
kubectl create namespace codescoring
-
Create a secret for accessing the private Docker image registry for CodeScoring. Use the registry address (REGISTRY_URL), login (USERNAME), and password (PASSWORD) received from the vendor.
kubectl create secret docker-registry codescoring-regcred --docker-server=REGISTRY_URL --docker-username=USERNAME --docker-password=PASSWORD -n codescoring
Alternatively, you can create a registry access secret through values.yaml by adding the following entry to .Values.imagePullSecrets:
registry.org: |
{"auths":{"registry.org":{"auth":"<base64>"}}}
-
Install Helm using your preferred method.
-
Run the following commands to add the current Helm repository to the local machine:
helm repo add codescoring-org https://{REGISTRY_URL}/repository/helm/ --username USERNAME --password PASSWORD
helm repo update
Helm chart settings
Important
It is strongly recommended to make the necessary changes before installing CodeScoring. Otherwise, a complete system reinstall may be required. These instructions assume that the specialist has experience working with Kubernetes clusters and Helm.
Tip
All resource limits shown in this document are approximate. Actual resource consumption depends on installation load and specific usage scenarios.
To edit CodeScoring parameters conveniently, download and unpack the Helm chart source code:
helm pull codescoring-org/codescoring-helm --version CHART_VERSION --untar --untardir codescoring-src && cd codescoring-src
In values.yaml, edit the required variables and then run the installation command from the Helm chart source directory:
helm install codescoring . -f values.yaml -n codescoring --atomic --version CHART_VERSION
The chart stores all configuration, including Kubernetes resource definitions, in values.yaml, which makes the file fairly large and not always convenient to edit.
If you need to override any parameters, it is acceptable and recommended to create an additional file with an arbitrary name, for example values-override.yaml. This document uses that name below.
For convenience, the chart includes a values-override.yaml template.
In this case, the installation command looks as follows. The order of files matters:
helm install codescoring . -f values.yaml -f values-override.yaml -n codescoring --atomic --version CHART_VERSION
Installation with built-in PostgreSQL and Redis
The chart can deploy PostgreSQL and Redis using StatefulSet resources.
To enable PostgreSQL and Redis installation, define the following parameters in values-override.yaml:
statefulSets:
codescoring-postgresql:
enabled: true
containers:
postgresql:
resources:
limits:
cpu: 2000m
memory: 12Gi
requests:
cpu: 1m
memory: 500Mi
codescoring-redis:
enabled: true
containers:
redis:
resources:
limits:
cpu: 2000m
memory: 4Gi
pvcs:
codescoring-postgresql:
accessModes:
- ReadWriteOnce
size: 20Gi
storageClassName: "default"
codescoring-redis:
accessModes:
- ReadWriteOnce
size: 1Gi
storageClassName: "default"
When using built-in databases, no additional connection configuration is required.
Connecting external databases
Important
When using your own database, make sure it meets the requirements.
Connecting external Redis
To connect external Redis, specify the corresponding connection strings in the following fields and keep the database numbers consistent:
configMaps:
ipcs-backend-env:
data:
DJANGO_CACHES_REDIS_URL: "redis://codescoring-redis:6379/1"
HUEY_REDIS_URL: "redis://codescoring-redis:6379/0"
CELERY_BROKER_URL: "redis://codescoring-redis:6379/2"
CELERY_RESULT_BACKEND: "redis://codescoring-redis:6379/2"
Connecting to PostgreSQL through PgBouncer
Important
External PostgreSQL must be connected through a connection pooler.
This option is suitable when PostgreSQL is already deployed in the existing infrastructure, but a connection pooler is not used. The Helm chart deploys PgBouncer and connects it to the existing PostgreSQL. Complete the following steps:
-
Configure the connection pooler by specifying the corresponding values:
secrets:
pgbouncer-secrets:
data:
# secrets for connecting pgbouncer to PostgreSQL
POSTGRES_DB: "codescoring_db"
POSTGRES_USER: "codescoring_user"
POSTGRES_PASSWORD: "changeme"
# secrets for internal pgbouncer pools
TRANSACTION_POOL_PASSWORD: "changeme"
SESSION_POOL_PASSWORD: "changeme"
STATS_USER: "codescoring_user-stats"
STATS_PASSWORD: "changeme"
ADMIN_USER: "codescoring_user-admin"
ADMIN_PASSWORD: "changeme"
configMaps:
pgbouncer-env:
data:
# parameters for connecting pgbouncer to PostgreSQL
POSTGRES_HOST: "codescoring-postgresql"
POSTGRES_PORT: "5432"
# parameters for internal pools
TRANSACTION_POOL_USER: "codescoring_user"
SESSION_POOL_USER: "codescoring_user-session"
TRANSACTION_POOL_SIZE: "50"
TRANSACTION_POOL_MIN_SIZE: "1"
SESSION_POOL_SIZE: "50"
SESSION_POOL_MIN_SIZE: "1"
# virtual pgbouncer databases that exist only inside pgbouncer
TRANSACTION_POOL_DATABASE_NAME: "codescoring_generic"
SESSION_POOL_DATABASE_NAME: "codescoring_generic-session"
MAX_CLIENT_CONN: "500"
-
Pass the configuration parameters created in step 1 to CodeScoring components:
secrets:
ipcs-secrets:
data:
# secrets for connecting to pools from pgbouncer-secrets
TRANSACTION_POOL_PASSWORD: "changeme"
SESSION_POOL_PASSWORD: "changeme"
DATABASE_PASSWORD: "changeme" # matches TRANSACTION_POOL_PASSWORD
configMaps:
ipcs-backend-env:
data:
# connection parameters for osa-api and judge
DATABASE_HOST: "pgbouncer"
DATABASE_PORT: "6432"
DATABASE_USERNAME: "codescoring_user" # matches TRANSACTION_POOL_USER
DATABASE_NAME: "codescoring_db" # matches TRANSACTION_POOL_DATABASE_NAME
TRANSACTION_POOL_HOST: "pgbouncer"
TRANSACTION_POOL_PORT: "6432"
TRANSACTION_POOL_USER: "codescoring_user"
TRANSACTION_POOL_DATABASE_NAME: "codescoring_db"
SESSION_POOL_HOST: "pgbouncer"
SESSION_POOL_PORT: "6432"
SESSION_POOL_USER: "codescoring_user-session"
SESSION_POOL_DATABASE_NAME: "codescoring_generic-session"
Configuring volumes
Dynamic Volume Provisioning with the required StorageClass
The chart creates the required volumes through Dynamic Volume Provisioning using an explicitly specified StorageClass.
To create PersistentVolumeClaim resources, fill in the following values section:
pvcs:
# replace storageClassName with the StorageClass used in the cluster
codescoring-ipcs-django-static:
accessModes:
- ReadWriteOnce
size: 10Gi
storageClassName: "default"
codescoring-ipcs-analysis-root:
accessModes:
- ReadWriteOnce
size: 10Gi
storageClassName: "default"
codescoring-ipcs-media-root:
accessModes:
- ReadWriteOnce
size: 10Gi
storageClassName: "default"
If the cluster supports volumes with the ReadWriteMany (RWX) access mode, it is recommended to use that mode because it allows installation components to be placed on different cluster nodes.
If the cluster does not support RWX, or if RWO is required for another reason, configure podAffinity so that pods using the same volumes are scheduled on the same node.
To do this, add the following block to values-override.yaml:
deploymentsGeneral:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: codescoring-component
operator: In
values:
- backend
- frontend
- huey
- celery
topologyKey: kubernetes.io/hostname
PersistentVolumeClaim for pre-created PersistentVolume resources
You can specify names of pre-created PersistentVolume resources in the volumeName field, for example:
pvcs:
codescoring-ipcs-analysis-root:
accessModes:
- ReadWriteOnce
size: 10Gi
storageClassName: "default"
volumeName: "codescoring-precreated-pv"
Configuring resource limits
By default, requests and limits are set to demonstration values that are not intended for production use. This makes it possible to run CodeScoring in clusters with limited resources, for example in minikube, for testing purposes.
When running in a production environment, you may need to configure resource limits. Edit the following fields:
Resource limits for init containers
# limits applied to all init containers
# this field can only be edited in values.yaml; override is not possible because of YAML structure limitations
init-container-resources: &init-container-resources
resources:
limits:
cpu: 1000m
memory: 1Gi
requests:
cpu: 1m
memory: 100Mi
# limits for backend init containers are configured separately
deployments:
ipcs-backend:
initContainers:
ipcs-collectstatic:
resources:
limits:
cpu: 1000m
memory: 2Gi
requests:
cpu: 1m
memory: 500Mi
ipcs-migrate:
resources:
limits:
cpu: 1000m
memory: 2Gi
requests:
cpu: 1m
memory: 500Mi
Resource limits for main component containers
In general, resources are configured using the following template:
deployments:
<deployment-name>:
containers:
<container-name>:
resources:
limits:
cpu: 8000m
memory: 12Gi
requests:
cpu: 1m
memory: 500Mi
You can specify requests and limits together or separately. However, if only limits are specified, Kubernetes automatically sets requests to the same values, which may negatively affect pod scheduling.
Adding a Certificate Authority (CA) certificate
To allow CodeScoring to access resources with TLS certificates signed by a corporate Certificate Authority (CA), add the root CA certificate (RootCA) to values.yaml in key: value format.
The key is the certificate file name, including the .crt extension. The value is the certificate in PEM format. Add it to the following field:
secrets:
ca-certificates:
data:
my-root-CA.crt: |-
-----BEGIN CERTIFICATE-----
MIIDTDCCAjSgAwIBAgIBATANBgkqhkiG9w0BAQUFADA3MQswCQYDVQQGEwJERTEP
MA0GA1UEChMGZWR1UEtJMRcwFQYDVQQDEw5lZHVQS0kgVGVzdCBDQTAeFw0xMDAz
MzExMjIwMjRaFw0zMDAzMjYxMjIwMjRaMDcxCzAJBgNVBAYTAkRFMQ8wDQYDVQQK
EwZlZHVQS0kxFzAVBgNVBAMTDmVkdVBLSSBUZXN0IENBMIIBIjANBgkqhkiG9w0B
AQEFAAOCAQ8AMIIBCgKCAQEAt5IxCk/NQPOLqeA1lGuB3pvqHGQPxRQ1udYGcXQY
t7EuSMFymUR9m5TsifG1ktktJTtOWyaWFC4ac0vai49wGVeuDYptfZBoHLIUvCwN
DOofLYHxk04WzfrtSiUTptn1o6QPOw8YR0XH30MEi1zgD8fLMZmVTJ+XwA5Eus6c
XtTmI4XhNrHUtvWt4UsNgLmp5/djUgRMpNqxIdrpFQzl+XycRJRAaoAwUzHFl14t
49qwBhGChxQ8AdDMQGA7kv6VR8o0ktCPv3a4GQbs8+z0cX0w5dC+XhJ1xpqW6TOg
qAY9XBFIDe5j21hjKmNZ39rsODVGUS2wUtNEhSz+3YqxLwIDAQABo2MwYTAdBgNV
HQ4EFgQUqHe3saMjZZLan8RlFJs+Xuz4yiAwHwYDVR0jBBgwFoAUqHe3saMjZZLa
n8RlFJs+Xuz4yiAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ
KoZIhvcNAQEFBQADggEBAEjQGyHZQis47c2kf+zXJJoDDlRgFzr9xfcnrHFaJvYx
nuqNE0T+xmujnwGm3VrgddeAQJuW3sD6y0Ox8NgL4z886VFeaDQ0GmFPI6HEVtg6
mixMhi+YzdkC+PFrEdYUeVNNwVO+bvJb1Rc08BYU4v7VtTkssHjru76E2/ahn/Ct
kaVTEojEWeRaxsw5/0VLkgyf8SwDaukM2aamqgEzfsw5GTdSAh7ERZKc+zF7Sr5s
DY8c5lOmyCwuNh9ODuw4cAThICrn7G8bh8ZyxLyj4Znxh0X45SwMZKTmYLfy9ab8
b/j7FK8uBNRL+pXl9HGBWAFA01uJw4HkYK+Uo+RcAzo=
-----END CERTIFICATE-----
You can specify any number of files, but each certificate must be stored in a separate file.
Environment variables
Managing environment variables through values
Environment variables and configuration files used by installation components are described in the configMaps and secrets blocks in values.yaml.
The most commonly overridden configuration parameters are included in values-override.yaml.
Managing environment variables through External Secret
External secret storage can also be connected. To use it, the cluster must have External Secrets Operator (ESO) installed. ESO adds the required CRDs (Custom Resource Definitions) to the cluster and connects it to secret storage.
To create an ExternalSecret resource and connect it to an existing SecretStore, add the corresponding entry to the vaults block:
vaults:
ipcs-backend-secret-external: # name of the secret created as a result
apiVersion: external-secrets.io/v1 # external-secrets.io/v1beta1 by default
enabled: true
store:
name: vault-backend # name of the pre-created SecretStore
kind: ClusterSecretStore # type of the pre-created SecretStore
path: secret/data/my-vault-secret # path to the secret in Vault
To pass the created secret to all Deployment resources, add the resource name from the vaults block to deploymentsGeneral.envSecrets, for example:
deploymentsGeneral:
envConfigmaps:
- ipcs-backend-env
envSecrets:
- ipcs-secrets
- ipcs-backend-secret-external # the resource name from the vaults block
To pass the secret only to one Deployment resource, specify it in the deployments block along with all secrets already used by that resource, for example:
deployments:
ipcs-backend:
envSecrets:
- ipcs-secrets
- ipcs-backend-secret-external
Migration from Helm Chart 2.x.x
Important
If built-in PostgreSQL was used, create a backup before any manipulations.
The installation will be unavailable during migration, so it is recommended to allocate a maintenance window. The migration takes 5-10 minutes in total.
Migration steps:
-
Delete all Deployment resources: kubectl delete deployment --all -n codescoring.
-
Delete all Service resources: kubectl delete service --all -n codescoring.
-
Run helm upgrade after filling in values.yaml and values-override.yaml according to Helm chart settings:
helm upgrade codescoring codescoring-org/codescoring-helm --version <CHART_VERSION> -f values.yaml -f values-override.yaml -n codescoring