Skip to content

Skaha Helm Chart

The Skaha Helm chart facilitates the deployment of the Skaha application within a Kubernetes cluster. This chart is designed to streamline the installation and management of Skaha, ensuring a seamless integration into your Kubernetes environment.

Chart source

The Skaha Helm chart is co-located with the Skaha service in opencadc/science-platform under helm/. Install from the published chart science-platform/skaha. An archived copy of the former deployments-repo chart is under helm/applications/archived/skaha/ and is no longer released from this repository.

Prerequisites

Before deploying the Skaha Helm chart, ensure that the following conditions are met:

  • Kubernetes Cluster: A running Kubernetes cluster, version 1.29 or higher.
  • Helm: Helm package manager, version 3, installed on your machine. Refer to the official Helm documentation for installation instructions.
  • Traefik: Required before Skaha install (IngressRoute, Middleware). See the deployment guide.
  • Kueue: Recommended; install and configure per the deployment guide before Skaha if you use session queueing.

Installation

To deploy the Skaha application using the Helm chart, follow these steps:

  1. Add the Skaha Helm Repository:

    helm repo add skaha-repo https://images.opencadc.org/chartrepo/platform
    

  2. Update Helm Repositories:

    helm repo update
    

  3. Install the Skaha Chart:

    helm --namespace skaha-system upgrade --install --values <your-skaha-values.yaml> skaha-release skaha-repo/skaha
    
    Replace skaha-release with your desired release name.

Configuration

The Skaha Helm chart comes with a default configuration suitable for most deployments. However, you can customize the installation by providing your own values.yaml file. This allows you to override default settings such as resource allocations, environment variables, and other parameters.

To customize the installation:

  • Create a values.yaml File: Define your custom configurations in this file.
  • Install the Chart with Custom Values:
    helm --namespace skaha-system upgrade --install --values values.yaml skaha-release skaha-repo/skaha
    

LimitRange

You can define a LimitRange for User Session Pods by modifying the deployment.skaha.sessions.limitRange section in your values.yaml file. This configuration allows you to set resource limits and requests for different session types. The min clause is ignored due to hard-coded resources for Desktop and Firefly sessions. This will go directly into a LimitRange object created in the Skaha workload Namespace, and, as such, supports the Kubernetes units.

When limit-range integration is enabled, the Skaha service uses the first LimitRange object returned for the workload namespace (not a specific name); the object name is therefore mostly irrelevant at runtime, though this chart uses a stable name when it creates the resource.

The rbac section allows you to create the necessary Role and RoleBinding for the LimitRange object. If your organization does not permit the creation of RBAC objects, you can set create to false and manage the RBAC externally.

deployment:
  skaha:
    sessions:
      limitRange:
        rbac:
          create: true
        limitSpec:
          max:
            # maximum resource limit to grow to, also used by the UI to limit selectable resources
            memory: "96Gi"
            cpu: "12"
          default:
            # actually refers to default limit
            memory: "32Gi"
            cpu: "8"
          defaultRequest:
            # default resource requests
            memory: "4Gi"
            cpu: "1"

Flexible Session Pods

You can customize the User Session Pods by modifying the deployment.skaha.sessions section in your values.yaml file. This includes settings for resource requests, storage allocation, and more.

Flexible User sessions are created with a small amount of CPU and memory by default and are allowed to grow to a specified limit in the LimitRange configuration. You can adjust these minimum (request) settings as needed:

deployment:
  skaha:
    sessions:
      flexResourceRequests:
        # The headless session type resource requests get slightly more resources to start.
        headless:
          memoryInGB: "2"
          cpuCores: "1"
        notebook:
          memoryInGB: "2"
          cpuCores: "0.5"

The headless, notebook, desktop, contributed, and firefly session types can all be customized individually. Any session type not specified will use the values defined in the LimitRange configuration.

Note that Kubernetes resource units are not supported in this configuration; only floating point or integer numbers as strings are valid. For example, for 100m of CPU, use "0.1".

Notes on tolerations and nodeAffinity

