apiVersion: apps/v1 kind: StatefulSet metadata: name: {{ template "redis-ha.fullname" . }}-server namespace: {{ .Release.Namespace }} labels: {{ template "redis-ha.fullname" . }}: replica {{ include "labels.standard" . | indent 4 }} spec: selector: matchLabels: release: {{ .Release.Name }} app: {{ template "redis-ha.name" . }} serviceName: {{ template "redis-ha.fullname" . }} replicas: {{ .Values.replicas }} podManagementPolicy: OrderedReady updateStrategy: type: RollingUpdate template: metadata: annotations: checksum/init-config: {{ print (include "config-redis.conf" .) (include "config-init.sh" .) | sha256sum }} {{- if .Values.podAnnotations }} {{ toYaml .Values.podAnnotations | indent 8 }} {{- end }} {{- if .Values.exporter.enabled }} prometheus.io/port: "{{ .Values.exporter.port }}" prometheus.io/scrape: "true" prometheus.io/path: {{ .Values.exporter.scrapePath }} {{- end }} labels: release: {{ .Release.Name }} app: {{ template "redis-ha.name" . }} {{ template "redis-ha.fullname" . }}: replica {{- range $key, $value := .Values.labels }} {{ $key }}: {{ $value }} {{- end }} spec: {{- if .Values.schedulerName }} schedulerName: "{{ .Values.schedulerName }}" {{- end }} {{- if .Values.nodeSelector }} nodeSelector: {{ toYaml .Values.nodeSelector | indent 8 }} {{- end }} {{- if .Values.tolerations }} tolerations: {{ toYaml .Values.tolerations | indent 8 }} {{- end }} affinity: {{- if .Values.affinity }} {{- with .Values.affinity }} {{ tpl . $ | indent 8 }} {{- end }} {{- else }} {{- if .Values.additionalAffinities }} {{ toYaml .Values.additionalAffinities | indent 8 }} {{- end }} podAntiAffinity: {{- if .Values.hardAntiAffinity }} requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchLabels: app: {{ template "redis-ha.name" . }} release: {{ .Release.Name }} {{ template "redis-ha.fullname" . }}: replica topologyKey: kubernetes.io/hostname {{- else }} preferredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchLabels: app: {{ template "redis-ha.name" . }} release: {{ .Release.Name }} {{ template "redis-ha.fullname" . }}: replica topologyKey: kubernetes.io/hostname {{- end }} preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchLabels: app: {{ template "redis-ha.name" . }} release: {{ .Release.Name }} {{ template "redis-ha.fullname" . }}: replica topologyKey: failure-domain.beta.kubernetes.io/zone {{- end }} {{- if .Values.imagePullSecrets }} imagePullSecrets: {{ toYaml .Values.imagePullSecrets | nindent 8 }} {{- end }} securityContext: {{ toYaml .Values.securityContext | indent 8 }} serviceAccountName: {{ template "redis-ha.serviceAccountName" . }} initContainers: {{- if .Values.sysctlImage.enabled }} - name: init-sysctl image: {{ template "redis.sysctl.image" . }} imagePullPolicy: {{ .Values.sysctlImage.pullPolicy }} resources: {{ toYaml .Values.sysctlImage.resources | indent 10 }} {{- if .Values.sysctlImage.mountHostSys }} volumeMounts: - name: host-sys mountPath: /host-sys {{- end }} command: {{ toYaml .Values.sysctlImage.command | indent 10 }} securityContext: runAsNonRoot: false privileged: true runAsUser: 0 {{- end }} {{- if and .Values.hostPath.path .Values.hostPath.chown }} - name: hostpath-chown image: {{ .Values.image.repository }}:{{ .Values.image.tag }} securityContext: runAsNonRoot: false runAsUser: 0 command: - chown - "{{ .Values.securityContext.runAsUser }}" - /data volumeMounts: - name: data mountPath: /data {{- end }} - name: config-init image: {{ .Values.image.repository }}:{{ .Values.image.tag }} imagePullPolicy: {{ .Values.image.pullPolicy }} resources: {{ toYaml .Values.init.resources | indent 10 }} command: - sh args: - /readonly-config/init.sh env: {{- $replicas := int (toString .Values.replicas) -}} {{- range $i := until $replicas }} - name: SENTINEL_ID_{{ $i }} value: {{ printf "%s\n%s\nindex: %d" (include "redis-ha.name" $) ($.Release.Name) $i | sha1sum }} {{ end -}} {{- if .Values.auth }} - name: AUTH valueFrom: secretKeyRef: {{- if .Values.existingSecret }} name: {{ .Values.existingSecret }} {{- else }} name: {{ template "redis-ha.fullname" . }} {{- end }} key: {{ .Values.authKey }} {{- end }} volumeMounts: - name: config mountPath: /readonly-config readOnly: true - name: data mountPath: /data containers: - name: redis image: {{ .Values.image.repository }}:{{ .Values.image.tag }} imagePullPolicy: {{ .Values.image.pullPolicy }} command: - redis-server args: - /data/conf/redis.conf {{- if .Values.auth }} env: - name: AUTH valueFrom: secretKeyRef: {{- if .Values.existingSecret }} name: {{ .Values.existingSecret }} {{- else }} name: {{ template "redis-ha.fullname" . }} {{- end }} key: {{ .Values.authKey }} {{- end }} livenessProbe: tcpSocket: port: {{ .Values.redis.port }} initialDelaySeconds: 15 resources: {{ toYaml .Values.redis.resources | indent 10 }} ports: - name: redis containerPort: {{ .Values.redis.port }} volumeMounts: - mountPath: /data name: data - name: sentinel image: {{ .Values.image.repository }}:{{ .Values.image.tag }} imagePullPolicy: {{ .Values.image.pullPolicy }} command: - redis-sentinel args: - /data/conf/sentinel.conf {{- if .Values.auth }} env: - name: AUTH valueFrom: secretKeyRef: {{- if .Values.existingSecret }} name: {{ .Values.existingSecret }} {{- else }} name: {{ template "redis-ha.fullname" . }} {{- end }} key: {{ .Values.authKey }} {{- end }} livenessProbe: tcpSocket: port: {{ .Values.sentinel.port }} initialDelaySeconds: 15 resources: {{ toYaml .Values.sentinel.resources | indent 10 }} ports: - name: sentinel containerPort: {{ .Values.sentinel.port }} volumeMounts: - mountPath: /data name: data {{- if .Values.exporter.enabled }} - name: redis-exporter image: "{{ .Values.exporter.image }}:{{ .Values.exporter.tag }}" imagePullPolicy: {{ .Values.exporter.pullPolicy }} args: {{- range $key, $value := .Values.exporter.extraArgs }} - --{{ $key }}={{ $value }} {{- end }} env: - name: REDIS_ADDR value: redis://localhost:{{ .Values.redis.port }} {{- if .Values.auth }} - name: REDIS_PASSWORD valueFrom: secretKeyRef: {{- if .Values.existingSecret }} name: {{ .Values.existingSecret }} {{- else }} name: {{ template "redis-ha.fullname" . }} {{- end }} key: {{ .Values.authKey }} {{- end }} {{- if .Values.exporter.script }} - name: REDIS_EXPORTER_SCRIPT value: /script/script.lua {{- end }} livenessProbe: httpGet: path: {{ .Values.exporter.scrapePath }} port: {{ .Values.exporter.port }} initialDelaySeconds: 15 timeoutSeconds: 1 periodSeconds: 15 resources: {{ toYaml .Values.exporter.resources | indent 10 }} ports: - name: exporter-port containerPort: {{ .Values.exporter.port }} {{- if .Values.exporter.script }} volumeMounts: - mountPath: /script name: script-mount {{- end }} {{- end }} {{- if .Values.priorityClassName }} priorityClassName: {{ .Values.priorityClassName }} {{- end }} volumes: - name: config configMap: name: {{ template "redis-ha.fullname" . }}-configmap {{- if .Values.sysctlImage.mountHostSys }} - name: host-sys hostPath: path: /sys {{- end }} {{- if .Values.exporter.script }} - name: script-mount configMap: name: {{ template "redis-ha.fullname" . }}-exporter-script-configmap items: - key: script path: script.lua {{- end }} {{- if .Values.persistentVolume.enabled }} volumeClaimTemplates: - metadata: name: data annotations: {{- range $key, $value := .Values.persistentVolume.annotations }} {{ $key }}: {{ $value }} {{- end }} spec: accessModes: {{- range .Values.persistentVolume.accessModes }} - {{ . | quote }} {{- end }} resources: requests: storage: {{ .Values.persistentVolume.size | quote }} {{- if .Values.persistentVolume.storageClass }} {{- if (eq "-" .Values.persistentVolume.storageClass) }} storageClassName: "" {{- else }} storageClassName: "{{ .Values.persistentVolume.storageClass }}" {{- end }} {{- end }} {{- if .Values.persistentVolume.reclaimPolicy }} persistentVolumeReclaimPolicy: "{{ .Values.persistentVolume.reclaimPolicy }}" {{- end }} {{- else if .Values.hostPath.path }} - name: data hostPath: path: {{ tpl .Values.hostPath.path .}} {{- else }} - name: data emptyDir: {{ toYaml .Values.emptyDir | indent 10 }} {{- end }}