{{- if (include "redis-cluster.createStatefulSet" .) }} apiVersion: {{ include "common.capabilities.statefulset.apiVersion" . }} kind: StatefulSet metadata: name: {{ include "common.names.fullname" . }} namespace: {{ .Release.Namespace }} labels: {{- include "common.labels.standard" . | nindent 4 }} {{- if .Values.commonLabels }} {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} {{- end }} {{- if .Values.commonAnnotations }} annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} {{- end }} spec: {{- if .Values.redis.updateStrategy }} updateStrategy: {{- toYaml .Values.redis.updateStrategy | nindent 4 }} {{- end }} selector: matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }} replicas: {{ .Values.cluster.nodes }} serviceName: {{ include "common.names.fullname" . }}-headless podManagementPolicy: {{ .Values.redis.podManagementPolicy }} template: metadata: labels: {{- include "common.labels.standard" . | nindent 8 }} {{- if .Values.redis.podLabels }} {{- toYaml .Values.redis.podLabels | nindent 8 }} {{- end }} {{- if and .Values.metrics.enabled .Values.metrics.podLabels }} {{- toYaml .Values.metrics.podLabels | nindent 8 }} {{- end }} annotations: checksum/scripts: {{ include (print $.Template.BasePath "/scripts-configmap.yaml") . | sha256sum }} {{- if not .Values.existingSecret }} checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} {{- end }} checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} {{- if .Values.redis.podAnnotations }} {{- toYaml .Values.redis.podAnnotations | nindent 8 }} {{- end }} {{- if and .Values.metrics.enabled .Values.metrics.podAnnotations }} {{- toYaml .Values.metrics.podAnnotations | nindent 8 }} {{- end }} spec: hostNetwork: {{ .Values.redis.hostNetwork }} {{- if semverCompare ">= 1.13" (include "common.capabilities.kubeVersion" .) }} enableServiceLinks: false {{- end }} {{- include "redis-cluster.imagePullSecrets" . | nindent 6 }} {{- if .Values.podSecurityContext.enabled }} securityContext: {{- omit .Values.podSecurityContext "enabled" | toYaml | nindent 8 }} {{- end }} serviceAccountName: {{ include "redis-cluster.serviceAccountName" . }} {{- if .Values.redis.hostAliases }} hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.redis.hostAliases "context" $) | nindent 8 }} {{- end }} {{- if .Values.redis.priorityClassName }} priorityClassName: {{ .Values.redis.priorityClassName }} {{- end }} {{- if .Values.redis.affinity }} affinity: {{- include "common.tplvalues.render" (dict "value" .Values.redis.affinity "context" $) | nindent 8 }} {{- else }} affinity: podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.redis.podAffinityPreset "context" $) | nindent 10 }} podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.redis.podAntiAffinityPreset "context" $) | nindent 10 }} nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.redis.nodeAffinityPreset.type "key" .Values.redis.nodeAffinityPreset.key "values" .Values.redis.nodeAffinityPreset.values) | nindent 10 }} {{- end }} {{- if .Values.redis.nodeSelector }} nodeSelector: {{- include "common.tplvalues.render" (dict "value" .Values.redis.nodeSelector "context" $) | nindent 8 }} {{- end }} {{- if .Values.redis.tolerations }} tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.redis.tolerations "context" $) | nindent 8 }} {{- end }} {{- if .Values.redis.shareProcessNamespace }} shareProcessNamespace: {{ .Values.redis.shareProcessNamespace }} {{- end }} {{- if .Values.redis.schedulerName }} schedulerName: {{ .Values.redis.schedulerName | quote }} {{- end }} {{- if .Values.redis.topologySpreadConstraints }} topologySpreadConstraints: {{- include "common.tplvalues.render" ( dict "value" .Values.redis.topologySpreadConstraints "context" $ ) | nindent 8 }} {{- end }} containers: - name: {{ include "common.names.fullname" . }} image: {{ include "redis-cluster.image" . }} imagePullPolicy: {{ .Values.image.pullPolicy | quote }} {{- if .Values.containerSecurityContext.enabled }} securityContext: {{- omit .Values.containerSecurityContext "enabled" | toYaml | nindent 12 }} {{- end }} {{- if .Values.diagnosticMode.enabled }} command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 12 }} {{- else if .Values.redis.command }} command: {{- include "common.tplvalues.render" (dict "value" .Values.redis.command "context" $) | nindent 12 }} {{- else }} command: ['/bin/bash', '-c'] {{- end }} {{- if .Values.diagnosticMode.enabled }} args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 12 }} {{- else if .Values.redis.args }} args: {{- include "common.tplvalues.render" (dict "value" .Values.redis.args "context" $) | nindent 12 }} {{- else if .Values.cluster.externalAccess.enabled }} args: - | # Backwards compatibility change if ! [[ -f /opt/bitnami/redis/etc/redis.conf ]]; then cp /opt/bitnami/redis/etc/redis-default.conf /opt/bitnami/redis/etc/redis.conf fi pod_index=($(echo "$POD_NAME" | tr "-" "\n")) pod_index="${pod_index[-1]}" ips=($(echo "{{ .Values.cluster.externalAccess.service.loadBalancerIP }}" | cut -d [ -f2 | cut -d ] -f 1)) export REDIS_CLUSTER_ANNOUNCE_IP="${ips[$pod_index]}" export REDIS_NODES="${ips[@]}" {{- if .Values.cluster.init }} if [[ "$pod_index" == "0" ]]; then export REDIS_CLUSTER_CREATOR="yes" export REDIS_CLUSTER_REPLICAS="{{ .Values.cluster.replicas }}" fi {{- end }} /opt/bitnami/scripts/redis-cluster/entrypoint.sh /opt/bitnami/scripts/redis-cluster/run.sh {{- else }} args: - | # Backwards compatibility change if ! [[ -f /opt/bitnami/redis/etc/redis.conf ]]; then echo COPYING FILE cp /opt/bitnami/redis/etc/redis-default.conf /opt/bitnami/redis/etc/redis.conf fi {{- if .Values.cluster.init }} pod_index=($(echo "$POD_NAME" | tr "-" "\n")) pod_index="${pod_index[-1]}" if [[ "$pod_index" == "0" ]]; then export REDIS_CLUSTER_CREATOR="yes" export REDIS_CLUSTER_REPLICAS="{{ .Values.cluster.replicas }}" fi {{- end }} /opt/bitnami/scripts/redis-cluster/entrypoint.sh /opt/bitnami/scripts/redis-cluster/run.sh {{- end }} env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name {{- if .Values.cluster.externalAccess.enabled }} - name: REDIS_CLUSTER_DYNAMIC_IPS value: "no" {{- else }} - name: REDIS_NODES value: "{{ $count := .Values.cluster.nodes | int }}{{ range $i, $v := until $count }}{{ include "common.names.fullname" $ }}-{{ $i }}.{{ template "common.names.fullname" $ }}-headless {{ end }}" {{- end }} {{- if .Values.usePassword }} - name: REDISCLI_AUTH valueFrom: secretKeyRef: name: {{ template "redis-cluster.secretName" . }} key: {{ template "redis-cluster.secretPasswordKey" . }} {{- if .Values.usePasswordFile }} - name: REDIS_PASSWORD_FILE value: "/opt/bitnami/redis/secrets/redis-password" {{- else }} - name: REDIS_PASSWORD valueFrom: secretKeyRef: name: {{ template "redis-cluster.secretName" . }} key: {{ template "redis-cluster.secretPasswordKey" . }} {{- end }} {{- else }} - name: ALLOW_EMPTY_PASSWORD value: "yes" {{- end }} - name: REDIS_AOF_ENABLED value: {{ .Values.redis.useAOFPersistence | quote }} - name: REDIS_TLS_ENABLED value: {{ ternary "yes" "no" .Values.tls.enabled | quote }} {{- if .Values.tls.enabled }} - name: REDIS_TLS_PORT value: {{ .Values.redis.containerPorts.redis | quote }} - name: REDIS_TLS_AUTH_CLIENTS value: {{ ternary "yes" "no" .Values.tls.authClients | quote }} - name: REDIS_TLS_CERT_FILE value: {{ template "redis-cluster.tlsCert" . }} - name: REDIS_TLS_KEY_FILE value: {{ template "redis-cluster.tlsCertKey" . }} - name: REDIS_TLS_CA_FILE value: {{ template "redis-cluster.tlsCACert" . }} {{- if .Values.tls.dhParamsFilename }} - name: REDIS_TLS_DH_PARAMS_FILE value: {{ template "redis-cluster.tlsDHParams" . }} {{- end }} {{- else }} - name: REDIS_PORT value: {{ .Values.redis.containerPorts.redis | quote }} {{- end }} {{- if .Values.redis.extraEnvVars }} {{- include "common.tplvalues.render" ( dict "value" .Values.redis.extraEnvVars "context" $ ) | nindent 12 }} {{- end }} {{- if or .Values.redis.extraEnvVarsCM .Values.redis.extraEnvVarsSecret }} envFrom: {{- if .Values.redis.extraEnvVarsCM }} - configMapRef: name: {{ include "common.tplvalues.render" ( dict "value" .Values.redis.extraEnvVarsCM "context" $ ) }} {{- end }} {{- if .Values.redis.extraEnvVarsSecret }} - secretRef: name: {{ include "common.tplvalues.render" ( dict "value" .Values.redis.extraEnvVarsSecret "context" $ ) }} {{- end }} {{- end }} ports: - name: tcp-redis containerPort: {{ .Values.redis.containerPorts.redis }} - name: tcp-redis-bus containerPort: {{ .Values.redis.containerPorts.bus }} {{- if not .Values.diagnosticMode.enabled }} {{- if .Values.redis.livenessProbe.enabled }} livenessProbe: initialDelaySeconds: {{ .Values.redis.livenessProbe.initialDelaySeconds }} periodSeconds: {{ .Values.redis.livenessProbe.periodSeconds }} # One second longer than command timeout should prevent generation of zombie processes. timeoutSeconds: {{ add1 .Values.redis.livenessProbe.timeoutSeconds }} successThreshold: {{ .Values.redis.livenessProbe.successThreshold }} failureThreshold: {{ .Values.redis.livenessProbe.failureThreshold }} exec: command: - sh - -c - /scripts/ping_liveness_local.sh {{ .Values.redis.livenessProbe.timeoutSeconds }} {{- else if .Values.redis.customLivenessProbe }} livenessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.redis.customLivenessProbe "context" $) | nindent 12 }} {{- end }} {{- if .Values.redis.readinessProbe.enabled }} readinessProbe: initialDelaySeconds: {{ .Values.redis.readinessProbe.initialDelaySeconds }} periodSeconds: {{ .Values.redis.readinessProbe.periodSeconds }} # One second longer than command timeout should prevent generation of zombie processes. timeoutSeconds: {{ add1 .Values.redis.readinessProbe.timeoutSeconds }} successThreshold: {{ .Values.redis.readinessProbe.successThreshold }} failureThreshold: {{ .Values.redis.readinessProbe.failureThreshold }} exec: command: - sh - -c - /scripts/ping_readiness_local.sh {{ .Values.redis.readinessProbe.timeoutSeconds }} {{- else if .Values.redis.customReadinessProbe }} readinessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.redis.customReadinessProbe "context" $) | nindent 12 }} {{- end }} {{- if .Values.redis.startupProbe.enabled }} startupProbe: tcpSocket: port: tcp-redis initialDelaySeconds: {{ .Values.redis.startupProbe.initialDelaySeconds }} periodSeconds: {{ .Values.redis.startupProbe.periodSeconds }} timeoutSeconds: {{ .Values.redis.startupProbe.timeoutSeconds }} successThreshold: {{ .Values.redis.startupProbe.successThreshold }} failureThreshold: {{ .Values.redis.startupProbe.failureThreshold }} {{- else if .Values.redis.customStartupProbe }} startupProbe: {{- include "common.tplvalues.render" (dict "value" .Values.redis.customStartupProbe "context" $) | nindent 12 }} {{- end }} {{- if .Values.redis.lifecycleHooks }} lifecycle: {{- include "common.tplvalues.render" (dict "value" .Values.redis.lifecycleHooks "context" $) | nindent 12 }} {{- end }} {{- end }} {{- if .Values.redis.resources }} resources: {{- include "common.tplvalues.render" (dict "value" .Values.redis.resources "context" $) | nindent 12 }} {{- end }} volumeMounts: - name: scripts mountPath: /scripts {{- if .Values.usePasswordFile }} - name: redis-password mountPath: /opt/bitnami/redis/secrets/ {{- end }} - name: redis-data mountPath: {{ .Values.persistence.path }} subPath: {{ .Values.persistence.subPath }} - name: default-config mountPath: /opt/bitnami/redis/etc/redis-default.conf subPath: redis-default.conf - name: redis-tmp-conf mountPath: /opt/bitnami/redis/etc/ {{- if .Values.tls.enabled }} - name: redis-certificates mountPath: /opt/bitnami/redis/certs readOnly: true {{- end }} {{- if .Values.redis.extraVolumeMounts }} {{- include "common.tplvalues.render" ( dict "value" .Values.redis.extraVolumeMounts "context" $ ) | nindent 12 }} {{- end }} {{- if .Values.metrics.enabled }} - name: metrics image: {{ template "redis-cluster.metrics.image" . }} imagePullPolicy: {{ .Values.metrics.image.pullPolicy | quote }} {{- if .Values.diagnosticMode.enabled }} command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 12 }} args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 12 }} {{- else }} command: - /bin/bash - -c - | {{- if .Values.usePasswordFile }} export REDIS_PASSWORD="$(< "${REDIS_PASSWORD_FILE}")" {{- end }} redis_exporter{{- range $key, $value := .Values.metrics.extraArgs }} --{{ $key }}={{ $value }}{{- end }} {{- end }} env: - name: BITNAMI_DEBUG value: {{ ternary "true" "false" (or .Values.image.debug .Values.diagnosticMode.enabled) | quote }} - name: REDIS_ALIAS value: {{ template "common.names.fullname" . }} - name: REDIS_ADDR value: {{ printf "%s://127.0.0.1:%g" (ternary "rediss" "redis" .Values.tls.enabled) .Values.redis.containerPorts.redis | quote }} {{- if and .Values.usePassword (not .Values.usePasswordFile) }} - name: REDIS_PASSWORD valueFrom: secretKeyRef: name: {{ template "redis-cluster.secretName" . }} key: {{ template "redis-cluster.secretPasswordKey" . }} {{- end }} {{- if .Values.usePasswordFile }} - name: REDIS_PASSWORD_FILE value: "/opt/bitnami/redis/secrets/redis-password" {{- end }} {{- if .Values.tls.enabled }} - name: REDIS_EXPORTER_TLS_CLIENT_KEY_FILE value: {{ template "redis-cluster.tlsCertKey" . }} - name: REDIS_EXPORTER_TLS_CLIENT_CERT_FILE value: {{ template "redis-cluster.tlsCert" . }} - name: REDIS_EXPORTER_TLS_CA_CERT_FILE value: {{ template "redis-cluster.tlsCACert" . }} {{- end }} {{- if or .Values.usePasswordFile .Values.tls.enabled }} volumeMounts: {{- if .Values.usePasswordFile }} - name: redis-password mountPath: /opt/bitnami/redis/secrets/ {{- end }} {{- if .Values.tls.enabled }} - name: redis-certificates mountPath: /opt/bitnami/redis/certs readOnly: true {{- end }} {{- end }} ports: - name: http-metrics containerPort: 9121 resources: {{- toYaml .Values.metrics.resources | nindent 12 }} {{- end }} {{- if .Values.redis.sidecars }} {{- include "common.tplvalues.render" ( dict "value" .Values.redis.sidecars "context" $ ) | nindent 8 }} {{- end }} {{- $needsVolumePermissions := and .Values.volumePermissions.enabled .Values.containerSecurityContext.enabled }} {{- if or $needsVolumePermissions .Values.sysctlImage.enabled .Values.redis.initContainers }} initContainers: {{- if $needsVolumePermissions }} - name: volume-permissions image: {{ include "redis-cluster.volumePermissions.image" . }} imagePullPolicy: {{ .Values.volumePermissions.image.pullPolicy | quote }} command: ["/bin/chown", "-R", "{{ .Values.containerSecurityContext.runAsUser }}:{{ .Values.podSecurityContext.fsGroup }}", "{{ .Values.persistence.path }}"] securityContext: runAsUser: 0 resources: {{- toYaml .Values.volumePermissions.resources | nindent 12 }} volumeMounts: - name: redis-data mountPath: {{ .Values.persistence.path }} subPath: {{ .Values.persistence.subPath }} {{- end }} {{- if .Values.sysctlImage.enabled }} - name: init-sysctl image: {{ template "redis-cluster.sysctl.image" . }} imagePullPolicy: {{ default "" .Values.sysctlImage.pullPolicy | quote }} resources: {{- toYaml .Values.sysctlImage.resources | nindent 12 }} {{- if .Values.sysctlImage.mountHostSys }} volumeMounts: - name: host-sys mountPath: /host-sys {{- end }} command: {{- toYaml .Values.sysctlImage.command | nindent 12 }} securityContext: privileged: true runAsUser: 0 {{- end }} {{- if .Values.redis.initContainers }} {{- toYaml .Values.redis.initContainers | nindent 8 }} {{- end }} {{- end }} volumes: - name: scripts configMap: name: {{ include "common.names.fullname" . }}-scripts defaultMode: 0755 {{- if .Values.usePasswordFile }} - name: redis-password secret: secretName: {{ include "redis-cluster.secretName" . }} items: - key: {{ include "redis-cluster.secretPasswordKey" . }} path: redis-password {{- end }} - name: default-config configMap: name: {{ include "common.names.fullname" . }}-default {{- if .Values.sysctlImage.mountHostSys }} - name: host-sys hostPath: path: /sys {{- end }} - name: redis-tmp-conf emptyDir: {} {{- if .Values.redis.extraVolumes }} {{- include "common.tplvalues.render" ( dict "value" .Values.redis.extraVolumes "context" $ ) | nindent 8 }} {{- end }} {{- if .Values.tls.enabled }} - name: redis-certificates secret: secretName: {{ include "redis-cluster.tlsSecretName" . }} defaultMode: 256 {{- end }} volumeClaimTemplates: - metadata: name: redis-data labels: {{- include "common.labels.matchLabels" . | nindent 10 }} {{- if .Values.persistence.annotations }} annotations: {{- include "common.tplvalues.render" (dict "value" .Values.persistence.annotations "context" $) | nindent 10 }} {{- end }} spec: accessModes: {{- range .Values.persistence.accessModes }} - {{ . | quote }} {{- end }} resources: requests: storage: {{ .Values.persistence.size | quote }} {{- include "common.storage.class" (dict "persistence" .Values.persistence "global" .Values.global) | nindent 8 }} {{- if or .Values.persistence.matchLabels .Values.persistence.matchExpressions }} selector: {{- if .Values.persistence.matchLabels }} matchLabels: {{- toYaml .Values.persistence.matchLabels | nindent 12 }} {{- end -}} {{- if .Values.persistence.matchExpressions }} matchExpressions: {{- toYaml .Values.persistence.matchExpressions | nindent 12 }} {{- end -}} {{- end }} {{- end }}