Ensure that tolerations and nodeAffinity are at the expected indentation! These are YAML configurations passed directly to Kubernetes, and the base .tolerations and .deployment.skaha.nodeAffinity values apply to the skaha API only, whereas the .deployment.skaha.sessions.tolerations and .deployment.skaha.sessions.nodeAffinity apply to all User Session Pods.

Kueue

Skaha leverages Kueue for efficient job queueing and management when properly installed and configured in your cluster. For detailed information on Kueue's features and setup, refer to the Kueue documentation.

Installation

https://kueue.sigs.k8s.io/docs/installation/#install-a-released-version

Will install the Kueue Chart, with a default ClusterQueue, and whatever defined LocalQueues were declared in the deployment.skaha.sessions.kueue section:

deployment:
  skaha:
    sessions:
      kueue:
        notebook:
          queueName: some-local-queue
          priorityClass: med

To determine your cluster's allocatable resources, checkout a small Python utility (requires uv): https://github.com/opencadc/deployments/tree/main/configs/kueue/kueuer

Then run:

git clone https://github.com/opencadc/deployments.git
cd deployments/configs/kueue/kueuer
# if not using the default ~/.kube/config
export KUBECONFIG=/home/user/.kube/my-config

# 60% of cluster resources
uv run kr cluster resources -f allocatable -s 0.6

# 80% of cluster resources
uv run kr cluster resources -f allocatable -s 0.8

Uninstallation

To remove the Skaha application from your cluster:

helm --namespace skaha-system uninstall skaha-release

This command will delete all resources associated with the Skaha release.

License

This project is licensed under the MIT License. For more information, refer to the LICENSE file in the repository.

Values Reference

skaha

A Helm chart to install the Skaha web service of the CANFAR Science Platform

Chart AppVersion Type
1.6.0-rc.5 1.3.0 application

Requirements

Repository Name Version
file://../../utils utils ^0.1.0
oci://registry-1.docker.io/bitnamicharts redis ^18.19.0

Values

