From 7676196b8a4e45b5d8bde04f3786de32e525aae2 Mon Sep 17 00:00:00 2001 From: Gabriel Radureau Date: Thu, 4 Dec 2025 12:58:03 +0100 Subject: [PATCH] use pascaliske chart for redis --- redis/Chart.yaml | 21 ++- redis/templates/NOTES.txt | 12 -- redis/templates/_helpers.tpl | 11 -- redis/templates/configmap.yaml | 24 --- redis/templates/headless-svc.yaml | 17 -- redis/templates/helm-chart-config.yaml | 3 + redis/templates/helm-chart.yaml | 3 + redis/templates/secret-auth.yaml | 11 -- redis/templates/statefulset.yaml | 135 -------------- redis/values.yaml | 234 ++++++++++++++++++++----- 10 files changed, 211 insertions(+), 260 deletions(-) delete mode 100644 redis/templates/NOTES.txt delete mode 100644 redis/templates/_helpers.tpl delete mode 100644 redis/templates/configmap.yaml delete mode 100644 redis/templates/headless-svc.yaml create mode 100644 redis/templates/helm-chart-config.yaml create mode 100644 redis/templates/helm-chart.yaml delete mode 100644 redis/templates/secret-auth.yaml delete mode 100644 redis/templates/statefulset.yaml diff --git a/redis/Chart.yaml b/redis/Chart.yaml index 61e71b2..4f04eab 100644 --- a/redis/Chart.yaml +++ b/redis/Chart.yaml @@ -10,8 +10,25 @@ # Chart.yaml # ----------------------------------------------------------------------------- apiVersion: v2 -name: keydb-custom # https://chatgpt.com/c/69315a7d-cb88-832c-bc18-3be2b519356d -description: "Custom KeyDB Helm chart for 2-node Master+Replica on Raspberry Pi 5" +name: redis +description: A Helm chart for Kubernetes + +dependencies: +- name: tool + version: 0.1.0 + repository: https://gitea.arcodange.duckdns.org/api/packages/arcodange-org/helm +- name: redis + version: 2.1.0 + repository: https://charts.pascaliske.dev + +# 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 version: 0.1.0 appVersion: "latest" \ No newline at end of file diff --git a/redis/templates/NOTES.txt b/redis/templates/NOTES.txt deleted file mode 100644 index c67b14a..0000000 --- a/redis/templates/NOTES.txt +++ /dev/null @@ -1,12 +0,0 @@ -# ----------------------------------------------------------------------------- -# templates/NOTES.txt -# ----------------------------------------------------------------------------- -{{""}} -1. Get the application URL by running these commands: - export POD0=$(kubectl get pods -l app={{ include "keydb-custom.name" . }} -o jsonpath="{.items[0].metadata.name}") - kubectl logs $POD0 - -2. To connect via keydb-cli from a pod: - kubectl run -it --rm --image=eqalpha/keydb --restart=Never keydb-client -- /bin/sh - # inside the pod: - keydb-cli -h {{ include "keydb-custom.fullname" . }}-0.{{ include "keydb-custom.fullname" . }}-headless -a "{{ .Values.auth.password }}" PING diff --git a/redis/templates/_helpers.tpl b/redis/templates/_helpers.tpl deleted file mode 100644 index b41ae0e..0000000 --- a/redis/templates/_helpers.tpl +++ /dev/null @@ -1,11 +0,0 @@ -# ----------------------------------------------------------------------------- -# templates/_helpers.tpl -# ----------------------------------------------------------------------------- -{{""}} -{{- define "keydb-custom.name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 63 -}} -{{- end -}} - -{{- define "keydb-custom.fullname" -}} -{{- printf "%s" (include "keydb-custom.name" .) -}} -{{- end -}} \ No newline at end of file diff --git a/redis/templates/configmap.yaml b/redis/templates/configmap.yaml deleted file mode 100644 index a8221bd..0000000 --- a/redis/templates/configmap.yaml +++ /dev/null @@ -1,24 +0,0 @@ -# ----------------------------------------------------------------------------- -# templates/configmap.yaml -# ----------------------------------------------------------------------------- -{{""}} -apiVersion: v1 -kind: ConfigMap -metadata: - name: '{{ include "keydb-custom.fullname" . }}-conf' - labels: - app: {{ include "keydb-custom.name" . }} -data: - keydb.conf: | - # Minimal keydb.conf generated from values - server-threads {{ .Values.keydb.serverThreads }} - maxmemory {{ .Values.keydb.maxmemory }} - maxmemory-policy {{ .Values.keydb.maxmemoryPolicy }} - appendonly {{ .Values.keydb.appendonly }} - protected-mode no - bind 0.0.0.0 - port {{ .Values.service.port }} - active-replica yes - scratch-file-path /tmp/ - jemalloc-bg-thread no # doesn't work with rpi5 16ko page size instead of classic 4ko size - # requirepass is handled via env (not in file) \ No newline at end of file diff --git a/redis/templates/headless-svc.yaml b/redis/templates/headless-svc.yaml deleted file mode 100644 index 41877f5..0000000 --- a/redis/templates/headless-svc.yaml +++ /dev/null @@ -1,17 +0,0 @@ -# ----------------------------------------------------------------------------- -# templates/headless-svc.yaml -# ----------------------------------------------------------------------------- -{{""}} -apiVersion: v1 -kind: Service -metadata: - name: '{{ include "keydb-custom.fullname" . }}-headless' - labels: - app: {{ include "keydb-custom.name" . }} -spec: - clusterIP: None - selector: - app: {{ include "keydb-custom.name" . }} - ports: - - port: {{ .Values.service.port }} - name: keydb \ No newline at end of file diff --git a/redis/templates/helm-chart-config.yaml b/redis/templates/helm-chart-config.yaml new file mode 100644 index 0000000..31cb271 --- /dev/null +++ b/redis/templates/helm-chart-config.yaml @@ -0,0 +1,3 @@ +{{- if eq .Values.tool.kind "HelmChart" -}} +{{- include "tool.helm-chart-config.tpl" . -}} +{{- end -}} \ No newline at end of file diff --git a/redis/templates/helm-chart.yaml b/redis/templates/helm-chart.yaml new file mode 100644 index 0000000..c6b793d --- /dev/null +++ b/redis/templates/helm-chart.yaml @@ -0,0 +1,3 @@ +{{- if eq .Values.tool.kind "HelmChart" -}} +{{- include "tool.helm-chart.tpl" . -}} +{{- end -}} \ No newline at end of file diff --git a/redis/templates/secret-auth.yaml b/redis/templates/secret-auth.yaml deleted file mode 100644 index 52aa4e2..0000000 --- a/redis/templates/secret-auth.yaml +++ /dev/null @@ -1,11 +0,0 @@ -# ----------------------------------------------------------------------------- -# templates/secret-auth.yaml -# ----------------------------------------------------------------------------- -{{""}} -apiVersion: v1 -kind: Secret -metadata: - name: '{{ include "keydb-custom.fullname" . }}-auth' -type: Opaque -stringData: - password: "{{ .Values.auth.password }}" \ No newline at end of file diff --git a/redis/templates/statefulset.yaml b/redis/templates/statefulset.yaml deleted file mode 100644 index 1fbebcf..0000000 --- a/redis/templates/statefulset.yaml +++ /dev/null @@ -1,135 +0,0 @@ -# ----------------------------------------------------------------------------- -# templates/statefulset.yaml -# ----------------------------------------------------------------------------- -{{""}} -apiVersion: apps/v1 -kind: StatefulSet -metadata: - name: {{ include "keydb-custom.fullname" . }} - labels: - app: {{ include "keydb-custom.name" . }} -spec: - serviceName: {{ include "keydb-custom.fullname" . }}-headless - replicas: {{ .Values.replicaCount }} - selector: - matchLabels: - app: {{ include "keydb-custom.name" . }} - template: - metadata: - labels: - app: {{ include "keydb-custom.name" . }} - spec: - {{- if .Values.nodeAffinity }} - affinity: - nodeAffinity: {{ toYaml .Values.nodeAffinity | nindent 8 }} - {{- end }} - {{- if .Values.podAntiAffinity.enabled }} - affinity: - podAntiAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - - labelSelector: - matchExpressions: - - key: "app" - operator: In - values: - - {{ include "keydb-custom.name" . }} - topologyKey: "kubernetes.io/hostname" - {{- end }} - containers: - - name: keydb - image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" - imagePullPolicy: {{ .Values.image.pullPolicy }} - ports: - - name: keydb - containerPort: {{ .Values.service.port }} - env: - - name: KEYDB_PASSWORD - valueFrom: - secretKeyRef: - name: {{ include "keydb-custom.fullname" . }}-auth - key: password - - name: KEYDB_CONF_FILE - value: "/etc/keydb/keydb.conf" - volumeMounts: - - name: keydb-conf - mountPath: /etc/keydb - - name: data - mountPath: /bitnami/keydb - resources: - {{ toYaml .Values.resources | nindent 12 }} - command: - - sh - - -c - - | - # Startup logic: - # - pod index 0 starts as master - # - pod index >0 will start and then configure REPLICAOF to master - POD_NAME=$(hostname) - # derive ordinal from pods named - - ORDINAL=${POD_NAME##*-} - # start keydb-server in background to accept CONFIG/CLI commands - keydb-server /etc/keydb/keydb.conf & - sleep 1 - if [ "${ORDINAL}" != "0" ]; then - # wait for master to be ready - MASTER_HOST={{ include "keydb-custom.fullname" . }}-0.{{ include "keydb-custom.fullname" . }}-headless - until nc -z ${MASTER_HOST} {{ .Values.service.port }}; do sleep 1; done - # configure replication (use CLI to set replicaof) - if [ -n "$KEYDB_PASSWORD" ]; then - keydb-cli -a "$KEYDB_PASSWORD" REPLICAOF ${MASTER_HOST} {{ .Values.service.port }} - else - keydb-cli REPLICAOF ${MASTER_HOST} {{ .Values.service.port }} - fi - echo "Configured replicaof ${MASTER_HOST}:{{ .Values.service.port }}" - # tail logs (block) to keep container running - wait - else - # master: block on server process - wait - fi - readinessProbe: - {{- if .Values.readinessProbe.enabled }} - exec: - command: - - sh - - -c - - | - # quick PING check - if [ -n "$KEYDB_PASSWORD" ]; then - keydb-cli -a "$KEYDB_PASSWORD" PING > /dev/null 2>&1 && exit 0 || exit 1 - else - keydb-cli PING > /dev/null 2>&1 && exit 0 || exit 1 - fi - initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.readinessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} - {{- end }} - livenessProbe: - {{- if .Values.livenessProbe.enabled }} - exec: - command: - - sh - - -c - - | - if [ -n "$KEYDB_PASSWORD" ]; then - keydb-cli -a "$KEYDB_PASSWORD" PING > /dev/null 2>&1 && exit 0 || exit 1 - else - keydb-cli PING > /dev/null 2>&1 && exit 0 || exit 1 - fi - initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.livenessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} - {{- end }} - volumes: - - name: keydb-conf - configMap: - name: {{ include "keydb-custom.fullname" . }}-conf - volumeClaimTemplates: - - metadata: - name: data - spec: - accessModes: {{ toYaml .Values.persistence.accessModes | nindent 8 }} - resources: - requests: - storage: {{ .Values.persistence.size }} - storageClassName: "{{ .Values.persistence.storageClass }}" \ No newline at end of file diff --git a/redis/values.yaml b/redis/values.yaml index e4c0b40..62b73a7 100644 --- a/redis/values.yaml +++ b/redis/values.yaml @@ -1,59 +1,197 @@ -# ----------------------------------------------------------------------------- -# values.yaml -# ----------------------------------------------------------------------------- -# Default values - adjust to your environment -replicaCount: 2 +redis: &redis_config + image: + # -- The repository to pull the image from. + repository: redis + # -- The docker tag, if left empty chart's appVersion will be used. + # @default -- `.Chart.AppVersion` + tag: '' + # -- The pull policy for the controller. + pullPolicy: IfNotPresent -image: - repository: eqalpha/keydb - tag: latest - pullPolicy: IfNotPresent + # -- Optionally supply image pull secrets. + imagePullSecrets: [] -service: - port: 6379 - headless: true + nameOverride: '' + fullnameOverride: '' -auth: - enabled: true - password: "redisarcodange" + controller: + # -- Create a workload for this chart. + enabled: true + # -- Type of the workload object. + kind: StatefulSet + # -- The number of replicas. + replicas: 1 + # -- Additional annotations for the controller object. + annotations: {} + # -- Additional labels for the controller object. + labels: {} -keydb: - serverThreads: 4 - maxmemory: "70%" - maxmemoryPolicy: "allkeys-lru" - appendonly: "no" + service: + # -- Create a service for exposing this chart. + enabled: true + # -- The service type used. + type: ClusterIP + # -- ClusterIP used if service type is `ClusterIP`. + clusterIP: '' + # -- LoadBalancerIP if service type is `LoadBalancer`. + loadBalancerIP: '' + # -- Allowed addresses when service type is `LoadBalancer`. + loadBalancerSourceRanges: [] + # -- Additional annotations for the service object. + annotations: {} + # -- Additional labels for the service object. + labels: {} -persistence: - enabled: true - accessModes: - - ReadWriteOnce - size: 1Gi - storageClass: "local-path" # set to your storageClass: longhorn, local-path, etc. + serviceMonitor: + # -- Create a service monitor for prometheus operator. + enabled: false + # -- How frequently the exporter should be scraped. + interval: 30s + # -- Timeout value for individual scrapes. + timeout: 10s + # -- Additional annotations for the service monitor object. + annotations: {} + # -- Additional labels for the service monitor object. + labels: {} -resources: - requests: - cpu: "300m" - memory: "512Mi" - limits: - cpu: "1200m" - memory: "1Gi" + redisExporter: + # -- Enable optional redis exporter instance as sidecar container. + enabled: false + # -- Image for the metric exporter + image: + # -- The repository to pull the image from. + repository: oliver006/redis_exporter + # -- The docker tag, if left empty latest will be used. + # @default -- `latest` + tag: 'latest' + # -- The pull policy for the exporter. + pullPolicy: IfNotPresent + # -- Pod-level security attributes. More info [here](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context). + securityContext: + runAsUser: 59000 + runAsGroup: 59000 + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + # -- Compute resources used by the container. More info [here](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/). + resources: + requests: + cpu: 10m + memory: 50Mi + limits: + cpu: 100m + memory: 100Mi -nodeAffinity: {} + env: + # -- Timezone for the container. + - name: TZ + value: Europe/Paris -podAntiAffinity: - enabled: true + # -- List of extra arguments for the container. + extraArgs: [] + # - --loglevel warning -securityContext: - enabled: false + ports: + redis: + # -- Enable the port inside the `Controller` and `Service` objects. + enabled: true + # -- The port used as internal port and cluster-wide port if `.service.type` == `ClusterIP`. + port: 6379 + # -- The external port used if `.service.type` == `NodePort`. + nodePort: null + # -- The protocol used for the service. + protocol: TCP + # -- The application protocol for this port. Used as hint for implementations to offer richer behavior. + appProtocol: redis -livenessProbe: - enabled: true - initialDelaySeconds: 30 - periodSeconds: 10 - timeoutSeconds: 5 + persistentVolumeClaim: + # -- Create a new persistent volume claim object. + create: true + # -- Mount path of the persistent volume claim object. + mountPath: /data + # -- Access mode of the persistent volume claim object. + accessMode: ReadWriteOnce + # -- Volume mode of the persistent volume claim object. + volumeMode: Filesystem + # -- Storage request size for the persistent volume claim object. + size: 1Gi + # -- Storage class name for the persistent volume claim object. + storageClassName: '' + # -- Use an existing persistent volume claim object. + existingPersistentVolumeClaim: '' + # -- Additional annotations for the persistent volume claim object. + annotations: {} + # -- Additional labels for the persistent volume claim object. + labels: {} -readinessProbe: - enabled: true - initialDelaySeconds: 5 - periodSeconds: 5 - timeoutSeconds: 2 \ No newline at end of file + serviceAccount: + # -- Specify the service account used for the controller. + name: '' + + # -- Optional priority class name to be used for pods. + priorityClassName: '' + + # -- Pod-level security attributes. More info [here](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context). + securityContext: {} + # fsGroup: 1000 + # runAsNonRoot: true + # runAsGroup: 1000 + # runAsUser: 1000 + + # -- Compute resources used by the container. More info [here](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/). + resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + + # -- Pod-level affinity. More info [here](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling). + affinity: {} + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: kubernetes.io/hostname + # operator: In + # values: + # - my-node-xyz + + # -- Pod-level tolerations. More info [here](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling). + tolerations: [] + # - key: node-role.kubernetes.io/control-plane + # operator: Exists + # effect: NoSchedule + + # -- Pod-level node selector. More info [here](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling). + nodeSelector: {} + # label: value + + # -- Specify any extra containers here as dictionary items - each should have its own key. + extraContainers: {} + # container: + # name: my-container + # image: my-org/my-image + + # -- Specify extra volume mounts for the default containers. + extraVolumeMounts: [] + # - name: my-volume + # mountPath: /path/to/volume + # readOnly: false + + # -- Specify extra volumes for the workload. + extraVolumes: [] + # - name: my-volume + # secret: + # secretName: my-secret + + +tool: + # kind: 'SubChart' or 'HelmChart', if subchart then uncomment Chart.yaml dependency, else comment and use tool library with helm chart template + kind: 'SubChart' + repo: https://charts.pascaliske.dev + chart: redis + version: 2.1.0 + values: *redis_config