diff --git a/charts/miroir/Chart.yaml b/charts/miroir/Chart.yaml index 362cc98..00111ed 100644 --- a/charts/miroir/Chart.yaml +++ b/charts/miroir/Chart.yaml @@ -1,6 +1,26 @@ apiVersion: v2 name: miroir -description: Distributed search orchestrator for Meilisearch -type: application version: 0.1.0 -appVersion: "0.1.0" +appVersion: 0.1.0 +description: RAID-like sharding and HA for Meilisearch Community Edition +keywords: + - search + - meilisearch + - sharding + - kubernetes +home: https://github.com/jedarden/miroir +sources: + - https://github.com/jedarden/miroir +maintainers: + - name: jedarden + url: https://github.com/jedarden +icon: https://raw.githubusercontent.com/meilisearch/meilisearch/main/assets/logo.svg +annotations: + artifacthub.io/category: database + artifacthub.io/license: MIT + artifacthub.io/links: | + - name: Documentation + url: https://github.com/jedarden/miroir + artifacthub.io/operator: "false" + artifacthub.io/prerelease: "false" +kubeVersion: ">=1.25.0-0" diff --git a/charts/miroir/templates/NOTES.txt b/charts/miroir/templates/NOTES.txt new file mode 100644 index 0000000..3d75c9b --- /dev/null +++ b/charts/miroir/templates/NOTES.txt @@ -0,0 +1,25 @@ +Miroir has been installed! + +Get the service URL: + export POD_NAME=$(kubectl get pods -n {{ .Release.Namespace }} -l "app.kubernetes.io/instance={{ .Release.Name }},app.kubernetes.io/component=miroir" -o jsonpath="{.items[0].metadata.name}") + kubectl port-forward -n {{ .Release.Namespace }} "$POD_NAME" 7700:7700 + +Then visit http://localhost:7700/health to verify the proxy is running. + +Components deployed: + - Miroir proxy ({{ .Values.miroir.replicas }} replica(s)) + - Meilisearch ({{ .Values.meilisearch.replicas }} node(s)) +{{- if eq (include "miroir.redisEnabled" .) "true" }} + - Redis (task store) +{{- else }} + - SQLite task store (embedded) +{{- end }} + +!!! PRODUCTION UPGRADE PATH !!! +These defaults are for dev/CI (single-pod evaluation). For production, override: + miroir.replicas=2+ + miroir.replicationFactor=2 + miroir.replicaGroups=2 + taskStore.backend=redis + redis.enabled=true + hpa.enabled=true diff --git a/charts/miroir/templates/_helpers.tpl b/charts/miroir/templates/_helpers.tpl new file mode 100644 index 0000000..efa4341 --- /dev/null +++ b/charts/miroir/templates/_helpers.tpl @@ -0,0 +1,190 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "miroir.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +*/}} +{{- define "miroir.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 }} + +{{/* +Common labels +*/}} +{{- define "miroir.labels" -}} +helm.sh/chart: {{ printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{ include "miroir.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "miroir.selectorLabels" -}} +app.kubernetes.io/name: {{ include "miroir.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +ServiceAccount name +*/}} +{{- define "miroir.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "miroir.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Secret name +*/}} +{{- define "miroir.secretName" -}} +{{- if .Values.miroir.existingSecret }} +{{- .Values.miroir.existingSecret }} +{{- else }} +{{- include "miroir.fullname" . }}-secret +{{- end }} +{{- end }} + +{{/* +Generate the full DNS address for a Meilisearch node. + +Usage: + {{ include "miroir.meilisearchNodeAddress" (dict "release" .Release "namespace" .Namespace "nodeIndex" 0) }} + +Returns: + http://release-name-meili-0.release-name-meili-headless.namespace.svc.cluster.local:7700 +*/}} +{{- define "miroir.meilisearchNodeAddress" -}} +{{- $ns := .namespace | default "default" -}} +http://{{ .release.Name }}-meili-{{ .nodeIndex }}.{{ .release.Name }}-meili-headless.{{ $ns }}.svc.cluster.local:7700 +{{- end -}} + +{{/* +Generate the list of Meilisearch node addresses for the ConfigMap. + +Usage: + {{ include "miroir.meilisearchNodeList" $ }} + +Returns a YAML-formatted list of node entries for the miroir config. +*/}} +{{- define "miroir.meilisearchNodeList" -}} +{{- $meiliReplicas := .Values.meilisearch.replicas | default 2 | int -}} +{{- $nodesPerGroup := .Values.meilisearch.nodesPerGroup | default 2 | int -}} +{{- $replicaGroups := .Values.miroir.replicaGroups | default 1 | int -}} +{{- range $group := until $replicaGroups -}} +{{- range $node := until $nodesPerGroup -}} +{{- $nodeIndex := add (mul $group $nodesPerGroup) $node }} +- id: "meili-{{ $nodeIndex }}" + address: {{ include "miroir.meilisearchNodeAddress" (dict "release" $.Release "namespace" $.Namespace "nodeIndex" $nodeIndex) }} + replica_group: {{ $group }} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Generate the miroir YAML config for the ConfigMap. + +Usage: + {{ include "miroir.config" $ }} +*/}} +{{- define "miroir.config" -}} +shards: {{ .Values.miroir.shards | default 64 }} +replication_factor: {{ .Values.miroir.replicationFactor | default 1 }} +replica_groups: {{ .Values.miroir.replicaGroups | default 1 }} +nodes: +{{ include "miroir.meilisearchNodeList" . | indent 2 }} +task_store: + backend: {{ .Values.taskStore.backend | default "sqlite" }} + path: {{ .Values.taskStore.path | default "/data/miroir-tasks.db" }} + {{- if eq (include "miroir.redisEnabled" .) "true" }} + url: redis://{{ .Release.Name }}-redis.{{ .Release.Namespace | default "default" }}.svc.cluster.local:6379 + {{- end }} +health: + interval_ms: 5000 + timeout_ms: 2000 + unhealthy_threshold: 3 + recovery_threshold: 2 +scatter: + node_timeout_ms: 5000 + retry_on_timeout: true + unavailable_shard_policy: partial +rebalancer: + auto_rebalance_on_recovery: true + max_concurrent_migrations: 4 + migration_timeout_s: 3600 +server: + port: 7700 + bind: "0.0.0.0" + max_body_bytes: 104857600 + max_concurrent_requests: 500 + request_timeout_ms: 30000 +connection_pool_per_node: + max_idle: 32 + max_total: 128 + idle_timeout_s: 60 +task_registry: + cache_size: 10000 + redis_pool_max: 50 + ttl_seconds: 604800 + prune_interval_s: 300 + prune_batch_size: 10000 +peer_discovery: + service_name: {{ .Release.Name }}-headless + refresh_interval_s: 15 +leader_election: + enabled: true + lease_ttl_s: 10 + renew_interval_s: 3 +hpa: + enabled: {{ .Values.hpa.enabled | default false }} +tracing: + enabled: {{ .Values.tracing.enabled | default false }} + endpoint: {{ .Values.tracing.endpoint | default "http://tempo.monitoring.svc:4317" }} + service_name: {{ .Values.tracing.serviceName | default "miroir" }} + sample_rate: {{ .Values.tracing.sampleRate | default 0.1 }} +{{- if .Values.miroir.cdc }} +cdc: + enabled: {{ .Values.miroir.cdc.enabled | default true }} + emit_ttl_deletes: {{ .Values.miroir.cdc.emit_ttl_deletes | default false }} + emit_internal_writes: {{ .Values.miroir.cdc.emit_internal_writes | default false }} + buffer: + primary: {{ .Values.miroir.cdc.buffer.primary | default "memory" }} + memory_bytes: {{ .Values.miroir.cdc.buffer.memory_bytes | default 67108864 }} + overflow: {{ .Values.miroir.cdc.buffer.overflow | default "drop" }} + {{- if eq (include "miroir.redisEnabled" .) "true" }} + redis_bytes: {{ .Values.miroir.cdc.buffer.redis_bytes | default 1073741824 }} + {{- end }} +{{- end }} +{{- end -}} + +{{/* +Return "true" if Redis is enabled, "false" otherwise. +*/}} +{{- define "miroir.redisEnabled" -}} +{{- if .Values.redis.enabled -}}true{{- else -}}false{{- end -}} +{{- end -}} + +{{/* +Return "true" if CDC PVC should be created, "false" otherwise. +*/}} +{{- define "miroir.cdcPvcEnabled" -}} +{{- if .Values.cdcPvc.enabled -}}true{{- else -}}false{{- end -}} +{{- end -}} diff --git a/charts/miroir/templates/meilisearch-service.yaml b/charts/miroir/templates/meilisearch-service.yaml new file mode 100644 index 0000000..f99f08f --- /dev/null +++ b/charts/miroir/templates/meilisearch-service.yaml @@ -0,0 +1,45 @@ +{{/* +Meilisearch Service +*/}} +{{- if .Values.meilisearch.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "miroir.fullname" . }}-meili + labels: + {{- include "miroir.labels" . | nindent 4 }} + app.kubernetes.io/component: meilisearch +spec: + type: ClusterIP + ports: + - port: 7700 + targetPort: http + protocol: TCP + name: http + selector: + {{- include "miroir.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: meilisearch +--- +{{/* +Meilisearch Headless Service for StatefulSet DNS +*/}} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "miroir.fullname" . }}-meili-headless + labels: + {{- include "miroir.labels" . | nindent 4 }} + app.kubernetes.io/component: meilisearch +spec: + type: ClusterIP + clusterIP: None + publishNotReadyAddresses: true + ports: + - port: 7700 + targetPort: http + protocol: TCP + name: http + selector: + {{- include "miroir.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: meilisearch +{{- end }} diff --git a/charts/miroir/templates/meilisearch-statefulset.yaml b/charts/miroir/templates/meilisearch-statefulset.yaml new file mode 100644 index 0000000..fde87eb --- /dev/null +++ b/charts/miroir/templates/meilisearch-statefulset.yaml @@ -0,0 +1,111 @@ +{{/* +Meilisearch StatefulSet +*/}} +{{- if .Values.meilisearch.enabled }} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "miroir.fullname" . }}-meili + labels: + {{- include "miroir.labels" . | nindent 4 }} + app.kubernetes.io/component: meilisearch +spec: + serviceName: {{ include "miroir.fullname" . }}-meili-headless + replicas: {{ .Values.meilisearch.replicas }} + selector: + matchLabels: + {{- include "miroir.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: meilisearch + template: + metadata: + annotations: + {{- with .Values.meilisearch.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "miroir.selectorLabels" . | nindent 8 }} + app.kubernetes.io/component: meilisearch + {{- with .Values.meilisearch.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + securityContext: + runAsNonRoot: true + runAsUser: 1000 + fsGroup: 1000 + containers: + - name: meilisearch + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: false + image: "{{ .Values.meilisearch.image.repository }}:{{ .Values.meilisearch.image.tag }}" + imagePullPolicy: {{ .Values.meilisearch.image.pullPolicy }} + ports: + - name: http + containerPort: 7700 + protocol: TCP + env: + - name: MEILI_MASTER_KEY + valueFrom: + secretKeyRef: + name: {{ include "miroir.secretName" . }} + key: nodeMasterKey + - name: MEILI_ENV + value: "production" + {{- with .Values.meilisearch.env }} + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - name: data + mountPath: /meili_data + livenessProbe: + httpGet: + path: /health + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 3 + readinessProbe: + httpGet: + path: /health + port: http + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 3 + failureThreshold: 2 + resources: + {{- toYaml .Values.meilisearch.resources | nindent 12 }} + {{- with .Values.meilisearch.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.meilisearch.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.meilisearch.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.meilisearch.persistence.enabled }} + volumeClaimTemplates: + - metadata: + name: data + labels: + {{- include "miroir.labels" . | nindent 10 }} + app.kubernetes.io/component: meilisearch + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.meilisearch.persistence.size }} + {{- if .Values.meilisearch.persistence.storageClass }} + storageClassName: {{ .Values.meilisearch.persistence.storageClass }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/miroir/templates/miroir-configmap.yaml b/charts/miroir/templates/miroir-configmap.yaml new file mode 100644 index 0000000..d5b935a --- /dev/null +++ b/charts/miroir/templates/miroir-configmap.yaml @@ -0,0 +1,15 @@ +{{/* +Miroir ConfigMap +*/}} +{{- if .Values.miroir.replicas }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "miroir.fullname" . }}-config + labels: + {{- include "miroir.labels" . | nindent 4 }} + app.kubernetes.io/component: miroir +data: + miroir.yaml: | +{{ include "miroir.config" . | indent 4 }} +{{- end }} diff --git a/charts/miroir/templates/miroir-deployment.yaml b/charts/miroir/templates/miroir-deployment.yaml new file mode 100644 index 0000000..08de087 --- /dev/null +++ b/charts/miroir/templates/miroir-deployment.yaml @@ -0,0 +1,140 @@ +{{/* +Miroir Deployment +*/}} +{{- if .Values.miroir.replicas }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "miroir.fullname" . }}-miroir + labels: + {{- include "miroir.labels" . | nindent 4 }} + app.kubernetes.io/component: miroir +spec: + {{- if not .Values.hpa.enabled }} + replicas: {{ .Values.miroir.replicas }} + {{- end }} + selector: + matchLabels: + {{- include "miroir.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: miroir + template: + metadata: + annotations: + prometheus.io/scrape: "true" + prometheus.io/port: "9090" + prometheus.io/path: "/metrics" + {{- with .Values.miroir.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "miroir.selectorLabels" . | nindent 8 }} + app.kubernetes.io/component: miroir + {{- with .Values.miroir.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ include "miroir.serviceAccountName" . }} + securityContext: + runAsNonRoot: true + runAsUser: 1000 + fsGroup: 1000 + {{- if eq (include "miroir.cdcPvcEnabled" .) "true" }} + fsGroupChangePolicy: OnRootMismatch + {{- end }} + containers: + - name: miroir + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: false + image: "{{ .Values.miroir.image.repository }}:{{ .Values.miroir.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.miroir.image.pullPolicy }} + ports: + - name: http + containerPort: 7700 + protocol: TCP + - name: metrics + containerPort: 9090 + protocol: TCP + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: MIROIR_CONFIG_PATH + value: /config/miroir.yaml + - name: MIROIR_MASTER_KEY + valueFrom: + secretKeyRef: + name: {{ include "miroir.secretName" . }} + key: masterKey + - name: MIROIR_NODE_MASTER_KEY + valueFrom: + secretKeyRef: + name: {{ include "miroir.secretName" . }} + key: nodeMasterKey + - name: MIROIR_ADMIN_API_KEY + valueFrom: + secretKeyRef: + name: {{ include "miroir.secretName" . }} + key: adminApiKey + - name: RUST_LOG + value: {{ .Values.miroir.logLevel | default "info" }} + volumeMounts: + - name: config + mountPath: /config + readOnly: true + - name: data + mountPath: /data + {{- if eq (include "miroir.cdcPvcEnabled" .) "true" }} + - name: cdc-buffer + mountPath: /cdc + {{- end }} + livenessProbe: + httpGet: + path: /health + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 3 + readinessProbe: + httpGet: + path: /health + port: http + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 3 + failureThreshold: 2 + resources: + {{- toYaml .Values.miroir.resources | nindent 12 }} + volumes: + - name: config + configMap: + name: {{ include "miroir.fullname" . }}-config + - name: data + emptyDir: {} + {{- if eq (include "miroir.cdcPvcEnabled" .) "true" }} + - name: cdc-buffer + persistentVolumeClaim: + claimName: {{ include "miroir.fullname" . }}-cdc-pvc + {{- end }} + {{- with .Values.miroir.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.miroir.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.miroir.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/charts/miroir/templates/miroir-headless.yaml b/charts/miroir/templates/miroir-headless.yaml new file mode 100644 index 0000000..27ac109 --- /dev/null +++ b/charts/miroir/templates/miroir-headless.yaml @@ -0,0 +1,27 @@ +{{/* +Miroir Headless Service for peer discovery +*/}} +{{- if .Values.miroir.replicas }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "miroir.fullname" . }}-headless + labels: + {{- include "miroir.labels" . | nindent 4 }} + app.kubernetes.io/component: miroir + {{- with .Values.headless.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + type: ClusterIP + clusterIP: None + ports: + - port: {{ .Values.service.ports.http | default 7700 }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "miroir.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: miroir +{{- end }} diff --git a/charts/miroir/templates/miroir-hpa.yaml b/charts/miroir/templates/miroir-hpa.yaml new file mode 100644 index 0000000..b969b9e --- /dev/null +++ b/charts/miroir/templates/miroir-hpa.yaml @@ -0,0 +1,40 @@ +{{/* +Miroir Horizontal Pod Autoscaler +*/}} +{{- if and .Values.miroir.replicas .Values.hpa.enabled }} +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "miroir.fullname" . }}-miroir + labels: + {{- include "miroir.labels" . | nindent 4 }} + app.kubernetes.io/component: miroir +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "miroir.fullname" . }}-miroir + minReplicas: {{ .Values.hpa.minReplicas }} + maxReplicas: {{ .Values.hpa.maxReplicas }} + metrics: + {{- if .Values.hpa.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: {{ .Values.hpa.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.hpa.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: {{ .Values.hpa.targetMemoryUtilizationPercentage }} + {{- end }} + {{- with .Values.hpa.behavior }} + behavior: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/miroir/templates/miroir-pvc.yaml b/charts/miroir/templates/miroir-pvc.yaml new file mode 100644 index 0000000..12c8a08 --- /dev/null +++ b/charts/miroir/templates/miroir-pvc.yaml @@ -0,0 +1,22 @@ +{{/* +Miroir CDC Buffer PVC +Only rendered when cdcPvc.enabled=true +*/}} +{{- if eq (include "miroir.cdcPvcEnabled" .) "true" }} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "miroir.fullname" . }}-cdc-pvc + labels: + {{- include "miroir.labels" . | nindent 4 }} + app.kubernetes.io/component: miroir +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.cdcPvc.size | default "5Gi" }} + {{- if .Values.cdcPvc.storageClass }} + storageClassName: {{ .Values.cdcPvc.storageClass }} + {{- end }} +{{- end }} diff --git a/charts/miroir/templates/miroir-secret.yaml b/charts/miroir/templates/miroir-secret.yaml new file mode 100644 index 0000000..bc64e5f --- /dev/null +++ b/charts/miroir/templates/miroir-secret.yaml @@ -0,0 +1,17 @@ +{{/* +Miroir Secret +*/}} +{{- if and .Values.miroir.replicas (not .Values.miroir.existingSecret) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "miroir.fullname" . }}-secret + labels: + {{- include "miroir.labels" . | nindent 4 }} + app.kubernetes.io/component: miroir +type: Opaque +stringData: + masterKey: {{ .Values.miroir.masterKey | default (randAlphaNum 32) | quote }} + nodeMasterKey: {{ .Values.meilisearch.masterKey | default (randAlphaNum 32) | quote }} + adminApiKey: {{ .Values.miroir.adminApiKey | default (randAlphaNum 32) | quote }} +{{- end }} diff --git a/charts/miroir/templates/redis-deployment.yaml b/charts/miroir/templates/redis-deployment.yaml new file mode 100644 index 0000000..735072a --- /dev/null +++ b/charts/miroir/templates/redis-deployment.yaml @@ -0,0 +1,115 @@ +{{/* +Redis Deployment (only when taskStore.backend=redis) +*/}} +{{- if eq (include "miroir.redisEnabled" .) "true" }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "miroir.fullname" . }}-redis + labels: + {{- include "miroir.labels" . | nindent 4 }} + app.kubernetes.io/component: redis +spec: + replicas: {{ .Values.redis.replicas }} + selector: + matchLabels: + {{- include "miroir.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: redis + template: + metadata: + annotations: + {{- with .Values.redis.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "miroir.selectorLabels" . | nindent 8 }} + app.kubernetes.io/component: redis + {{- with .Values.redis.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + securityContext: + runAsNonRoot: true + runAsUser: 999 + fsGroup: 999 + containers: + - name: redis + image: "{{ .Values.redis.image.repository }}:{{ .Values.redis.image.tag }}" + imagePullPolicy: {{ .Values.redis.image.pullPolicy }} + ports: + - name: redis + containerPort: 6379 + protocol: TCP + {{- if .Values.redis.persistence.enabled }} + volumeMounts: + - name: data + mountPath: /data + {{- end }} + livenessProbe: + exec: + command: ["redis-cli", "ping"] + initialDelaySeconds: 5 + periodSeconds: 10 + readinessProbe: + exec: + command: ["redis-cli", "ping"] + initialDelaySeconds: 3 + periodSeconds: 5 + resources: + {{- toYaml .Values.redis.resources | nindent 12 }} + {{- if .Values.redis.persistence.enabled }} + volumes: + - name: data + persistentVolumeClaim: + claimName: {{ include "miroir.fullname" . }}-redis-data + {{- end }} + {{- with .Values.redis.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.redis.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.redis.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "miroir.fullname" . }}-redis + labels: + {{- include "miroir.labels" . | nindent 4 }} + app.kubernetes.io/component: redis +spec: + type: {{ .Values.redis.service.type | default "ClusterIP" }} + ports: + - port: {{ .Values.redis.service.port | default 6379 }} + targetPort: redis + protocol: TCP + name: redis + selector: + {{- include "miroir.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: redis +{{- if .Values.redis.persistence.enabled }} +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "miroir.fullname" . }}-redis-data + labels: + {{- include "miroir.labels" . | nindent 4 }} + app.kubernetes.io/component: redis +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.redis.persistence.size | default "1Gi" }} + {{- if .Values.redis.persistence.storageClass }} + storageClassName: {{ .Values.redis.persistence.storageClass }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/miroir/templates/serviceaccount.yaml b/charts/miroir/templates/serviceaccount.yaml new file mode 100644 index 0000000..03ca836 --- /dev/null +++ b/charts/miroir/templates/serviceaccount.yaml @@ -0,0 +1,15 @@ +{{/* +ServiceAccount +*/}} +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "miroir.serviceAccountName" . }} + labels: + {{- include "miroir.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/miroir/tests/connection-test.yaml b/charts/miroir/tests/connection-test.yaml new file mode 100644 index 0000000..a8ae7ca --- /dev/null +++ b/charts/miroir/tests/connection-test.yaml @@ -0,0 +1,18 @@ +{{/* +Helm test: verify miroir proxy is healthy +*/}} +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "miroir.fullname" . }}-connection-test" + labels: + {{- include "miroir.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +spec: + containers: + - name: curl + image: curlimages/curl:latest + command: ["curl", "-f", "http://{{ include "miroir.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local:7700/health"] + restartPolicy: Never diff --git a/charts/miroir/values.schema.json b/charts/miroir/values.schema.json index fd79990..5f4ff05 100644 --- a/charts/miroir/values.schema.json +++ b/charts/miroir/values.schema.json @@ -31,6 +31,7 @@ "minimum": 1 }, "existingSecret": { "type": "string" }, + "logLevel": { "type": "string", "enum": ["trace", "debug", "info", "warn", "error"] }, "podAnnotations": { "type": "object" }, "podLabels": { "type": "object" }, "resources": { diff --git a/charts/miroir/values.yaml b/charts/miroir/values.yaml index c776084..266aa3e 100644 --- a/charts/miroir/values.yaml +++ b/charts/miroir/values.yaml @@ -12,6 +12,9 @@ miroir: shards: 64 replicationFactor: 1 # dev default: override to 2 in production replicaGroups: 1 # dev default: override to 2 in production + masterKey: "" # auto-generated if empty; ignored when existingSecret is set + adminApiKey: "" # auto-generated if empty; ignored when existingSecret is set + logLevel: info # RUST_LOG: trace, debug, info, warn, error existingSecret: "" # name of K8s Secret with masterKey, nodeMasterKey, adminApiKey podAnnotations: {} podLabels: {}