diff --git a/tools/deployment/spider-helm/Chart.yaml b/tools/deployment/spider-helm/Chart.yaml index 9e83a862..ee7b3008 100644 --- a/tools/deployment/spider-helm/Chart.yaml +++ b/tools/deployment/spider-helm/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: "v2" name: "spider" description: "A Helm chart for the Spider Huntsman deployment" type: "application" -version: "0.1.0" +version: "0.1.1" appVersion: "0.1.0" home: "https://github.com/y-scope/spider" sources: ["https://github.com/y-scope/spider"] diff --git a/tools/deployment/spider-helm/templates/_helpers.tpl b/tools/deployment/spider-helm/templates/_helpers.tpl new file mode 100644 index 00000000..c2f75c79 --- /dev/null +++ b/tools/deployment/spider-helm/templates/_helpers.tpl @@ -0,0 +1,145 @@ +{{/* +Expands the name of the chart. + +@return {string} The chart name (truncated to 63 characters) +*/}} +{{- define "spider.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Creates a default fully qualified app name (truncated to 63 chars for the DNS naming spec). If the +release name already contains the chart name it is used as-is. + +@return {string} The fully qualified app name (truncated to 63 characters) +*/}} +{{- define "spider.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 }}{{/* if contains $name .Release.Name */}} +{{- end }}{{/* if .Values.fullnameOverride */}} +{{- end }}{{/* define "spider.fullname" */}} + +{{/* +Creates a fully qualified component name while preserving its suffix within the 63-character limit. + +@param {object} root Root template context (required) +@param {string} component Component name suffix (required) +@return {string} The fully qualified component name +*/}} +{{- define "spider.componentFullname" -}} +{{- $suffix := printf "-%s" .component -}} +{{- $maxBaseLength := sub 63 (len $suffix) | int -}} +{{- $base := include "spider.fullname" .root | trunc $maxBaseLength | trimSuffix "-" -}} +{{- printf "%s%s" $base $suffix -}} +{{- end }} + +{{/* +Creates chart name and version as used by the chart label. + +@return {string} Chart name and version (truncated to 63 characters) +*/}} +{{- define "spider.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Creates common labels for all resources. + +@return {string} YAML-formatted common labels +*/}} +{{- define "spider.labels" -}} +helm.sh/chart: {{ include "spider.chart" . }} +{{ include "spider.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Creates selector labels for matching resources. + +@return {string} YAML-formatted selector labels +*/}} +{{- define "spider.selectorLabels" -}} +app.kubernetes.io/name: {{ include "spider.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Creates a container image reference from .Values.image. + +Renders repository@digest when "digest" is set; otherwise, requires "tag" and renders repository:tag. + +@param {object} root Root template context (required) +@param {string} component Key under .Values.image (e.g., "storage", "database") +@return {string} Full image reference (repository@digest or repository:tag) +*/}} +{{- define "spider.imageRef" -}} +{{- $img := index .root.Values.image .component -}} +{{- if $img.digest -}} +{{- printf "%s@%s" $img.repository $img.digest -}} +{{- else -}} +{{- $tag := required (printf "image.%s.tag is required" .component) $img.tag -}} +{{- printf "%s:%s" $img.repository $tag -}} +{{- end -}} +{{- end }} + +{{/* +Creates timings for readiness probes (faster checks for quicker startup). + +@return {string} YAML-formatted readiness probe timing configuration +*/}} +{{- define "spider.readinessProbeTimings" -}} +initialDelaySeconds: 6 +periodSeconds: 2 +timeoutSeconds: 2 +failureThreshold: 10 +{{- end }} + +{{/* +Creates timings for liveness probes. + +@return {string} YAML-formatted liveness probe timing configuration +*/}} +{{- define "spider.livenessProbeTimings" -}} +initialDelaySeconds: 180 +periodSeconds: 30 +timeoutSeconds: 4 +failureThreshold: 3 +{{- end }} + +{{/* +Gets the bundled database Service host or external `spiderConfig.database.host`. + +@param {object} . Root template context +@return {string} The database host +*/}} +{{- define "spider.databaseHost" -}} +{{- if has "database" .Values.spiderConfig.bundled -}} +{{- include "spider.componentFullname" (dict "root" . "component" "database") -}} +{{- else -}} +{{- .Values.spiderConfig.database.host -}} +{{- end -}} +{{- end }} + +{{/* +Gets the bundled database port or external `spiderConfig.database.port`. + +@param {object} . Root template context +@return {string} The database port +*/}} +{{- define "spider.databasePort" -}} +{{- if has "database" .Values.spiderConfig.bundled -}} +3306 +{{- else -}} +{{- .Values.spiderConfig.database.port -}} +{{- end -}} +{{- end }} diff --git a/tools/deployment/spider-helm/templates/configmap.yaml b/tools/deployment/spider-helm/templates/configmap.yaml new file mode 100644 index 00000000..7e0aa0a6 --- /dev/null +++ b/tools/deployment/spider-helm/templates/configmap.yaml @@ -0,0 +1,19 @@ +apiVersion: "v1" +kind: "ConfigMap" +metadata: + name: {{ include "spider.componentFullname" (dict "root" . "component" "config") }} + labels: + {{- include "spider.labels" . | nindent 4 }} +data: + storage.yaml: | + host: "0.0.0.0" + port: {{ .Values.spiderConfig.storage.port }} + runtime: + db_config: + host: {{ include "spider.databaseHost" . | quote }} + max_connections: {{ .Values.spiderConfig.database.max_connections }} + name: {{ .Values.spiderConfig.database.name | quote }} + port: {{ include "spider.databasePort" . }} + {{- with .Values.spiderConfig.storage.runtime }} + {{- toYaml . | nindent 6 }} + {{- end }} diff --git a/tools/deployment/spider-helm/templates/database-secret.yaml b/tools/deployment/spider-helm/templates/database-secret.yaml new file mode 100644 index 00000000..5d34650c --- /dev/null +++ b/tools/deployment/spider-helm/templates/database-secret.yaml @@ -0,0 +1,14 @@ +apiVersion: "v1" +kind: "Secret" +metadata: + name: {{ include "spider.componentFullname" (dict "root" . "component" "database") }} + labels: + {{- include "spider.labels" . | nindent 4 }} + app.kubernetes.io/component: "database" +type: "Opaque" +stringData: + username: {{ .Values.spiderConfig.database.username | quote }} + password: {{ .Values.spiderConfig.database.password | quote }} + {{- if has "database" .Values.spiderConfig.bundled }} + root_password: {{ .Values.spiderConfig.database.root_password | quote }} + {{- end }} diff --git a/tools/deployment/spider-helm/templates/database-service.yaml b/tools/deployment/spider-helm/templates/database-service.yaml new file mode 100644 index 00000000..98bbab3b --- /dev/null +++ b/tools/deployment/spider-helm/templates/database-service.yaml @@ -0,0 +1,17 @@ +{{- if has "database" .Values.spiderConfig.bundled }} +apiVersion: "v1" +kind: "Service" +metadata: + name: {{ include "spider.componentFullname" (dict "root" . "component" "database") }} + labels: + {{- include "spider.labels" . | nindent 4 }} + app.kubernetes.io/component: "database" +spec: + clusterIP: "None" + selector: + {{- include "spider.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: "database" + ports: + - port: 3306 + targetPort: "database" +{{- end }} diff --git a/tools/deployment/spider-helm/templates/database-statefulset.yaml b/tools/deployment/spider-helm/templates/database-statefulset.yaml new file mode 100644 index 00000000..60b09efc --- /dev/null +++ b/tools/deployment/spider-helm/templates/database-statefulset.yaml @@ -0,0 +1,71 @@ +{{- if has "database" .Values.spiderConfig.bundled }} +apiVersion: "apps/v1" +kind: "StatefulSet" +metadata: + name: {{ include "spider.componentFullname" (dict "root" . "component" "database") }} + labels: + {{- include "spider.labels" . | nindent 4 }} + app.kubernetes.io/component: "database" +spec: + serviceName: {{ include "spider.componentFullname" (dict "root" . "component" "database") }} + replicas: 1 + selector: + matchLabels: + {{- include "spider.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: "database" + template: + metadata: + labels: + {{- include "spider.labels" . | nindent 8 }} + app.kubernetes.io/component: "database" + spec: + containers: + - name: "database" + image: {{ include "spider.imageRef" (dict "root" . "component" "database") | quote }} + imagePullPolicy: {{ .Values.image.database.pullPolicy | quote }} + env: + - name: "MYSQL_DATABASE" + value: {{ .Values.spiderConfig.database.name | quote }} + - name: "MYSQL_USER" + valueFrom: + secretKeyRef: + name: {{ include "spider.componentFullname" (dict "root" . "component" "database") }} + key: "username" + - name: "MYSQL_PASSWORD" + valueFrom: + secretKeyRef: + name: {{ include "spider.componentFullname" (dict "root" . "component" "database") }} + key: "password" + - name: "MYSQL_ROOT_PASSWORD" + valueFrom: + secretKeyRef: + name: {{ include "spider.componentFullname" (dict "root" . "component" "database") }} + key: "root_password" + ports: + - name: "database" + containerPort: 3306 + volumeMounts: + - name: "data" + mountPath: "/var/lib/mysql" + readinessProbe: + {{- include "spider.readinessProbeTimings" . | nindent 12 }} + exec: &health-check + command: [ + "mysqladmin", "ping", + "--host=127.0.0.1", + "--port=3306", + "--user=$(MYSQL_USER)", + "--password=$(MYSQL_PASSWORD)" + ] + livenessProbe: + {{- include "spider.livenessProbeTimings" . | nindent 12 }} + exec: *health-check + volumeClaimTemplates: + - metadata: + name: "data" + spec: + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: "20Gi" +{{- end }} diff --git a/tools/deployment/spider-helm/templates/storage-deployment.yaml b/tools/deployment/spider-helm/templates/storage-deployment.yaml new file mode 100644 index 00000000..5bc1b635 --- /dev/null +++ b/tools/deployment/spider-helm/templates/storage-deployment.yaml @@ -0,0 +1,55 @@ +apiVersion: "apps/v1" +kind: "Deployment" +metadata: + name: {{ include "spider.componentFullname" (dict "root" . "component" "storage") }} + labels: + {{- include "spider.labels" . | nindent 4 }} + app.kubernetes.io/component: "storage" +spec: + replicas: 1 + selector: + matchLabels: + {{- include "spider.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: "storage" + template: + metadata: + labels: + {{- include "spider.labels" . | nindent 8 }} + app.kubernetes.io/component: "storage" + spec: + containers: + - name: "storage" + image: {{ include "spider.imageRef" (dict "root" . "component" "storage") | quote }} + imagePullPolicy: {{ .Values.image.storage.pullPolicy | quote }} + command: ["spider-storage", "--config", "/etc/spider/storage.yaml"] + env: + - name: "SPIDER_STORAGE_DB_USERNAME" + valueFrom: + secretKeyRef: + name: {{ include "spider.componentFullname" (dict "root" . "component" "database") }} + key: "username" + - name: "SPIDER_STORAGE_DB_PASSWORD" + valueFrom: + secretKeyRef: + name: {{ include "spider.componentFullname" (dict "root" . "component" "database") }} + key: "password" + ports: + - name: "grpc" + containerPort: {{ .Values.spiderConfig.storage.port }} + volumeMounts: + - name: "config" + mountPath: "/etc/spider/storage.yaml" + subPath: "storage.yaml" + readOnly: true + readinessProbe: + {{- include "spider.readinessProbeTimings" . | nindent 12 }} + tcpSocket: + port: "grpc" + livenessProbe: + {{- include "spider.livenessProbeTimings" . | nindent 12 }} + tcpSocket: + port: "grpc" + volumes: + - name: "config" + configMap: + name: {{ include "spider.componentFullname" (dict "root" . "component" "config") }} diff --git a/tools/deployment/spider-helm/templates/storage-service.yaml b/tools/deployment/spider-helm/templates/storage-service.yaml new file mode 100644 index 00000000..a853f94d --- /dev/null +++ b/tools/deployment/spider-helm/templates/storage-service.yaml @@ -0,0 +1,15 @@ +apiVersion: "v1" +kind: "Service" +metadata: + name: {{ include "spider.componentFullname" (dict "root" . "component" "storage") }} + labels: + {{- include "spider.labels" . | nindent 4 }} + app.kubernetes.io/component: "storage" +spec: + selector: + {{- include "spider.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: "storage" + ports: + - name: "grpc" + port: {{ .Values.spiderConfig.storage.port }} + targetPort: "grpc" diff --git a/tools/deployment/spider-helm/values.yaml b/tools/deployment/spider-helm/values.yaml index 8b137891..5d47931a 100644 --- a/tools/deployment/spider-helm/values.yaml +++ b/tools/deployment/spider-helm/values.yaml @@ -1 +1,39 @@ +fullnameOverride: "" +nameOverride: "" +image: + database: + pullPolicy: "Always" + repository: "mariadb" + tag: "10.11.16" + storage: + pullPolicy: "Always" + repository: "ghcr.io/y-scope/spider/storage" + tag: "main" + +spiderConfig: + # List of third-party services bundled (deployed) as part of the chart. + # Remove a service from this list to use an external instance instead, and configure its host/port + # accordingly in the service-specific sections below. + bundled: + - "database" + + database: + # Host and port for the database service. When "database" is in `bundled`, the host is + # automatically set to the bundled service name (ignored). When external, set these to the + # external service's address. + host: "127.0.0.1" + max_connections: 64 + name: "spider-db" + password: "spider-password" + port: 3306 + root_password: "spider-root-password" + username: "spider-user" + + storage: + port: 50051 + runtime: + ready_queue_config: + cleanup_capacity: 256 + commit_capacity: 256 + task_capacity: 1048576