Key Type Default Description
autoscaling.enabled bool true Enable HorizontalPodAutoscaler for skaha-tomcat. Target and scaling behavior are intentionally chart-managed (CPU 65%).
autoscaling.maxReplicas int 6 Maximum number of skaha-tomcat replicas.
autoscaling.minReplicas int 2 Minimum number of skaha-tomcat replicas.
deployment.hostname string "myhost.example.com" Public hostname for the Skaha API.
deployment.skaha.apiVersion string "v1" Skaha API version path segment (for example, v1 -> /skaha/v1/...).
deployment.skaha.defaultQuotaGB string "10" Default user storage quota in GiB for first-time users.
deployment.skaha.identityManagerClass string "org.opencadc.auth.StandardIdentityManager" Java IdentityManager implementation used for authentication.
deployment.skaha.image string "images.opencadc.org/platform/skaha:1.3.0" Container image for the Skaha API service.
deployment.skaha.imageCache.refreshSchedule string "*/30 * * * *" Cron schedule used to refresh cached images.
deployment.skaha.imagePullPolicy string "Always" Image pull policy for the Skaha API container.
deployment.skaha.init.image string "busybox:1.37.0" Init container image used to bootstrap user storage paths.
deployment.skaha.init.imagePullPolicy string "IfNotPresent" Image pull policy for the bootstrap init container.
deployment.skaha.posixMapperCacheTTLSeconds string "86400" TTL in seconds for cached POSIX mapper entries.
deployment.skaha.registryHosts string "images.canfar.net" Space-delimited list of image registry hosts allowed for sessions.
deployment.skaha.resources.limits.cpu string "2000m" CPU limit for the Skaha API container.
deployment.skaha.resources.limits.memory string "3Gi" Memory limit for the Skaha API container.
deployment.skaha.resources.requests.cpu string "1000m" CPU request for the Skaha API container.
deployment.skaha.resources.requests.memory string "2Gi" Memory request for the Skaha API container.
deployment.skaha.sessions object {"authorization":{"group":{"enabled":false,"uri":""},"permissionsAPI":{"authAPIBaseURL":"","baseURL":"","enabled":false,"method":"","name":"skaha","route":"","type":"route","version":""}},"expirySeconds":"345600","flexResourceRequests":{"headless":{"cpuCores":"1","memoryInGB":"4"}},"headlessPriorityClass":{"create":false,"description":"For high-priority headless jobs. Preempting.","globalDefault":false,"preemptionPolicy":"PreemptLowerPriority","value":2000},"imagePullPolicy":"Always","ingress":{"customResponseHeaders":{},"tls":{}},"initContainerImage":"redis:8.2.2-bookworm","kueue":{"rbac":{"create":false}},"limitRange":{"create":true,"enabled":false},"maxCount":"5","maxEphemeralStorage":"200Gi","minEphemeralStorage":"20Gi","namespace":{"create":false,"name":"skaha-workload"},"nodeLabelSelector":null,"priorityClass":{"create":false,"description":"For high-priority user pods. Preempting.","globalDefault":false,"name":"uber-user-preempt-high","preemptionPolicy":"PreemptLowerPriority","value":2000},"tolerations":[],"userStorage":{"admin":{},"homeDirectory":"home","projectsDirectory":"projects","spec":{},"topLevelDirectory":"/cavern"}} @deprecated Prefer deployment.skaha.sessions.authorization or deprecated usersGroup alone. Still honoured when sessions.authorization.group.enabled is false. The IVOA GMS Group URI to verify users against for permission to use the Science Platform. See https://www.ivoa.net/documents/GMS/20220222/REC-GMS-1.0.html#tth_sEc3.2 usersGroup: "ivo://example.org/gms?prototyping-groups/mini-src/platform-users" Group URI for users to ensure priority for their headless jobs. See https://www.ivoa.net/documents/GMS/20220222/REC-GMS-1.0.html#tth_sEc3.2 headlessPriorityGroup: "ivo://example.org/gms?skaha-priority-headless-users" Array of GMS Group URIs allowed to set the logging level. If none set, then nobody can change the log level. See https://www.ivoa.net/documents/GMS/20220222/REC-GMS-1.0.html#tth_sEc3.2 for GMS Group URIs See https://github.com/opencadc/core/tree/main/cadc-log for Logging control loggingGroups: - "ivo://example.org/gms?prototyping-groups/mini-src/platform-users" The Resource ID (URI) of the Service that contains the Posix Mapping information posixMapperResourceID: "ivo://example.org/posix-mapper" URI or URL of the OIDC (IAM) server. Used to validate incoming tokens. oidcURI: https://iam.example.org/ The Resource ID (URI) of the GMS Service. gmsID: ivo://example.org/gms The absolute URL of the IVOA Registry where services are registered registryURL: https://spsrc27.iaa.csic.es/reg This applies to Skaha itself. Meaning, this Pod will be scheduled as described by the nodeAffinity clause. Note the different indentation level compared to the sessions.nodeAffinity. See https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/ nodeAffinity: {} Settings for User Sessions. Sensible defaults supplied, but can be overridden. For units of storage, see https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#meaning-of-memory.
deployment.skaha.sessions.authorization.group.enabled bool false When true, SKAHA_USERS_GROUP is set from uri. Required uri when enabled (Helm validates). The Skaha service enforces mutually exclusive authorization modes at runtime.
deployment.skaha.sessions.authorization.permissionsAPI.authAPIBaseURL string "" Base URL for the SRCNet Auth API used by the permissions client.
deployment.skaha.sessions.authorization.permissionsAPI.baseURL string "" Required when enabled is true (Helm validates).
deployment.skaha.sessions.authorization.permissionsAPI.enabled bool false When true, SKAHA_PERMISSIONS_API_* vars are set from baseURL, authAPIBaseURL, type, route, name, version, and method. Required baseURL and authAPIBaseURL when enabled (Helm validates). The Skaha service enforces mutually exclusive authorization modes at runtime.
deployment.skaha.sessions.authorization.permissionsAPI.method string "" Method of the permissions API.
deployment.skaha.sessions.authorization.permissionsAPI.name string "skaha" Name of the permissions API.
deployment.skaha.sessions.authorization.permissionsAPI.route string "" Route of the permissions API.
deployment.skaha.sessions.authorization.permissionsAPI.type string "route" Type of the permissions API.
deployment.skaha.sessions.authorization.permissionsAPI.version string "" Version of the permissions API.
deployment.skaha.sessions.expirySeconds string "345600" Session lifetime in seconds before expiry and shutdown.
deployment.skaha.sessions.flexResourceRequests.headless.cpuCores string "1" Default CPU request (cores) for flex headless sessions.
deployment.skaha.sessions.flexResourceRequests.headless.memoryInGB string "4" Default memory request (GiB) for flex headless sessions.
deployment.skaha.sessions.headlessPriorityClass object {"create":false,"description":"For high-priority headless jobs. Preempting.","globalDefault":false,"preemptionPolicy":"PreemptLowerPriority","value":2000} Effective headless PriorityClass configuration (merged with legacy headlessPriorityClass).
deployment.skaha.sessions.imagePullPolicy string "Always" Image pull policy applied to all user session containers.
deployment.skaha.sessions.ingress.customResponseHeaders object {} Custom response headers added to user-session ingress responses.
deployment.skaha.sessions.ingress.tls object {} TLS configuration for the user-session Traefik IngressRoute.
deployment.skaha.sessions.initContainerImage string "redis:8.2.2-bookworm" Image used by the session init container that manages POSIX data.
deployment.skaha.sessions.kueue object {"rbac":{"create":false}} Per-session-type Kueue configuration.
deployment.skaha.sessions.limitRange.create bool true When true together with enabled, the chart creates the LimitRange <release>-session-limit-range in the workload namespace from spec below. When false, do not create one here; ensure the namespace has a LimitRange Skaha can use (Skaha uses the first LimitRange returned; the name is mostly irrelevant).
deployment.skaha.sessions.limitRange.enabled bool false When true, set SKAHA_SESSION_LIMIT_RANGE_ENABLED on the Skaha deployment so it loads the first LimitRange in the workload namespace (name is mostly irrelevant). Also gates this chart's LimitRange Role/RoleBinding (rbac.create). Must also be true (with create) for the chart to render the LimitRange manifest.
deployment.skaha.sessions.maxCount string "5" Maximum number of active sessions allowed per user.
deployment.skaha.sessions.maxEphemeralStorage string "200Gi" Maximum ephemeral storage limit for sessions (non-desktop).
deployment.skaha.sessions.minEphemeralStorage string "20Gi" Initial ephemeral storage request for new sessions (non-desktop).
deployment.skaha.sessions.nodeLabelSelector string nil Node label selector used when discovering schedulable worker nodes.
deployment.skaha.sessions.priorityClass object {"create":false,"description":"For high-priority user pods. Preempting.","globalDefault":false,"name":"uber-user-preempt-high","preemptionPolicy":"PreemptLowerPriority","value":2000} PriorityClass assigned to the Skaha API Pod.
deployment.skaha.sessions.tolerations list [] Tolerations applied to user session Pods.
deployment.skaha.sessions.userStorage.homeDirectory string "home" Relative path under topLevelDirectory for user home directories.
deployment.skaha.sessions.userStorage.projectsDirectory string "projects" Relative path under topLevelDirectory for shared projects storage.
deployment.skaha.sessions.userStorage.topLevelDirectory string "/cavern" Absolute mount path containing user home and projects directories.
experimentalFeatures.enabled bool false Enable processing of experimental feature gates.
ingress.enabled bool true Enable ingress routing for the Skaha API.
ingress.path string "/skaha" Ingress path prefix routed to the Skaha API Service.
kubernetesClusterDomain string "cluster.local" Kubernetes DNS domain used when building internal service hostnames.
metricsBackend.enabled bool false When true, install Kueue-read ClusterRole/Binding first (Helm kind order), then Metrics Service and Deployment. Applies fail if cluster RBAC cannot be created (for example forbidden).
metricsBackend.env object {} Map of environment variables for the Metrics container (typically METRICS_*). GitOps should supply the full map per environment.
metricsBackend.image.pullPolicy string "IfNotPresent" imagePullPolicy for the Metrics API container.
metricsBackend.image.repository string "images.opencadc.org/platform/metrics" Metrics container image repository.
metricsBackend.image.tag string "v0.1.5" Metrics container image tag.
metricsBackend.ingress.enabled bool false When true and top-level ingress.enabled is true, add a path on the same host routing to the Metrics Service.
metricsBackend.ingress.path string "/metrics" Ingress path prefix for the Metrics API (Traefik).
metricsBackend.rbac.enabled bool false When true, create metricsBackend Kueue-read ClusterRole/ClusterRoleBinding. Set false to disable cluster-scoped RBAC while keeping the metrics workload enabled.
metricsBackend.redis.enabled bool true When true, set METRICS_REDIS_URL to this release's Bitnami Redis master Service (-redis-master), same instance Skaha uses. Set false and supply METRICS_REDIS_URL in env if Metrics should use another Redis.
metricsBackend.replicaCount int 1 Fixed replica count for the Metrics API (no HPA in this chart version).
metricsBackend.resources object {"limits":{"cpu":"1","memory":"1Gi"},"requests":{"cpu":"100m","memory":"256Mi"}} Resource requests and limits for the Metrics API container.
metricsBackend.revisionHistoryLimit int 3 revisionHistoryLimit for the Metrics API Deployment.
metricsBackend.test.enabled bool true Run helm test hook that retries /healthz until success (requires metricsBackend.enabled).
metricsBackend.test.image string "busybox:1.37.0" Image for the helm test hook Pod.
metricsBackend.test.maxWaitSeconds int 180 Maximum seconds to wait for Metrics /healthz (should exceed startupProbe worst case plus scheduling margin).
podSecurityContext object {}
rbac.clusterRole.create bool false
rbac.create bool true
redis.architecture string "standalone" Redis deployment architecture.
redis.auth.enabled bool false Enable Redis authentication.
redis.image.repository string "redis" Redis image repository used by the bundled chart dependency.
redis.image.tag string "8.2.2-bookworm" Redis image tag used by the bundled chart dependency.
redis.master.containerSecurityContext.allowPrivilegeEscalation bool false Disallow privilege escalation in the Redis master container.
redis.master.containerSecurityContext.capabilities.drop list ["ALL"] Linux capabilities dropped from the Redis master container.
redis.master.containerSecurityContext.readOnlyRootFilesystem bool true Mount Redis master root filesystem as read-only.
redis.master.containerSecurityContext.runAsGroup int 1001 Group ID for the Redis master container.
redis.master.containerSecurityContext.runAsNonRoot bool true Require Redis master to run as a non-root user.
redis.master.containerSecurityContext.runAsUser int 1001 User ID for the Redis master container.
redis.master.containerSecurityContext.seccompProfile.type string "RuntimeDefault" Seccomp profile type for Redis master.
redis.master.persistence.enabled bool false Enable persistence for the Redis master StatefulSet.
replicaCount int 1 Number of skaha-tomcat replicas when autoscaling is disabled.
secrets string nil
securityContext object {} Optional Pod-level security context for the Skaha API Deployment.
service.port int 8080 Service port exposed for the Skaha API Service.
serviceAccount object {"annotations":{},"automount":true,"create":true,"name":""} ServiceAccount used by the Skaha API Pod.
tolerations list [] Tolerations applied to the Skaha API Pod.

metricsBackend install ordering

When metricsBackend.enabled is true, the chart emits ClusterRole, ClusterRoleBinding, Service, and Deployment for metrics. Helm applies manifest groups in a deterministic kind order so RBAC objects are reconciled before typical namespaced workload kinds. If the API server rejects creating or updating those cluster-scoped RBAC rules (for example the caller lacks permission), the release fails instead of only rolling out a broken metrics Deployment. helm test (optional) still targets the running Service after install; it does not replace RBAC admission checks.

If metricsBackend.enabled=true and metricsBackend.rbac.enabled=false, this chart will not create the metrics ClusterRole/ClusterRoleBinding. In that mode, the deployer is responsible for ensuring the Skaha ServiceAccount (deployment.skaha.serviceAccountName) already has get/list permissions on the Kueue ClusterQueue API before installation.