scripts-configmap.yaml 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713
  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4. name: {{ printf "%s-scripts" (include "common.names.fullname" .) }}
  5. namespace: {{ .Release.Namespace | quote }}
  6. labels: {{- include "common.labels.standard" . | nindent 4 }}
  7. {{- if .Values.commonLabels }}
  8. {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }}
  9. {{- end }}
  10. {{- if .Values.commonAnnotations }}
  11. annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
  12. {{- end }}
  13. data:
  14. {{- if and (eq .Values.architecture "replication") .Values.sentinel.enabled }}
  15. start-node.sh: |
  16. #!/bin/bash
  17. . /opt/bitnami/scripts/libos.sh
  18. . /opt/bitnami/scripts/liblog.sh
  19. . /opt/bitnami/scripts/libvalidations.sh
  20. get_port() {
  21. hostname="$1"
  22. type="$2"
  23. port_var=$(echo "${hostname^^}_SERVICE_PORT_$type" | sed "s/-/_/g")
  24. port=${!port_var}
  25. if [ -z "$port" ]; then
  26. case $type in
  27. "SENTINEL")
  28. echo {{ .Values.sentinel.containerPorts.sentinel }}
  29. ;;
  30. "REDIS")
  31. echo {{ .Values.master.containerPorts.redis }}
  32. ;;
  33. esac
  34. else
  35. echo $port
  36. fi
  37. }
  38. get_full_hostname() {
  39. hostname="$1"
  40. {{- if .Values.useExternalDNS.enabled }}
  41. full_hostname="${hostname}.{{- include "redis.externalDNS.suffix" . }}"
  42. {{- else if eq .Values.sentinel.service.type "NodePort" }}
  43. full_hostname="${hostname}.{{- .Release.Namespace }}"
  44. {{- else }}
  45. full_hostname="${hostname}.${HEADLESS_SERVICE}"
  46. {{- end }}
  47. {{- if .Values.useHostnames }}
  48. echo "${full_hostname}"
  49. {{- else }}
  50. getent hosts "${full_hostname}" | awk '{ print $1 ; exit }'
  51. {{- end }}
  52. }
  53. REDISPORT=$(get_port "$HOSTNAME" "REDIS")
  54. HEADLESS_SERVICE="{{ template "common.names.fullname" . }}-headless.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }}"
  55. if [ -n "$REDIS_EXTERNAL_MASTER_HOST" ]; then
  56. REDIS_SERVICE="$REDIS_EXTERNAL_MASTER_HOST"
  57. else
  58. REDIS_SERVICE="{{ template "common.names.fullname" . }}.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }}"
  59. fi
  60. SENTINEL_SERVICE_PORT=$(get_port "{{ include "common.names.fullname" . }}" "TCP_SENTINEL")
  61. validate_quorum() {
  62. if is_boolean_yes "$REDIS_TLS_ENABLED"; then
  63. quorum_info_command="{{- if and .Values.auth.enabled .Values.auth.sentinel }}REDISCLI_AUTH="\$REDIS_PASSWORD" {{ end }}redis-cli -h $REDIS_SERVICE -p $SENTINEL_SERVICE_PORT --tls --cert ${REDIS_TLS_CERT_FILE} --key ${REDIS_TLS_KEY_FILE} --cacert ${REDIS_TLS_CA_FILE} sentinel master {{ .Values.sentinel.masterSet }}"
  64. else
  65. quorum_info_command="{{- if and .Values.auth.enabled .Values.auth.sentinel }}REDISCLI_AUTH="\$REDIS_PASSWORD" {{ end }}redis-cli -h $REDIS_SERVICE -p $SENTINEL_SERVICE_PORT sentinel master {{ .Values.sentinel.masterSet }}"
  66. fi
  67. info "about to run the command: $quorum_info_command"
  68. eval $quorum_info_command | grep -Fq "s_down"
  69. }
  70. trigger_manual_failover() {
  71. if is_boolean_yes "$REDIS_TLS_ENABLED"; then
  72. failover_command="{{- if and .Values.auth.enabled .Values.auth.sentinel }}REDISCLI_AUTH="\$REDIS_PASSWORD" {{ end }}redis-cli -h $REDIS_SERVICE -p $SENTINEL_SERVICE_PORT --tls --cert ${REDIS_TLS_CERT_FILE} --key ${REDIS_TLS_KEY_FILE} --cacert ${REDIS_TLS_CA_FILE} sentinel failover {{ .Values.sentinel.masterSet }}"
  73. else
  74. failover_command="{{- if and .Values.auth.enabled .Values.auth.sentinel }}REDISCLI_AUTH="\$REDIS_PASSWORD" {{ end }}redis-cli -h $REDIS_SERVICE -p $SENTINEL_SERVICE_PORT sentinel failover {{ .Values.sentinel.masterSet }}"
  75. fi
  76. info "about to run the command: $failover_command"
  77. eval $failover_command
  78. }
  79. get_sentinel_master_info() {
  80. if is_boolean_yes "$REDIS_TLS_ENABLED"; then
  81. sentinel_info_command="{{- if and .Values.auth.enabled .Values.auth.sentinel }}REDISCLI_AUTH="\$REDIS_PASSWORD" {{ end }}timeout {{ .Values.sentinel.getMasterTimeout }} redis-cli -h $REDIS_SERVICE -p $SENTINEL_SERVICE_PORT --tls --cert ${REDIS_TLS_CERT_FILE} --key ${REDIS_TLS_KEY_FILE} --cacert ${REDIS_TLS_CA_FILE} sentinel get-master-addr-by-name {{ .Values.sentinel.masterSet }}"
  82. else
  83. sentinel_info_command="{{- if and .Values.auth.enabled .Values.auth.sentinel }}REDISCLI_AUTH="\$REDIS_PASSWORD" {{ end }}timeout {{ .Values.sentinel.getMasterTimeout }} redis-cli -h $REDIS_SERVICE -p $SENTINEL_SERVICE_PORT sentinel get-master-addr-by-name {{ .Values.sentinel.masterSet }}"
  84. fi
  85. info "about to run the command: $sentinel_info_command"
  86. eval $sentinel_info_command
  87. }
  88. {{- if and .Values.replica.containerSecurityContext.runAsUser (eq (.Values.replica.containerSecurityContext.runAsUser | int) 0) }}
  89. useradd redis
  90. chown -R redis {{ .Values.replica.persistence.path }}
  91. {{- end }}
  92. [[ -f $REDIS_PASSWORD_FILE ]] && export REDIS_PASSWORD="$(< "${REDIS_PASSWORD_FILE}")"
  93. [[ -f $REDIS_MASTER_PASSWORD_FILE ]] && export REDIS_MASTER_PASSWORD="$(< "${REDIS_MASTER_PASSWORD_FILE}")"
  94. # check if there is a master
  95. master_in_persisted_conf="$(get_full_hostname "$HOSTNAME")"
  96. master_port_in_persisted_conf="$REDIS_MASTER_PORT_NUMBER"
  97. master_in_sentinel="$(get_sentinel_master_info)"
  98. redisRetVal=$?
  99. {{- if .Values.sentinel.persistence.enabled }}
  100. if [[ -f /opt/bitnami/redis-sentinel/etc/sentinel.conf ]]; then
  101. master_in_persisted_conf="$(awk '/monitor/ {print $4}' /opt/bitnami/redis-sentinel/etc/sentinel.conf)"
  102. master_port_in_persisted_conf="$(awk '/monitor/ {print $5}' /opt/bitnami/redis-sentinel/etc/sentinel.conf)"
  103. info "Found previous master ${master_in_persisted_conf}:${master_port_in_persisted_conf} in /opt/bitnami/redis-sentinel/etc/sentinel.conf"
  104. debug "$(cat /opt/bitnami/redis-sentinel/etc/sentinel.conf | grep monitor)"
  105. touch /opt/bitnami/redis-sentinel/etc/.node_read
  106. fi
  107. {{- end }}
  108. if [[ $redisRetVal -ne 0 ]]; then
  109. if [[ "$master_in_persisted_conf" == "$(get_full_hostname "$HOSTNAME")" ]]; then
  110. # Case 1: No active sentinel and in previous sentinel.conf we were the master --> MASTER
  111. info "Configuring the node as master"
  112. export REDIS_REPLICATION_MODE="master"
  113. else
  114. # Case 2: No active sentinel and in previous sentinel.conf we were not master --> REPLICA
  115. info "Configuring the node as replica"
  116. export REDIS_REPLICATION_MODE="replica"
  117. REDIS_MASTER_HOST=${master_in_persisted_conf}
  118. REDIS_MASTER_PORT_NUMBER=${master_port_in_persisted_conf}
  119. fi
  120. else
  121. # Fetches current master's host and port
  122. REDIS_SENTINEL_INFO=($(get_sentinel_master_info))
  123. info "Current master: REDIS_SENTINEL_INFO=(${REDIS_SENTINEL_INFO[0]},${REDIS_SENTINEL_INFO[1]})"
  124. REDIS_MASTER_HOST=${REDIS_SENTINEL_INFO[0]}
  125. REDIS_MASTER_PORT_NUMBER=${REDIS_SENTINEL_INFO[1]}
  126. if [[ "$REDIS_MASTER_HOST" == "$(get_full_hostname "$HOSTNAME")" ]]; then
  127. # Case 3: Active sentinel and master it is this node --> MASTER
  128. info "Configuring the node as master"
  129. export REDIS_REPLICATION_MODE="master"
  130. else
  131. # Case 4: Active sentinel and master is not this node --> REPLICA
  132. info "Configuring the node as replica"
  133. export REDIS_REPLICATION_MODE="replica"
  134. {{- if and .Values.sentinel.automateClusterRecovery (le (int .Values.sentinel.downAfterMilliseconds) 2000) }}
  135. retry_count=1
  136. while validate_quorum
  137. do
  138. info "sleeping, waiting for Redis master to come up"
  139. sleep 1s
  140. if ! ((retry_count % 11)); then
  141. info "Trying to manually failover"
  142. failover_result=$(trigger_manual_failover)
  143. debug "Failover result: $failover_result"
  144. fi
  145. ((retry_count+=1))
  146. done
  147. info "Redis master is up now"
  148. {{- end }}
  149. fi
  150. fi
  151. if [[ -n "$REDIS_EXTERNAL_MASTER_HOST" ]]; then
  152. REDIS_MASTER_HOST="$REDIS_EXTERNAL_MASTER_HOST"
  153. REDIS_MASTER_PORT_NUMBER="${REDIS_EXTERNAL_MASTER_PORT}"
  154. fi
  155. if [[ -f /opt/bitnami/redis/mounted-etc/replica.conf ]];then
  156. cp /opt/bitnami/redis/mounted-etc/replica.conf /opt/bitnami/redis/etc/replica.conf
  157. fi
  158. if [[ -f /opt/bitnami/redis/mounted-etc/redis.conf ]];then
  159. cp /opt/bitnami/redis/mounted-etc/redis.conf /opt/bitnami/redis/etc/redis.conf
  160. fi
  161. echo "" >> /opt/bitnami/redis/etc/replica.conf
  162. echo "replica-announce-port $REDISPORT" >> /opt/bitnami/redis/etc/replica.conf
  163. echo "replica-announce-ip $(get_full_hostname "$HOSTNAME")" >> /opt/bitnami/redis/etc/replica.conf
  164. {{- if .Values.tls.enabled }}
  165. ARGS=("--port" "0")
  166. ARGS+=("--tls-port" "${REDIS_TLS_PORT}")
  167. ARGS+=("--tls-cert-file" "${REDIS_TLS_CERT_FILE}")
  168. ARGS+=("--tls-key-file" "${REDIS_TLS_KEY_FILE}")
  169. ARGS+=("--tls-ca-cert-file" "${REDIS_TLS_CA_FILE}")
  170. ARGS+=("--tls-auth-clients" "${REDIS_TLS_AUTH_CLIENTS}")
  171. ARGS+=("--tls-replication" "yes")
  172. {{- if .Values.tls.dhParamsFilename }}
  173. ARGS+=("--tls-dh-params-file" "${REDIS_TLS_DH_PARAMS_FILE}")
  174. {{- end }}
  175. {{- else }}
  176. ARGS=("--port" "${REDIS_PORT}")
  177. {{- end }}
  178. if [[ "$REDIS_REPLICATION_MODE" = "slave" ]] || [[ "$REDIS_REPLICATION_MODE" = "replica" ]]; then
  179. ARGS+=("--replicaof" "${REDIS_MASTER_HOST}" "${REDIS_MASTER_PORT_NUMBER}")
  180. fi
  181. {{- if .Values.auth.enabled }}
  182. ARGS+=("--requirepass" "${REDIS_PASSWORD}")
  183. ARGS+=("--masterauth" "${REDIS_MASTER_PASSWORD}")
  184. {{- else }}
  185. ARGS+=("--protected-mode" "no")
  186. {{- end }}
  187. ARGS+=("--include" "/opt/bitnami/redis/etc/replica.conf")
  188. ARGS+=("--include" "/opt/bitnami/redis/etc/redis.conf")
  189. {{- if .Values.replica.extraFlags }}
  190. {{- range .Values.replica.extraFlags }}
  191. ARGS+=({{ . | quote }})
  192. {{- end }}
  193. {{- end }}
  194. {{- if .Values.replica.preExecCmds }}
  195. {{- .Values.replica.preExecCmds | nindent 4 }}
  196. {{- end }}
  197. {{- if .Values.replica.command }}
  198. exec {{ .Values.replica.command }} "${ARGS[@]}"
  199. {{- else }}
  200. exec redis-server "${ARGS[@]}"
  201. {{- end }}
  202. start-sentinel.sh: |
  203. #!/bin/bash
  204. . /opt/bitnami/scripts/libos.sh
  205. . /opt/bitnami/scripts/libvalidations.sh
  206. . /opt/bitnami/scripts/libfile.sh
  207. HEADLESS_SERVICE="{{ template "common.names.fullname" . }}-headless.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }}"
  208. REDIS_SERVICE="{{ template "common.names.fullname" . }}.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }}"
  209. get_port() {
  210. hostname="$1"
  211. type="$2"
  212. port_var=$(echo "${hostname^^}_SERVICE_PORT_$type" | sed "s/-/_/g")
  213. port=${!port_var}
  214. if [ -z "$port" ]; then
  215. case $type in
  216. "SENTINEL")
  217. echo {{ .Values.sentinel.containerPorts.sentinel }}
  218. ;;
  219. "REDIS")
  220. echo {{ .Values.master.containerPorts.redis }}
  221. ;;
  222. esac
  223. else
  224. echo $port
  225. fi
  226. }
  227. get_full_hostname() {
  228. hostname="$1"
  229. {{- if .Values.useExternalDNS.enabled }}
  230. full_hostname="${hostname}.{{- include "redis.externalDNS.suffix" . }}"
  231. {{- else if eq .Values.sentinel.service.type "NodePort" }}
  232. full_hostname="${hostname}.{{- .Release.Namespace }}"
  233. {{- else }}
  234. full_hostname="${hostname}.${HEADLESS_SERVICE}"
  235. {{- end }}
  236. {{- if .Values.useHostnames }}
  237. echo "${full_hostname}"
  238. {{- else }}
  239. getent hosts "${full_hostname}" | awk '{ print $1 ; exit }'
  240. {{- end }}
  241. }
  242. SERVPORT=$(get_port "$HOSTNAME" "SENTINEL")
  243. REDISPORT=$(get_port "$HOSTNAME" "REDIS")
  244. SENTINEL_SERVICE_PORT=$(get_port "{{ include "common.names.fullname" . }}" "TCP_SENTINEL")
  245. sentinel_conf_set() {
  246. local -r key="${1:?missing key}"
  247. local value="${2:-}"
  248. # Sanitize inputs
  249. value="${value//\\/\\\\}"
  250. value="${value//&/\\&}"
  251. value="${value//\?/\\?}"
  252. [[ "$value" = "" ]] && value="\"$value\""
  253. replace_in_file "/opt/bitnami/redis-sentinel/etc/sentinel.conf" "^#*\s*${key} .*" "${key} ${value}" false
  254. }
  255. sentinel_conf_add() {
  256. echo $'\n'"$@" >> "/opt/bitnami/redis-sentinel/etc/sentinel.conf"
  257. }
  258. host_id() {
  259. echo "$1" | openssl sha1 | awk '{print $2}'
  260. }
  261. get_sentinel_master_info() {
  262. if is_boolean_yes "$REDIS_SENTINEL_TLS_ENABLED"; then
  263. sentinel_info_command="{{- if and .Values.auth.enabled .Values.auth.sentinel }}REDISCLI_AUTH="\$REDIS_PASSWORD" {{ end }}timeout {{ .Values.sentinel.getMasterTimeout }} redis-cli -h $REDIS_SERVICE -p $SENTINEL_SERVICE_PORT --tls --cert ${REDIS_SENTINEL_TLS_CERT_FILE} --key ${REDIS_SENTINEL_TLS_KEY_FILE} --cacert ${REDIS_SENTINEL_TLS_CA_FILE} sentinel get-master-addr-by-name {{ .Values.sentinel.masterSet }}"
  264. else
  265. sentinel_info_command="{{- if and .Values.auth.enabled .Values.auth.sentinel }}REDISCLI_AUTH="\$REDIS_PASSWORD" {{ end }}timeout {{ .Values.sentinel.getMasterTimeout }} redis-cli -h $REDIS_SERVICE -p $SENTINEL_SERVICE_PORT sentinel get-master-addr-by-name {{ .Values.sentinel.masterSet }}"
  266. fi
  267. info "about to run the command: $sentinel_info_command"
  268. eval $sentinel_info_command
  269. }
  270. [[ -f $REDIS_PASSWORD_FILE ]] && export REDIS_PASSWORD="$(< "${REDIS_PASSWORD_FILE}")"
  271. master_in_persisted_conf="$(get_full_hostname "$HOSTNAME")"
  272. {{- if .Values.sentinel.persistence.enabled }}
  273. if [[ -f /opt/bitnami/redis-sentinel/etc/sentinel.conf ]]; then
  274. check_lock_file() {
  275. [[ -f /opt/bitnami/redis-sentinel/etc/.node_read ]]
  276. }
  277. retry_while "check_lock_file"
  278. rm -f /opt/bitnami/redis-sentinel/etc/.node_read
  279. master_in_persisted_conf="$(awk '/monitor/ {print $4}' /opt/bitnami/redis-sentinel/etc/sentinel.conf)"
  280. info "Found previous master $master_in_persisted_conf in /opt/bitnami/redis-sentinel/etc/sentinel.conf"
  281. debug "$(cat /opt/bitnami/redis-sentinel/etc/sentinel.conf | grep monitor)"
  282. fi
  283. {{- end }}
  284. if ! get_sentinel_master_info && [[ "$master_in_persisted_conf" == "$(get_full_hostname "$HOSTNAME")" ]]; then
  285. # No master found, lets create a master node
  286. export REDIS_REPLICATION_MODE="master"
  287. REDIS_MASTER_HOST=$(get_full_hostname "$HOSTNAME")
  288. REDIS_MASTER_PORT_NUMBER="$REDISPORT"
  289. else
  290. export REDIS_REPLICATION_MODE="replica"
  291. # Fetches current master's host and port
  292. REDIS_SENTINEL_INFO=($(get_sentinel_master_info))
  293. info "printing REDIS_SENTINEL_INFO=(${REDIS_SENTINEL_INFO[0]},${REDIS_SENTINEL_INFO[1]})"
  294. REDIS_MASTER_HOST=${REDIS_SENTINEL_INFO[0]}
  295. REDIS_MASTER_PORT_NUMBER=${REDIS_SENTINEL_INFO[1]}
  296. fi
  297. if [[ -n "$REDIS_EXTERNAL_MASTER_HOST" ]]; then
  298. REDIS_MASTER_HOST="$REDIS_EXTERNAL_MASTER_HOST"
  299. REDIS_MASTER_PORT_NUMBER="${REDIS_EXTERNAL_MASTER_PORT}"
  300. fi
  301. cp /opt/bitnami/redis-sentinel/mounted-etc/sentinel.conf /opt/bitnami/redis-sentinel/etc/sentinel.conf
  302. {{- if .Values.auth.enabled }}
  303. printf "\nsentinel auth-pass %s %s" "{{ .Values.sentinel.masterSet }}" "$REDIS_PASSWORD" >> /opt/bitnami/redis-sentinel/etc/sentinel.conf
  304. {{- if and .Values.auth.enabled .Values.auth.sentinel }}
  305. printf "\nrequirepass %s" "$REDIS_PASSWORD" >> /opt/bitnami/redis-sentinel/etc/sentinel.conf
  306. {{- end }}
  307. {{- end }}
  308. printf "\nsentinel myid %s" "$(host_id "$HOSTNAME")" >> /opt/bitnami/redis-sentinel/etc/sentinel.conf
  309. if [[ -z "$REDIS_MASTER_HOST" ]] || [[ -z "$REDIS_MASTER_PORT_NUMBER" ]]
  310. then
  311. # Prevent incorrect configuration to be written to sentinel.conf
  312. error "Redis master host is configured incorrectly (host: $REDIS_MASTER_HOST, port: $REDIS_MASTER_PORT_NUMBER)"
  313. exit 1
  314. fi
  315. sentinel_conf_set "sentinel monitor" "{{ .Values.sentinel.masterSet }} "$REDIS_MASTER_HOST" "$REDIS_MASTER_PORT_NUMBER" {{ .Values.sentinel.quorum }}"
  316. add_known_sentinel() {
  317. hostname="$1"
  318. ip="$2"
  319. if [[ -n "$hostname" && -n "$ip" && "$hostname" != "$HOSTNAME" ]]; then
  320. sentinel_conf_add "sentinel known-sentinel {{ .Values.sentinel.masterSet }} $(get_full_hostname "$hostname") $(get_port "$hostname" "SENTINEL") $(host_id "$hostname")"
  321. fi
  322. }
  323. add_known_replica() {
  324. hostname="$1"
  325. ip="$2"
  326. if [[ -n "$ip" && "$(get_full_hostname "$hostname")" != "$REDIS_MASTER_HOST" ]]; then
  327. sentinel_conf_add "sentinel known-replica {{ .Values.sentinel.masterSet }} $(get_full_hostname "$hostname") $(get_port "$hostname" "REDIS")"
  328. fi
  329. }
  330. # Add available hosts on the network as known replicas & sentinels
  331. for node in $(seq 0 $(({{ .Values.replica.replicaCount }}-1))); do
  332. hostname="{{ template "common.names.fullname" . }}-node-$node"
  333. ip="$(getent hosts "$hostname.$HEADLESS_SERVICE" | awk '{ print $1 }')"
  334. add_known_sentinel "$hostname" "$ip"
  335. add_known_replica "$hostname" "$ip"
  336. done
  337. echo "" >> /opt/bitnami/redis-sentinel/etc/sentinel.conf
  338. {{- if not (contains "sentinel announce-hostnames" .Values.sentinel.configuration) }}
  339. echo "sentinel announce-hostnames yes" >> /opt/bitnami/redis-sentinel/etc/sentinel.conf
  340. {{- end }}
  341. {{- if not (contains "sentinel resolve-hostnames" .Values.sentinel.configuration) }}
  342. echo "sentinel resolve-hostnames yes" >> /opt/bitnami/redis-sentinel/etc/sentinel.conf
  343. {{- end }}
  344. {{- if not (contains "sentinel announce-port" .Values.sentinel.configuration) }}
  345. echo "sentinel announce-port $SERVPORT" >> /opt/bitnami/redis-sentinel/etc/sentinel.conf
  346. {{- end }}
  347. {{- if not (contains "sentinel announce-ip" .Values.sentinel.configuration) }}
  348. echo "sentinel announce-ip $(get_full_hostname "$HOSTNAME")" >> /opt/bitnami/redis-sentinel/etc/sentinel.conf
  349. {{- end }}
  350. {{- if .Values.tls.enabled }}
  351. ARGS=("--port" "0")
  352. ARGS+=("--tls-port" "${REDIS_SENTINEL_TLS_PORT_NUMBER}")
  353. ARGS+=("--tls-cert-file" "${REDIS_SENTINEL_TLS_CERT_FILE}")
  354. ARGS+=("--tls-key-file" "${REDIS_SENTINEL_TLS_KEY_FILE}")
  355. ARGS+=("--tls-ca-cert-file" "${REDIS_SENTINEL_TLS_CA_FILE}")
  356. ARGS+=("--tls-replication" "yes")
  357. ARGS+=("--tls-auth-clients" "${REDIS_SENTINEL_TLS_AUTH_CLIENTS}")
  358. {{- if .Values.tls.dhParamsFilename }}
  359. ARGS+=("--tls-dh-params-file" "${REDIS_SENTINEL_TLS_DH_PARAMS_FILE}")
  360. {{- end }}
  361. {{- end }}
  362. {{- if .Values.sentinel.preExecCmds }}
  363. {{ .Values.sentinel.preExecCmds | nindent 4 }}
  364. {{- end }}
  365. exec redis-server /opt/bitnami/redis-sentinel/etc/sentinel.conf {{- if .Values.tls.enabled }} "${ARGS[@]}" {{- end }} --sentinel
  366. prestop-sentinel.sh: |
  367. #!/bin/bash
  368. . /opt/bitnami/scripts/libvalidations.sh
  369. . /opt/bitnami/scripts/libos.sh
  370. HEADLESS_SERVICE="{{ template "common.names.fullname" . }}-headless.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }}"
  371. SENTINEL_SERVICE_ENV_NAME={{ printf "%s%s" (upper (include "common.names.fullname" .)| replace "-" "_") "_SERVICE_PORT_TCP_SENTINEL" }}
  372. SENTINEL_SERVICE_PORT=${!SENTINEL_SERVICE_ENV_NAME}
  373. get_full_hostname() {
  374. hostname="$1"
  375. {{- if .Values.useExternalDNS.enabled }}
  376. full_hostname="${hostname}.{{- include "redis.externalDNS.suffix" . }}"
  377. {{- else if eq .Values.sentinel.service.type "NodePort" }}
  378. full_hostname="${hostname}.{{- .Release.Namespace }}"
  379. {{- else }}
  380. full_hostname="${hostname}.${HEADLESS_SERVICE}"
  381. {{- end }}
  382. {{- if .Values.useHostnames }}
  383. echo "${full_hostname}"
  384. {{- else }}
  385. getent hosts "${full_hostname}" | awk '{ print $1 ; exit }'
  386. {{- end }}
  387. }
  388. run_sentinel_command() {
  389. if is_boolean_yes "$REDIS_SENTINEL_TLS_ENABLED"; then
  390. redis-cli -h "$REDIS_SERVICE" -p "$SENTINEL_SERVICE_PORT" --tls --cert "$REDIS_SENTINEL_TLS_CERT_FILE" --key "$REDIS_SENTINEL_TLS_KEY_FILE" --cacert "$REDIS_SENTINEL_TLS_CA_FILE" sentinel "$@"
  391. else
  392. redis-cli -h "$REDIS_SERVICE" -p "$SENTINEL_SERVICE_PORT" sentinel "$@"
  393. fi
  394. }
  395. sentinel_failover_finished() {
  396. REDIS_SENTINEL_INFO=($(run_sentinel_command get-master-addr-by-name "{{ .Values.sentinel.masterSet }}"))
  397. REDIS_MASTER_HOST="${REDIS_SENTINEL_INFO[0]}"
  398. [[ "$REDIS_MASTER_HOST" != "$(get_full_hostname $HOSTNAME)" ]]
  399. }
  400. REDIS_SERVICE="{{ include "common.names.fullname" . }}.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }}"
  401. {{ if .Values.auth.sentinel -}}
  402. # redis-cli automatically consumes credentials from the REDISCLI_AUTH variable
  403. [[ -n "$REDIS_PASSWORD" ]] && export REDISCLI_AUTH="$REDIS_PASSWORD"
  404. [[ -f "$REDIS_PASSWORD_FILE" ]] && export REDISCLI_AUTH="$(< "${REDIS_PASSWORD_FILE}")"
  405. {{- end }}
  406. if ! sentinel_failover_finished; then
  407. echo "I am the master pod and you are stopping me. Starting sentinel failover"
  408. if retry_while "sentinel_failover_finished" "{{ sub .Values.sentinel.terminationGracePeriodSeconds 10 }}" 1; then
  409. echo "Master has been successfuly failed over to a different pod."
  410. exit 0
  411. else
  412. echo "Master failover failed"
  413. exit 1
  414. fi
  415. else
  416. exit 0
  417. fi
  418. prestop-redis.sh: |
  419. #!/bin/bash
  420. . /opt/bitnami/scripts/libvalidations.sh
  421. . /opt/bitnami/scripts/libos.sh
  422. run_redis_command() {
  423. if is_boolean_yes "$REDIS_TLS_ENABLED"; then
  424. redis-cli -h 127.0.0.1 -p "$REDIS_TLS_PORT" --tls --cert "$REDIS_TLS_CERT_FILE" --key "$REDIS_TLS_KEY_FILE" --cacert "$REDIS_TLS_CA_FILE" "$@"
  425. else
  426. redis-cli -h 127.0.0.1 -p "$REDIS_PORT" "$@"
  427. fi
  428. }
  429. is_master() {
  430. REDIS_ROLE=$(run_redis_command role | head -1)
  431. [[ "$REDIS_ROLE" == "master" ]]
  432. }
  433. HEADLESS_SERVICE="{{ template "common.names.fullname" . }}-headless.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }}"
  434. SENTINEL_SERVICE_ENV_NAME={{ printf "%s%s" (upper (include "common.names.fullname" .)| replace "-" "_") "_SERVICE_PORT_TCP_SENTINEL" }}
  435. SENTINEL_SERVICE_PORT=${!SENTINEL_SERVICE_ENV_NAME}
  436. get_full_hostname() {
  437. hostname="$1"
  438. {{- if .Values.useExternalDNS.enabled }}
  439. full_hostname="${hostname}.{{- include "redis.externalDNS.suffix" . }}"
  440. {{- else if eq .Values.sentinel.service.type "NodePort" }}
  441. full_hostname="${hostname}.{{- .Release.Namespace }}"
  442. {{- else }}
  443. full_hostname="${hostname}.${HEADLESS_SERVICE}"
  444. {{- end }}
  445. {{- if .Values.useHostnames }}
  446. echo "${full_hostname}"
  447. {{- else }}
  448. getent hosts "${full_hostname}" | awk '{ print $1 ; exit }'
  449. {{- end }}
  450. }
  451. run_sentinel_command() {
  452. if is_boolean_yes "$REDIS_SENTINEL_TLS_ENABLED"; then
  453. {{ .Values.auth.sentinel | ternary "" "env -u REDISCLI_AUTH " -}} redis-cli -h "$REDIS_SERVICE" -p "$SENTINEL_SERVICE_PORT" --tls --cert "$REDIS_SENTINEL_TLS_CERT_FILE" --key "$REDIS_SENTINEL_TLS_KEY_FILE" --cacert "$REDIS_SENTINEL_TLS_CA_FILE" sentinel "$@"
  454. else
  455. {{ .Values.auth.sentinel | ternary "" "env -u REDISCLI_AUTH " -}} redis-cli -h "$REDIS_SERVICE" -p "$SENTINEL_SERVICE_PORT" sentinel "$@"
  456. fi
  457. }
  458. sentinel_failover_finished() {
  459. REDIS_SENTINEL_INFO=($(run_sentinel_command get-master-addr-by-name "{{ .Values.sentinel.masterSet }}"))
  460. REDIS_MASTER_HOST="${REDIS_SENTINEL_INFO[0]}"
  461. [[ "$REDIS_MASTER_HOST" != "$(get_full_hostname $HOSTNAME)" ]]
  462. }
  463. REDIS_SERVICE="{{ include "common.names.fullname" . }}.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }}"
  464. # redis-cli automatically consumes credentials from the REDISCLI_AUTH variable
  465. [[ -n "$REDIS_PASSWORD" ]] && export REDISCLI_AUTH="$REDIS_PASSWORD"
  466. [[ -f "$REDIS_PASSWORD_FILE" ]] && export REDISCLI_AUTH="$(< "${REDIS_PASSWORD_FILE}")"
  467. if is_master && ! sentinel_failover_finished; then
  468. echo "I am the master pod and you are stopping me. Pausing client connections."
  469. # Pausing client write connections to avoid data loss
  470. run_redis_command CLIENT PAUSE "{{ mul (add 2 (sub .Values.sentinel.terminationGracePeriodSeconds 10)) 1000 }}" WRITE
  471. echo "Issuing failover"
  472. # if I am the master, issue a command to failover once
  473. run_sentinel_command failover "{{ .Values.sentinel.masterSet }}"
  474. {{- if .Values.sentinel.redisShutdownWaitFailover }}
  475. echo "Waiting for sentinel to complete failover for up to {{ sub .Values.sentinel.terminationGracePeriodSeconds 10 }}s"
  476. retry_while "sentinel_failover_finished" "{{ sub .Values.sentinel.terminationGracePeriodSeconds 10 }}" 1
  477. {{- end }}
  478. else
  479. exit 0
  480. fi
  481. {{- else }}
  482. start-master.sh: |
  483. #!/bin/bash
  484. [[ -f $REDIS_PASSWORD_FILE ]] && export REDIS_PASSWORD="$(< "${REDIS_PASSWORD_FILE}")"
  485. {{- if and .Values.master.containerSecurityContext.runAsUser (eq (.Values.master.containerSecurityContext.runAsUser | int) 0) }}
  486. useradd redis
  487. chown -R redis {{ .Values.master.persistence.path }}
  488. {{- end }}
  489. if [[ -f /opt/bitnami/redis/mounted-etc/master.conf ]];then
  490. cp /opt/bitnami/redis/mounted-etc/master.conf /opt/bitnami/redis/etc/master.conf
  491. fi
  492. if [[ -f /opt/bitnami/redis/mounted-etc/redis.conf ]];then
  493. cp /opt/bitnami/redis/mounted-etc/redis.conf /opt/bitnami/redis/etc/redis.conf
  494. fi
  495. {{- if .Values.tls.enabled }}
  496. ARGS=("--port" "0")
  497. ARGS+=("--tls-port" "${REDIS_TLS_PORT}")
  498. ARGS+=("--tls-cert-file" "${REDIS_TLS_CERT_FILE}")
  499. ARGS+=("--tls-key-file" "${REDIS_TLS_KEY_FILE}")
  500. ARGS+=("--tls-ca-cert-file" "${REDIS_TLS_CA_FILE}")
  501. ARGS+=("--tls-auth-clients" "${REDIS_TLS_AUTH_CLIENTS}")
  502. {{- if .Values.tls.dhParamsFilename }}
  503. ARGS+=("--tls-dh-params-file" "${REDIS_TLS_DH_PARAMS_FILE}")
  504. {{- end }}
  505. {{- else }}
  506. ARGS=("--port" "${REDIS_PORT}")
  507. {{- end }}
  508. {{- if .Values.auth.enabled }}
  509. ARGS+=("--requirepass" "${REDIS_PASSWORD}")
  510. ARGS+=("--masterauth" "${REDIS_PASSWORD}")
  511. {{- else }}
  512. ARGS+=("--protected-mode" "no")
  513. {{- end }}
  514. ARGS+=("--include" "/opt/bitnami/redis/etc/redis.conf")
  515. ARGS+=("--include" "/opt/bitnami/redis/etc/master.conf")
  516. {{- if .Values.master.extraFlags }}
  517. {{- range .Values.master.extraFlags }}
  518. ARGS+=({{ . | quote }})
  519. {{- end }}
  520. {{- end }}
  521. {{- if .Values.master.preExecCmds }}
  522. {{ .Values.master.preExecCmds | nindent 4 }}
  523. {{- end }}
  524. {{- if .Values.master.command }}
  525. exec {{ .Values.master.command }} "${ARGS[@]}"
  526. {{- else }}
  527. exec redis-server "${ARGS[@]}"
  528. {{- end }}
  529. {{- if eq .Values.architecture "replication" }}
  530. start-replica.sh: |
  531. #!/bin/bash
  532. get_port() {
  533. hostname="$1"
  534. type="$2"
  535. port_var=$(echo "${hostname^^}_SERVICE_PORT_$type" | sed "s/-/_/g")
  536. port=${!port_var}
  537. if [ -z "$port" ]; then
  538. case $type in
  539. "SENTINEL")
  540. echo {{ .Values.sentinel.containerPorts.sentinel }}
  541. ;;
  542. "REDIS")
  543. echo {{ .Values.master.containerPorts.redis }}
  544. ;;
  545. esac
  546. else
  547. echo $port
  548. fi
  549. }
  550. get_full_hostname() {
  551. hostname="$1"
  552. {{- if .Values.useExternalDNS.enabled }}
  553. full_hostname="${hostname}.{{- include "redis.externalDNS.suffix" . }}"
  554. {{- else if eq .Values.sentinel.service.type "NodePort" }}
  555. full_hostname="${hostname}.{{- .Release.Namespace }}"
  556. {{- else }}
  557. full_hostname="${hostname}.${HEADLESS_SERVICE}"
  558. {{- end }}
  559. {{- if .Values.useHostnames }}
  560. echo "${full_hostname}"
  561. {{- else }}
  562. getent hosts "${full_hostname}" | awk '{ print $1 ; exit }'
  563. {{- end }}
  564. }
  565. REDISPORT=$(get_port "$HOSTNAME" "REDIS")
  566. [[ -f $REDIS_PASSWORD_FILE ]] && export REDIS_PASSWORD="$(< "${REDIS_PASSWORD_FILE}")"
  567. [[ -f $REDIS_MASTER_PASSWORD_FILE ]] && export REDIS_MASTER_PASSWORD="$(< "${REDIS_MASTER_PASSWORD_FILE}")"
  568. {{- if and .Values.replica.containerSecurityContext.runAsUser (eq (.Values.replica.containerSecurityContext.runAsUser | int) 0) }}
  569. useradd redis
  570. chown -R redis {{ .Values.replica.persistence.path }}
  571. {{- end }}
  572. if [[ -f /opt/bitnami/redis/mounted-etc/replica.conf ]];then
  573. cp /opt/bitnami/redis/mounted-etc/replica.conf /opt/bitnami/redis/etc/replica.conf
  574. fi
  575. if [[ -f /opt/bitnami/redis/mounted-etc/redis.conf ]];then
  576. cp /opt/bitnami/redis/mounted-etc/redis.conf /opt/bitnami/redis/etc/redis.conf
  577. fi
  578. echo "" >> /opt/bitnami/redis/etc/replica.conf
  579. echo "replica-announce-port $REDISPORT" >> /opt/bitnami/redis/etc/replica.conf
  580. echo "replica-announce-ip $(get_full_hostname "$HOSTNAME")" >> /opt/bitnami/redis/etc/replica.conf
  581. {{- if .Values.tls.enabled }}
  582. ARGS=("--port" "0")
  583. ARGS+=("--tls-port" "${REDIS_TLS_PORT}")
  584. ARGS+=("--tls-cert-file" "${REDIS_TLS_CERT_FILE}")
  585. ARGS+=("--tls-key-file" "${REDIS_TLS_KEY_FILE}")
  586. ARGS+=("--tls-ca-cert-file" "${REDIS_TLS_CA_FILE}")
  587. ARGS+=("--tls-auth-clients" "${REDIS_TLS_AUTH_CLIENTS}")
  588. ARGS+=("--tls-replication" "yes")
  589. {{- if .Values.tls.dhParamsFilename }}
  590. ARGS+=("--tls-dh-params-file" "${REDIS_TLS_DH_PARAMS_FILE}")
  591. {{- end }}
  592. {{- else }}
  593. ARGS=("--port" "${REDIS_PORT}")
  594. {{- end }}
  595. ARGS+=("--replicaof" "${REDIS_MASTER_HOST}" "${REDIS_MASTER_PORT_NUMBER}")
  596. {{- if .Values.auth.enabled }}
  597. ARGS+=("--requirepass" "${REDIS_PASSWORD}")
  598. ARGS+=("--masterauth" "${REDIS_MASTER_PASSWORD}")
  599. {{- else }}
  600. ARGS+=("--protected-mode" "no")
  601. {{- end }}
  602. ARGS+=("--include" "/opt/bitnami/redis/etc/redis.conf")
  603. ARGS+=("--include" "/opt/bitnami/redis/etc/replica.conf")
  604. {{- if .Values.replica.extraFlags }}
  605. {{- range .Values.replica.extraFlags }}
  606. ARGS+=({{ . | quote }})
  607. {{- end }}
  608. {{- end }}
  609. {{- if .Values.replica.preExecCmds }}
  610. {{ .Values.replica.preExecCmds | nindent 4 }}
  611. {{- end }}
  612. {{- if .Values.replica.command }}
  613. exec {{ .Values.replica.command }} "${ARGS[@]}"
  614. {{- else }}
  615. exec redis-server "${ARGS[@]}"
  616. {{- end }}
  617. {{- end }}
  618. {{- end }}