diff --git a/label-studio/.helmignore b/label-studio/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/label-studio/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/label-studio/Chart.yaml b/label-studio/Chart.yaml new file mode 100644 index 0000000..6b14e97 --- /dev/null +++ b/label-studio/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: label-studio +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 1.1 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/label-studio/label-studio-1.1.tgz b/label-studio/label-studio-1.1.tgz new file mode 100644 index 0000000..4ce6f9f Binary files /dev/null and b/label-studio/label-studio-1.1.tgz differ diff --git a/label-studio/templates/NOTES.txt b/label-studio/templates/NOTES.txt new file mode 100644 index 0000000..9aa2973 --- /dev/null +++ b/label-studio/templates/NOTES.txt @@ -0,0 +1,35 @@ +1. Get the application URL by running these commands: +{{- if .Values.httpRoute.enabled }} +{{- if .Values.httpRoute.hostnames }} + export APP_HOSTNAME={{ .Values.httpRoute.hostnames | first }} +{{- else }} + export APP_HOSTNAME=$(kubectl get --namespace {{(first .Values.httpRoute.parentRefs).namespace | default .Release.Namespace }} gateway/{{ (first .Values.httpRoute.parentRefs).name }} -o jsonpath="{.spec.listeners[0].hostname}") + {{- end }} +{{- if and .Values.httpRoute.rules (first .Values.httpRoute.rules).matches (first (first .Values.httpRoute.rules).matches).path.value }} + echo "Visit http://$APP_HOSTNAME{{ (first (first .Values.httpRoute.rules).matches).path.value }} to use your application" + + NOTE: Your HTTPRoute depends on the listener configuration of your gateway and your HTTPRoute rules. + The rules can be set for path, method, header and query parameters. + You can check the gateway configuration with 'kubectl get --namespace {{(first .Values.httpRoute.parentRefs).namespace | default .Release.Namespace }} gateway/{{ (first .Values.httpRoute.parentRefs).name }} -o yaml' +{{- end }} +{{- else if .Values.ingress.enabled }} +{{- range $host := .Values.ingress.hosts }} + {{- range .paths }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} + {{- end }} +{{- end }} +{{- else if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "label-studio.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch its status by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "label-studio.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "label-studio.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + echo http://$SERVICE_IP:{{ .Values.service.port }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "label-studio.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT +{{- end }} diff --git a/label-studio/templates/_helpers.tpl b/label-studio/templates/_helpers.tpl new file mode 100644 index 0000000..711c378 --- /dev/null +++ b/label-studio/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "label-studio.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "label-studio.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "label-studio.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "label-studio.labels" -}} +helm.sh/chart: {{ include "label-studio.chart" . }} +{{ include "label-studio.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "label-studio.selectorLabels" -}} +app.kubernetes.io/name: {{ include "label-studio.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "label-studio.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "label-studio.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/label-studio/templates/deployment.yaml b/label-studio/templates/deployment.yaml new file mode 100644 index 0000000..6fee6c1 --- /dev/null +++ b/label-studio/templates/deployment.yaml @@ -0,0 +1,78 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "label-studio.fullname" . }} + labels: + {{- include "label-studio.labels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "label-studio.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "label-studio.labels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "label-studio.serviceAccountName" . }} + {{- with .Values.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + {{- with .Values.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: http + containerPort: {{ .Values.service.port }} + protocol: TCP + {{- with .Values.livenessProbe }} + livenessProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.volumeMounts }} + volumeMounts: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.volumes }} + volumes: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/label-studio/templates/hpa.yaml b/label-studio/templates/hpa.yaml new file mode 100644 index 0000000..8c1dca2 --- /dev/null +++ b/label-studio/templates/hpa.yaml @@ -0,0 +1,32 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "label-studio.fullname" . }} + labels: + {{- include "label-studio.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "label-studio.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/label-studio/templates/httproute.yaml b/label-studio/templates/httproute.yaml new file mode 100644 index 0000000..bee4070 --- /dev/null +++ b/label-studio/templates/httproute.yaml @@ -0,0 +1,38 @@ +{{- if .Values.httpRoute.enabled -}} +{{- $fullName := include "label-studio.fullname" . -}} +{{- $svcPort := .Values.service.port -}} +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: {{ $fullName }} + labels: + {{- include "label-studio.labels" . | nindent 4 }} + {{- with .Values.httpRoute.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + parentRefs: + {{- with .Values.httpRoute.parentRefs }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.httpRoute.hostnames }} + hostnames: + {{- toYaml . | nindent 4 }} + {{- end }} + rules: + {{- range .Values.httpRoute.rules }} + {{- with .matches }} + - matches: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .filters }} + filters: + {{- toYaml . | nindent 8 }} + {{- end }} + backendRefs: + - name: {{ $fullName }} + port: {{ $svcPort }} + weight: 1 + {{- end }} +{{- end }} diff --git a/label-studio/templates/ingress.yaml b/label-studio/templates/ingress.yaml new file mode 100644 index 0000000..13ecac3 --- /dev/null +++ b/label-studio/templates/ingress.yaml @@ -0,0 +1,43 @@ +{{- if .Values.ingress.enabled -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "label-studio.fullname" . }} + labels: + {{- include "label-studio.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- with .Values.ingress.className }} + ingressClassName: {{ . }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + {{- with .pathType }} + pathType: {{ . }} + {{- end }} + backend: + service: + name: {{ include "label-studio.fullname" $ }} + port: + number: {{ $.Values.service.port }} + {{- end }} + {{- end }} +{{- end }} diff --git a/label-studio/templates/service.yaml b/label-studio/templates/service.yaml new file mode 100644 index 0000000..50d6127 --- /dev/null +++ b/label-studio/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "label-studio.fullname" . }} + labels: + {{- include "label-studio.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "label-studio.selectorLabels" . | nindent 4 }} diff --git a/label-studio/templates/serviceaccount.yaml b/label-studio/templates/serviceaccount.yaml new file mode 100644 index 0000000..039b3c7 --- /dev/null +++ b/label-studio/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "label-studio.serviceAccountName" . }} + labels: + {{- include "label-studio.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +automountServiceAccountToken: {{ .Values.serviceAccount.automount }} +{{- end }} diff --git a/label-studio/templates/tests/test-connection.yaml b/label-studio/templates/tests/test-connection.yaml new file mode 100644 index 0000000..a1b2e9e --- /dev/null +++ b/label-studio/templates/tests/test-connection.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "label-studio.fullname" . }}-test-connection" + labels: + {{- include "label-studio.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ include "label-studio.fullname" . }}:{{ .Values.service.port }}'] + restartPolicy: Never diff --git a/label-studio/values.yaml b/label-studio/values.yaml new file mode 100644 index 0000000..591e33d --- /dev/null +++ b/label-studio/values.yaml @@ -0,0 +1,774 @@ +# Default values for Label Studio. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +global: + # Image pull secret to use for registry authentication. + # Alternatively, you can specify the value as an array of strings. + imagePullSecrets: [] + + image: + registry: docker.io + repository: heartexlabs/label-studio + pullPolicy: IfNotPresent + tag: "" + + pgConfig: + host: "127.0.0.1" + port: 5432 + dbName: "label" + userName: "label" + password: + secretName: "label-studio-pg-password" + secretKey: "label-studio-pg-password" + ssl: + pgSslMode: "" + pgSslSecretName: "" + pgSslRootCertSecretKey: "" + pgSslCertSecretKey: "" + pgSslKeySecretKey: "" + + # Redis location, for example redis://[:password]@localhost:6379/1 + # Supported only in LSE + redisConfig: + host: "127.0.0.1" + password: + secretName: "label-studio-redis-password" + secretKey: "label-studio-redis-password" + ssl: + redisSslCertReqs: "" + redisSslSecretName: "" + redisSslCaCertsSecretKey: "" + redisSslCertFileSecretKey: "" + redisSslKeyFileSecretKey: "" + + extraEnvironmentVars: {} + extraEnvironmentSecrets: { } + + persistence: + enabled: true + type: volume # s3, azure, gcs + config: + s3: + accessKey: "" + secretKey: "" + accessKeyExistingSecret: "" + accessKeyExistingSecretKey: "" + secretKeyExistingSecret: "" + secretKeyExistingSecretKey: "" + region: "" + bucket: "" + folder: "" + urlExpirationSecs: "86400" + endpointUrl: "" + objectParameters: {} + volume: + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + storageClass: "" + size: 10Gi + accessModes: + - ReadWriteOnce + annotations: {} + existingClaim: "" + resourcePolicy: "" + azure: + storageAccountName: "" + storageAccountKey: "" + storageAccountNameExistingSecret: "" + storageAccountNameExistingSecretKey: "" + storageAccountKeyExistingSecret: "" + storageAccountKeyExistingSecretKey: "" + containerName: "" + folder: "" + urlExpirationSecs: "86400" + gcs: + projectID: "" + applicationCredentialsJSON: "" + applicationCredentialsJSONExistingSecret: "" + applicationCredentialsJSONExistingSecretKey: "" + bucket: "" + folder: "" + urlExpirationSecs: "86400" + + featureFlags: { } + # File name of a shell script to load additional template environment variables from. + # This is useful when using Vault. + # "- /vault/secrets/config" + envInjectSources: [] + + ## @param app.cmdWrapper Additional commands to run prior to starting App. Useful to run wrappers before startup command + ## e.g: + ## cmdWrapper: "newrelic-admin run-program" + ## + cmdWrapper: "" + + # File names of a custom SSL root certs. These filename will be appended to existing root certs. + # "- /tmp/my_cool_root_cert" + customCaCerts: [ ] + +app: + # Update strategy - only really applicable for deployments with RWO PVs attached + # If replicas = 1, an update can get "stuck", as the previous pod remains attached to the + # PV, and the "incoming" pod can never start. Changing the strategy to "Recreate" will + # terminate the single previous pod, so that the new, incoming pod can attach to the PV + deploymentStrategy: + type: RollingUpdate + + deploymentAnnotations: { } + + replicas: 1 + + NameOverride: "" + FullnameOverride: "" + labels: { } + podLabels: { } + + ## @param app.args Override default container args (useful when using custom images) + ## + args: + - "label-studio-uwsgi" + + resources: + requests: {} + ## Example: + # memory: "600Mi" + # cpu: "250m" + limits: {} + ## Example: + # memory: "4000Mi" + # cpu: "4" + + initContainer: + resources: + requests: {} + ## Example: + # memory: 384Mi + # cpu: 250m + limits: {} + ## Example: + # memory: 512Mi + # cpu: 500m + + nginx: + args: + - "nginx" + extraEnvironmentVars: {} + extraEnvironmentSecrets: {} + resources: + requests: {} + ## Example + ## memory: 384Mi + ## cpu: 250m + limits: {} + ## Example: + ## memory: 1G + ## cpu: 1000m + livenessProbe: + enabled: true + tcpSocket: + port: 8085 + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 3 + failureThreshold: 3 + successThreshold: 1 + readinessProbe: + enabled: true + httpGet: + path: /nginx_health + port: 8085 + initialDelaySeconds: 10 + periodSeconds: 5 + timeoutSeconds: 3 + failureThreshold: 1 + successThreshold: 1 + + # extraEnvironmentVars is a list of extra environment variables to set in the + # app deployment. + extraEnvironmentVars: { } + # KUBERNETES_SERVICE_HOST: kubernetes.default.svc + + # extraEnvironmentSecrets is a list of extra environment variables to set in the + # app deployment. + extraEnvironmentSecrets: { } + # MYSQL_PASSWORD: + # secretName: mysql_secret + # secretKey: password + + # nodeSelector labels for pod assignment, formatted as a multi-line string or YAML map. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + # Example: + # nodeSelector: + # beta.kubernetes.io/arch: amd64 + nodeSelector: { } + + topologySpreadConstraints: [ ] + + dnsPolicy: "ClusterFirst" + + enableServiceLinks: false + + shareProcessNamespace: false + + automountServiceAccountToken: true + + # Extra k8s annotations to attach to the app pods + # This can either be YAML or a YAML-formatted multi-line templated string map + # of the annotations to apply to the app pods + annotations: { } + + # Extra k8s labels to attach to Label Studio Enterprise. + # Provide a YAML map of k8s labels. + extraLabels: { } + + affinity: { } + + # Toleration Settings for app pods + # Provide either a multi-line string or YAML matching the Toleration array + # in a PodSpec. + tolerations: [] + + # Used to define custom readinessProbe settings + readinessProbe: + enabled: true + httpGet: + path: /health + port: 8000 + scheme: HTTP + # When a probe fails, Kubernetes will try failureThreshold times before giving up + failureThreshold: 1 + # Number of seconds after the container has started before probe initiates + initialDelaySeconds: 60 + # How often (in seconds) to perform the probe + periodSeconds: 5 + # Minimum consecutive successes for the probe to be considered successful after having failed + successThreshold: 1 + # Number of seconds after which the probe times out. + timeoutSeconds: 1 + # Used to enable a livenessProbe for the pods + livenessProbe: + enabled: true + tcpSocket: + port: 8000 + # When a probe fails, Kubernetes will try failureThreshold times before giving up + failureThreshold: 3 + # Number of seconds after the container has started before probe initiates + initialDelaySeconds: 10 + # How often (in seconds) to perform the probe + periodSeconds: 10 + # Minimum consecutive successes for the probe to be considered successful after having failed + successThreshold: 1 + # Number of seconds after which the probe times out. + timeoutSeconds: 5 + + service: + type: ClusterIP + port: 80 + targetPort: 8085 + portName: service + annotations: { } + sessionAffinity: "None" + sessionAffinityConfig: { } + + ingress: + enabled: false + # For Kubernetes >= 1.18 you should specify the ingress-controller using the field ingressClassName + # See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress + className: "" + annotations: { } + ## Examples: + ## kubernetes.io/tls-acme: "true" + host: "" + # You may need to set this to '/*' in order to use this with ALB ingress controllers. + path: / + ## Extra paths to prepend to the host configuration. This is useful when working with annotation based services. + extraPaths: [] + pathType: ImplementationSpecific + ## Examples: + ## - path: /* + ## backend: + ## serviceName: ssl-redirect + ## servicePort: use-annotation + tls: [ ] + ## Examples: + ## - secretName: chart-example-tls + ## hosts: + ## - app.heartex.local + ## @param api.ingress.extraHosts An array with additional hostname(s) to be covered with the ingress record + ## e.g: + ## extraHosts: + ## - name: app.humansignal.local + ## path: / + ## + extraHosts: [ ] + + # Definition of the serviceAccount used to run Label Studio Enterprise + serviceAccount: + # Specifies whether to create a service account + create: true + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + # Extra k8s annotations for the serviceAccount definition. This can either be + # YAML or a YAML-formatted multi-line templated string map of the + # k8s annotations to apply to the serviceAccount. + annotations: {} + + # Array to add extra volumes + extraVolumes: [ ] + # Array to add extra mounts (normally used with extraVolumes) + extraVolumeMounts: [ ] + + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod + ## @param app.podSecurityContext.enabled Enable pod Security Context + ## + podSecurityContext: + enabled: true + fsGroup: 1001 + + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container + ## @param containerSecurityContext.enabled Enable container Security Context + ## @param containerSecurityContext.runAsNonRoot Avoid running as root User + ## @param containerSecurityContext.allowPrivilegeEscalation Controls whether a process can gain more privileges than its parent process + ## + containerSecurityContext: + enabled: true + runAsUser: 1001 + runAsNonRoot: true + allowPrivilegeEscalation: false + + ## RBAC configuration + ## + rbac: + ## @param rbac.create Specifies whether RBAC resources should be created + ## + create: false + ## @param app.rbac.rules Custom RBAC rules to set + ## e.g: + ## rules: + ## - apiGroups: + ## - "" + ## resources: + ## - pods + ## verbs: + ## - get + ## - list + ## + rules: [] + + contextPath: / + ## @param app.cmdWrapper Additional commands to run prior to starting App. Useful to run wrappers before startup command + ## e.g: + ## cmdWrapper: "newrelic-admin run-program" + ## + cmdWrapper: "" + + ## Minimal number of seconds preStop hook waits before LS is stopped to finish processing requests + ## Note: must be set to lower value than terminationGracePeriodSeconds so that preStop hook finishes + ## before grace period expires + preStopDelaySeconds: 15 + # Seconds LS pod needs to terminate gracefully + terminationGracePeriodSeconds: 30 + + ## Add additional init containers to the App Deployment pod + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ + ## e.g: + ## initContainers: + ## - name: your-image-name + ## image: your-image + ## imagePullPolicy: Always + ## command: ['sh', '-c', 'echo "hello world"'] + ## + initContainers: [ ] + + ## Add additional init containers to the App Deployment pod after sql migration + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ + ## e.g: + ## postMigrationInitContainers: + ## - name: your-image-name + ## image: your-image + ## imagePullPolicy: Always + ## command: ['sh', '-c', 'echo "hello world"'] + ## + postMigrationInitContainers: [ ] + + ## Pod Disruption Budget configuration + ## ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb + ## @param app.pdb.create Enable/disable a Pod Disruption Budget creation + ## @param app.pdb.minAvailable Minimum number/percentage of pods that should remain scheduled + ## @param app.pdb.maxUnavailable Maximum number/percentage of pods that may be made unavailable. Defaults to `1` if both `app.pdb.minAvailable` and `app.pdb.maxUnavailable` are empty. + ## + pdb: + create: false + minAvailable: "" + maxUnavailable: "" + + +migrationJob: + enabled: false + # For Helm hooks, you can use: + # "helm.sh/hook": pre-install,pre-upgrade + # "helm.sh/hook-weight": "0" + # "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + # For ArgoCD, you can also use: + # "argocd.argoproj.io/hook": PreSync + # "argocd.argoproj.io/hook-delete-policy": BeforeHookCreation + annotations: {} + +rqworker: + enabled: true + + NameOverride: "" + FullnameOverride: "" + labels: {} + podLabels: {} + + deploymentStrategy: + type: Recreate + + deploymentAnnotations: { } + + autoscaling: + enabled: false + scalingType: deployment + + queues: + high: + replicas: 1 + args: '"high"' + resources: + requests: {} + limits: {} + scaledOptions: + minReplicaCount: 0 + maxReplicaCount: 5 + pollingInterval: 5 + cooldownPeriod: 60 + listLength: 10 + low: + replicas: 1 + args: '"low"' + resources: + requests: {} + limits: {} + scaledOptions: + minReplicaCount: 0 + maxReplicaCount: 5 + pollingInterval: 5 + cooldownPeriod: 60 + listLength: 10 + default: + replicas: 4 + args: '"default"' + resources: + requests: {} + limits: {} + scaledOptions: + minReplicaCount: 0 + maxReplicaCount: 5 + pollingInterval: 5 + cooldownPeriod: 60 + listLength: 10 + critical: + replicas: 1 + args: '"critical"' + resources: + requests: {} + limits: {} + scaledOptions: + minReplicaCount: 0 + maxReplicaCount: 5 + pollingInterval: 5 + cooldownPeriod: 60 + listLength: 10 + # Default fallback in the case if queue-specific resources are not set + resources: + requests: {} + ## memory: "256Mi" + ## cpu: "250m" + limits: {} + ## Example: + ## memory: "1500Mi" + ## cpu: "1" + + pdb: + create: false + minAvailable: "" + maxUnavailable: "" + + # extraEnvironmentVars is a list of extra environment variables to set in the + # rqworker deployment. + extraEnvironmentVars: { } + # KUBERNETES_SERVICE_HOST: kubernetes.default.svc + + # extraEnvironmentSecrets is a list of extra environment variables to set in the + # rqworker deployment. + extraEnvironmentSecrets: { } + # MYSQL_PASSWORD: + # secretName: mysql_secret + # secretKey: password + + # nodeSelector labels for pod assignment, formatted as a multi-line string or YAML map. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + # Example: + # nodeSelector: + # beta.kubernetes.io/arch: amd64 + nodeSelector: { } + + topologySpreadConstraints: [ ] + + dnsPolicy: "ClusterFirst" + + enableServiceLinks: false + + shareProcessNamespace: false + + automountServiceAccountToken: true + + # Extra k8s annotations to attach to the rqworker pods + # This can either be YAML or a YAML-formatted multi-line templated string map + # of the annotations to apply to the rqworker pods + annotations: { } + + # Extra k8s labels to attach to the rqworker + # This should be a YAML map of the labels to apply to the rqworker + extraLabels: { } + + affinity: { } + + # Toleration Settings for rqworker pods + # Provide either a multi-line string or YAML matching the Toleration array + # in a PodSpec. + tolerations: [] + + # Used to define custom readinessProbe settings + readinessProbe: + enabled: false + path: /version + # When a probe fails, Kubernetes will try failureThreshold times before giving up + failureThreshold: 2 + # Number of seconds after the container has started before probe initiates + initialDelaySeconds: 60 + # How often (in seconds) to perform the probe + periodSeconds: 5 + # Minimum consecutive successes for the probe to be considered successful after having failed + successThreshold: 1 + # Number of seconds after which the probe times out. + timeoutSeconds: 3 + # Used to enable a livenessProbe for the pods + livenessProbe: + enabled: false + path: "/health" + # When a probe fails, Kubernetes will try failureThreshold times before giving up + failureThreshold: 2 + # Number of seconds after the container has started before probe initiates + initialDelaySeconds: 60 + # How often (in seconds) to perform the probe + periodSeconds: 5 + # Minimum consecutive successes for the probe to be considered successful after having failed + successThreshold: 1 + # Number of seconds after which the probe times out. + timeoutSeconds: 3 + + # Definition of the serviceAccount used to run rqworker for Label Studio Enterprise + serviceAccount: + # Specifies whether to create a service account + create: true + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + # Extra k8s annotations for the serviceAccount definition. This can either be + # YAML or a YAML-formatted multi-line templated string map of the + # k8s annotations to apply to the serviceAccount. + annotations: { } + + # Array to add extra volumes + extraVolumes: [ ] + # Array to add extra mounts (normally used with extraVolumes) + extraVolumeMounts: [ ] + + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod + ## @param rqworker.podSecurityContext.enabled Enable pod Security Context + ## + podSecurityContext: + enabled: true + fsGroup: 1001 + + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container + ## @param containerSecurityContext.enabled Enable container Security Context + ## @param containerSecurityContext.runAsNonRoot Avoid running as root User + ## @param containerSecurityContext.allowPrivilegeEscalation Controls whether a process can gain more privileges than its parent process + ## + containerSecurityContext: + enabled: true + runAsUser: 1001 + runAsNonRoot: true + allowPrivilegeEscalation: false + + ## RBAC configuration + ## + rbac: + ## @param rbac.create Specifies whether RBAC resources should be created + ## + create: false + ## @param rqworker.rbac.rules Custom RBAC rules to set + ## e.g: + ## rules: + ## - apiGroups: + ## - "" + ## resources: + ## - pods + ## verbs: + ## - get + ## - list + ## + rules: [] + + ## @param app.cmdWrapper Additional commands to run prior to starting App. Useful to run wrappers before startup command + ## e.g: + ## cmdWrapper: "newrelic-admin run-program" + ## + cmdWrapper: "" + + # Seconds rqworker pod needs to terminate gracefully + terminationGracePeriodSeconds: 30 + +# [Enterprise Only] +enterprise: + enabled: false + # This value refers to a Kubernetes secret that you have + # created that contains your enterprise license. + enterpriseLicense: + # The name of the Kubernetes secret that holds the enterprise license. The + # secret must be in the same namespace that Label Studio Enterprise is installed into. + secretName: "" + # The key within the Kubernetes secret that holds the enterprise license. + secretKey: "license" + +postgresql: + enabled: true + clusterDomain: cluster.local + architecture: standalone + image: + repository: bitnamilegacy/postgresql + tag: 13.18.0 + auth: + username: "labelstudio" + password: "labelstudio" + database: "labelstudio" + volumePermissions: + image: + repository: bitnamilegacy/os-shell + metrics: + image: + repository: bitnamilegacy/postgres-exporter + global: + security: + allowInsecureImages: true + +redis: + enabled: false + clusterDomain: cluster.local + architecture: standalone + master: + enableServiceLinks: false + auth: + enabled: false + image: + repository: bitnamilegacy/redis + sentinel: + image: + repository: bitnamilegacy/redis-sentinel + kubectl: + image: + repository: bitnamilegacy/kubectl + sysctl: + image: + repository: bitnamilegacy/os-shell + metrics: + image: + repository: bitnamilegacy/redis-exporter + volumePermissions: + image: + repository: bitnamilegacy/os-shell + global: + security: + allowInsecureImages: true + +ci: false +clusterDomain: cluster.local + +checkConfig: + skipEnvValues: false + +cronjob: + enabled: false + jobs: {} + annotations: {} + NameOverride: "" + FullnameOverride: "" + +metrics: + enabled: false + serviceMonitor: + enabled: false + annotations: {} + labels: {} + jobLabel: "" + honorLabels: false + interval: "" + scrapeTimeout: "" + metricRelabelings: [] + relabelings: [] + selector: {} + + uwsgiExporter: + enabled: false + image: + registry: "docker.io" + repository: "timonwong/uwsgi-exporter" + tag: "v1.3.0" + pullPolicy: "Always" + pullSecrets: [ ] + + containerSecurityContext: + enabled: true + allowPrivilegeEscalation: false + readOnlyRootFilesystem: false + runAsUser: 1001 + + resources: + requests: { } + ## Example: + # cpu: "200m" + # memory: "64Mi" + limits: { } + # cpu: "20m" + # memory: "128Mi" + + livenessProbe: + enabled: false + httpGet: + path: "/-/healthy" + port: "uwsgimetrics" + initialDelaySeconds: 2 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 3 + successThreshold: 1 + + readinessProbe: + enabled: false + httpGet: + path: "/metrics" + port: "uwsgimetrics" + initialDelaySeconds: 2 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 3 + successThreshold: 1