From faed1b1c278c47777732b5e2acd0cf681db874f9 Mon Sep 17 00:00:00 2001 From: Jose Antonio Carmona Date: Wed, 10 Jun 2020 14:13:23 +0200 Subject: [PATCH] [bitnami/redis-cluster] Add TLS support for cluster (#2760) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [bitnami/redis-cluster] Add TLS support to Redis-Cluster Signed-off-by: joancafom * [bitnami/redis-cluster] Update components versions Signed-off-by: Bitnami Containers Co-authored-by: Carlos Rodríguez Hernández Co-authored-by: Bitnami Containers --- bitnami/redis-cluster/Chart.yaml | 2 +- bitnami/redis-cluster/README.md | 37 + bitnami/redis-cluster/templates/NOTES.txt | 20 +- bitnami/redis-cluster/templates/_helpers.tpl | 30 + .../redis-cluster/templates/configmap.yaml | 797 ++++++++++++++---- .../redis-cluster/templates/init-cluster.yaml | 40 +- .../templates/redis-statefulset.yaml | 41 + .../templates/scripts-configmap.yaml | 16 + .../templates/update-cluster.yaml | 38 +- bitnami/redis-cluster/values-production.yaml | 27 +- bitnami/redis-cluster/values.yaml | 27 +- 11 files changed, 888 insertions(+), 187 deletions(-) diff --git a/bitnami/redis-cluster/Chart.yaml b/bitnami/redis-cluster/Chart.yaml index 4c2389fd57..8ee8fd193b 100644 --- a/bitnami/redis-cluster/Chart.yaml +++ b/bitnami/redis-cluster/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 name: redis-cluster -version: 2.2.4 +version: 2.3.0 appVersion: 6.0.5 description: Open source, advanced key-value store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets and sorted sets. keywords: diff --git a/bitnami/redis-cluster/README.md b/bitnami/redis-cluster/README.md index a6376372dc..91d24ba51f 100644 --- a/bitnami/redis-cluster/README.md +++ b/bitnami/redis-cluster/README.md @@ -130,6 +130,13 @@ The following table lists the configurable parameters of the Redis chart and the | `podLabels` | Additional labels for Redis pod | {} | | `podAnnotations` | Additional annotations for Redis pod | {} | | `redisPort` | Redis port. | `6379` | +| `tls.enabled` | Enable TLS support for replication traffic | `false` | +| `tls.authClients` | Require clients to authenticate or not | `true` | +| `tls.certificatesSecret` | Name of the secret that contains the certificates | `nil` | +| `tls.certFilename` | Certificate filename | `nil` | +| `tls.certKeyFilename` | Certificate key filename | `nil` | +| `tls.certCAFilename` | CA Certificate filename | `nil` | +| `tls.dhParamsFilename` | DH params (in order to support DH based ciphers) | `nil` | | `command` | Redis entrypoint string. The command `redis-server` is executed if this is not provided. | `nil` | | `args` | Arguments for the provided command if needed | `nil` | | `configmap` | Additional Redis configuration for the nodes (this value is evaluated as a template) | `nil` | @@ -365,6 +372,36 @@ existingSecret=redis-password-secret metrics.enabled=true ``` +### Securing traffic using TLS + +TLS support can be enabled in the chart by specifying the `tls.` parameters while creating a release. The following parameters should be configured to properly enable the TLS support in the cluster: + +- `tls.enabled`: Enable TLS support. Defaults to `false` +- `tls.certificatesSecret`: Name of the secret that contains the certificates. No defaults. +- `tls.certFilename`: Certificate filename. No defaults. +- `tls.certKeyFilename`: Certificate key filename. No defaults. +- `tls.certCAFilename`: CA Certificate filename. No defaults. + +For example: + +First, create the secret with the cetificates files: + +```console +kubectl create secret generic certificates-tls-secret --from-file=./cert.pem --from-file=./cert.key --from-file=./ca.pem +``` + +Then, use the following parameters: + +```console +tls.enabled="true" +tls.certificatesSecret="certificates-tls-secret" +tls.certFilename="cert.pem" +tls.certKeyFilename="cert.key" +tls.certCAFilename="ca.pem" +``` + +> **Note TLS and Prometheus Metrics**: Current version of Redis Metrics Exporter (v1.6.1 at the time of writing) does not fully support the use of TLS. By enabling both features, the metric reporting pod may not work as expected. See Redis Metrics Exporter issue [387](https://github.com/oliver006/redis_exporter/issues/387) for more information. + ### Sidecars and Init Containers If you have a need for additional containers to run within the same pod as Redis (e.g. an additional metrics or logging exporter), you can do so via the `sidecars` config parameter. Simply define your container according to the Kubernetes container spec. diff --git a/bitnami/redis-cluster/templates/NOTES.txt b/bitnami/redis-cluster/templates/NOTES.txt index 2b5c7095dd..3b3d95e889 100644 --- a/bitnami/redis-cluster/templates/NOTES.txt +++ b/bitnami/redis-cluster/templates/NOTES.txt @@ -29,7 +29,7 @@ To connect to your Redis server from outside the cluster check the following inf To connect to your database from outside the cluster execute the following commands: export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "redis-cluster.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") - redis-cli -c -h $SERVICE_IP -p {{ .Values.service.port }} {{- if .Values.usePassword }} -a $REDIS_PASSWORD{{ end }} + redis-cli -c -h $SERVICE_IP -p {{ .Values.service.port }} {{- if .Values.usePassword }} -a $REDIS_PASSWORD{{ end }}{{ if .Values.tls.enabled }} --tls --cert /tmp/client.cert --key /tmp/client.key --cacert /tmp/CA.cert{{ end }} {{- end }} {{- else }} @@ -44,14 +44,30 @@ To connect to your Redis cluster: 1. Run a Redis pod that you can use as a client: +{{- if .Values.tls.enabled }} + kubectl run --namespace {{ .Release.Namespace }} {{ template "redis-cluster.fullname" . }}-client --restart='Never' --env REDIS_PASSWORD=$REDIS_PASSWORD --image {{ template "redis-cluster.image" . }} --command -- sleep infinity + + Copy your TLS certificates to the pod: + + kubectl cp --namespace {{ .Release.Namespace }} /path/to/client.cert {{ template "redis-cluster.fullname" . }}-client:/tmp/client.cert + kubectl cp --namespace {{ .Release.Namespace }} /path/to/client.key {{ template "redis-cluster.fullname" . }}-client:/tmp/client.key + kubectl cp --namespace {{ .Release.Namespace }} /path/to/CA.cert {{ template "redis-cluster.fullname" . }}-client:/tmp/CA.cert + + Use the following command to attach to the pod: + + kubectl exec --tty -i {{ template "redis-cluster.fullname" . }}-client \ + {{- if and (.Values.networkPolicy.enabled) (not .Values.networkPolicy.allowExternal) }}--labels="{{ template "redis-cluster.fullname" . }}-client=true" \{{- end }} + --namespace {{ .Release.Namespace }} -- bash +{{- else }} kubectl run --namespace {{ .Release.Namespace }} {{ template "redis-cluster.fullname" . }}-client --rm --tty -i --restart='Never' \ {{ if .Values.usePassword }} --env REDIS_PASSWORD=$REDIS_PASSWORD \{{ end }} {{- if and (.Values.networkPolicy.enabled) (not .Values.networkPolicy.allowExternal) }}--labels="{{ template "redis-cluster.fullname" . }}-client=true" \{{- end }} --image {{ template "redis-cluster.image" . }} -- bash +{{- end }} 2. Connect using the Redis CLI: -redis-cli -c -h {{ template "redis-cluster.fullname" . }}{{ if .Values.usePassword }} -a $REDIS_PASSWORD{{ end }} +redis-cli -c -h {{ template "redis-cluster.fullname" . }}{{ if .Values.usePassword }} -a $REDIS_PASSWORD{{ end }}{{ if .Values.tls.enabled }} --tls --cert /tmp/client.cert --key /tmp/client.key --cacert /tmp/CA.cert{{ end }} {{ if and (.Values.networkPolicy.enabled) (not .Values.networkPolicy.allowExternal) }} Note: Since NetworkPolicy is enabled, only pods with label diff --git a/bitnami/redis-cluster/templates/_helpers.tpl b/bitnami/redis-cluster/templates/_helpers.tpl index 2c4e0f3757..881c8ec81e 100644 --- a/bitnami/redis-cluster/templates/_helpers.tpl +++ b/bitnami/redis-cluster/templates/_helpers.tpl @@ -133,6 +133,36 @@ Also, we can't use a single if because lazy evaluation is not an option {{- end -}} {{- end -}} +{{/* +Return the path to the cert file. +*/}} +{{- define "redis-cluster.tlsCert" -}} +{{- required "Certificate filename is required when TLS in enabled" .Values.tls.certFilename | printf "/opt/bitnami/redis/certs/%s" -}} +{{- end -}} + +{{/* +Return the path to the cert key file. +*/}} +{{- define "redis-cluster.tlsCertKey" -}} +{{- required "Certificate Key filename is required when TLS in enabled" .Values.tls.certKeyFilename | printf "/opt/bitnami/redis/certs/%s" -}} +{{- end -}} + +{{/* +Return the path to the CA cert file. +*/}} +{{- define "redis-cluster.tlsCACert" -}} +{{- required "Certificate CA filename is required when TLS in enabled" .Values.tls.certCAFilename | printf "/opt/bitnami/redis/certs/%s" -}} +{{- end -}} + +{{/* +Return the path to the DH params file. +*/}} +{{- define "redis-cluster.tlsDHParams" -}} +{{- if .Values.tls.dhParamsFilename -}} +{{- printf "/opt/bitnami/redis/certs/%s" .Values.tls.dhParamsFilename -}} +{{- end -}} +{{- end -}} + {{/* Create the name of the service account to use */}} diff --git a/bitnami/redis-cluster/templates/configmap.yaml b/bitnami/redis-cluster/templates/configmap.yaml index e952965048..54b0ba17f1 100644 --- a/bitnami/redis-cluster/templates/configmap.yaml +++ b/bitnami/redis-cluster/templates/configmap.yaml @@ -11,7 +11,7 @@ data: # started with the file path as first argument: # # ./redis-server /path/to/redis.conf - + # Note on units: when memory size is needed, it is possible to specify # it in the usual form of 1k 5GB 4M and so forth: # @@ -23,9 +23,9 @@ data: # 1gb => 1024*1024*1024 bytes # # units are case insensitive so 1GB 1Gb 1gB are all the same. - + ################################## INCLUDES ################################### - + # Include one or more other config files here. This is useful if you # have a standard template that goes to all Redis servers but also need # to customize a few per-server settings. Include files can include @@ -41,17 +41,17 @@ data: # # include /path/to/local.conf # include /path/to/other.conf - + ################################## MODULES ##################################### - + # Load modules at startup. If the server is not able to load modules # it will abort. It is possible to use multiple loadmodule directives. # # loadmodule /path/to/my_module.so # loadmodule /path/to/other_module.so - + ################################## NETWORK ##################################### - + # By default, if no "bind" configuration directive is specified, Redis listens # for connections from all the network interfaces available on the server. # It is possible to listen to just one or multiple selected interfaces using @@ -74,7 +74,7 @@ data: # JUST COMMENT THE FOLLOWING LINE. # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ bind 127.0.0.1 - + # Protected mode is a layer of security protection, in order to avoid that # Redis instances left open on the internet are accessed and exploited. # @@ -93,11 +93,11 @@ data: # even if no authentication is configured, nor a specific set of interfaces # are explicitly listed using the "bind" directive. protected-mode yes - + # Accept connections on the specified port, default is 6379 (IANA #815344). # If port 0 is specified Redis will not listen on a TCP socket. port 6379 - + # TCP listen() backlog. # # In high requests-per-second environments you need an high backlog in order @@ -106,7 +106,7 @@ data: # make sure to raise both the value of somaxconn and tcp_max_syn_backlog # in order to get the desired effect. tcp-backlog 511 - + # Unix socket. # # Specify the path for the Unix socket that will be used to listen for @@ -115,10 +115,10 @@ data: # # unixsocket /tmp/redis.sock # unixsocketperm 700 - + # Close the connection after a client is idle for N seconds (0 to disable) timeout 0 - + # TCP keepalive. # # If non-zero, use SO_KEEPALIVE to send TCP ACKs to clients in absence @@ -135,13 +135,83 @@ data: # A reasonable value for this option is 300 seconds, which is the new # Redis default starting with Redis 3.2.1. tcp-keepalive 300 - + + ################################# TLS/SSL ##################################### + + # By default, TLS/SSL is disabled. To enable it, the "tls-port" configuration + # directive can be used to define TLS-listening ports. To enable TLS on the + # default port, use: + # + # port 0 + # tls-port 6379 + + # Configure a X.509 certificate and private key to use for authenticating the + # server to connected clients, masters or cluster peers. These files should be + # PEM formatted. + # + # tls-cert-file redis.crt + # tls-key-file redis.key + + # Configure a DH parameters file to enable Diffie-Hellman (DH) key exchange: + # + # tls-dh-params-file redis.dh + + # Configure a CA certificate(s) bundle or directory to authenticate TLS/SSL + # clients and peers. Redis requires an explicit configuration of at least one + # of these, and will not implicitly use the system wide configuration. + # + # tls-ca-cert-file ca.crt + # tls-ca-cert-dir /etc/ssl/certs + + # By default, clients (including replica servers) on a TLS port are required + # to authenticate using valid client side certificates. + # + # It is possible to disable authentication using this directive. + # + # tls-auth-clients no + + # By default, a Redis replica does not attempt to establish a TLS connection + # with its master. + # + # Use the following directive to enable TLS on replication links. + # + # tls-replication yes + + # By default, the Redis Cluster bus uses a plain TCP connection. To enable + # TLS for the bus protocol, use the following directive: + # + # tls-cluster yes + + # Explicitly specify TLS versions to support. Allowed values are case insensitive + # and include "TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3" (OpenSSL >= 1.1.1) or + # any combination. To enable only TLSv1.2 and TLSv1.3, use: + # + # tls-protocols "TLSv1.2 TLSv1.3" + + # Configure allowed ciphers. See the ciphers(1ssl) manpage for more information + # about the syntax of this string. + # + # Note: this configuration applies only to <= TLSv1.2. + # + # tls-ciphers DEFAULT:!MEDIUM + + # Configure allowed TLSv1.3 ciphersuites. See the ciphers(1ssl) manpage for more + # information about the syntax of this string, and specifically for TLSv1.3 + # ciphersuites. + # + # tls-ciphersuites TLS_CHACHA20_POLY1305_SHA256 + + # When choosing a cipher, use the server's preference instead of the client + # preference. By default, the server follows the client's preference. + # + # tls-prefer-server-ciphers yes + ################################# GENERAL ##################################### - + # By default Redis does not run as a daemon. Use 'yes' if you need it. # Note that Redis will write a pid file in /var/run/redis.pid when daemonized. daemonize no - + # If you run Redis from upstart or systemd, Redis can interact with your # supervision tree. Options: # supervised no - no supervision interaction @@ -152,7 +222,7 @@ data: # Note: these supervision methods only signal "process is ready." # They do not enable continuous liveness pings back to your supervisor. supervised no - + # If a pid file is specified, Redis writes it where specified at startup # and removes it at exit. # @@ -163,7 +233,7 @@ data: # Creating a pid file is best effort: if Redis is not able to create it # nothing bad happens, the server will start and run normally. pidfile /var/run/redis_6379.pid - + # Specify the server verbosity level. # This can be one of: # debug (a lot of information, useful for development/testing) @@ -171,27 +241,27 @@ data: # notice (moderately verbose, what you want in production probably) # warning (only very important / critical messages are logged) loglevel notice - + # Specify the log file name. Also the empty string can be used to force # Redis to log on the standard output. Note that if you use standard # output for logging but daemonize, logs will be sent to /dev/null logfile "" - + # To enable logging to the system logger, just set 'syslog-enabled' to yes, # and optionally update the other syslog parameters to suit your needs. # syslog-enabled no - + # Specify the syslog identity. # syslog-ident redis - + # Specify the syslog facility. Must be USER or between LOCAL0-LOCAL7. # syslog-facility local0 - + # Set the number of databases. The default database is DB 0, you can select # a different one on a per-connection basis using SELECT where # dbid is a number between 0 and 'databases'-1 databases 16 - + # By default Redis shows an ASCII art logo only when started to log to the # standard output and if the standard output is a TTY. Basically this means # that normally a logo is displayed only in interactive sessions. @@ -199,7 +269,7 @@ data: # However it is possible to force the pre-4.0 behavior and always show a # ASCII art logo in startup logs by setting the following option to yes. always-show-logo yes - + ################################ SNAPSHOTTING ################################ # # Save the DB on disk: @@ -221,11 +291,11 @@ data: # like in the following example: # # save "" - + save 900 1 save 300 10 save 60 10000 - + # By default Redis will stop accepting writes if RDB snapshots are enabled # (at least one save point) and the latest background save failed. # This will make the user aware (in a hard way) that data is not persisting @@ -240,13 +310,13 @@ data: # continue to work as usual even if there are problems with disk, # permissions, and so forth. stop-writes-on-bgsave-error yes - + # Compress string objects using LZF when dump .rdb databases? # For default that's set to 'yes' as it's almost always a win. # If you want to save some CPU in the saving child set it to 'no' but # the dataset will likely be bigger if you have compressible values or keys. rdbcompression yes - + # Since version 5 of RDB a CRC64 checksum is placed at the end of the file. # This makes the format more resistant to corruption but there is a performance # hit to pay (around 10%) when saving and loading RDB files, so you can disable it @@ -255,10 +325,23 @@ data: # RDB files created with checksum disabled have a checksum of zero that will # tell the loading code to skip the check. rdbchecksum yes - + # The filename where to dump the DB dbfilename dump.rdb - + + # Remove RDB files used by replication in instances without persistence + # enabled. By default this option is disabled, however there are environments + # where for regulations or other security concerns, RDB files persisted on + # disk by masters in order to feed replicas, or stored on disk by replicas + # in order to load them for the initial synchronization, should be deleted + # ASAP. Note that this option ONLY WORKS in instances that have both AOF + # and RDB persistence disabled, otherwise is completely ignored. + # + # An alternative (and sometimes better) way to obtain the same effect is + # to use diskless replication on both master and replicas instances. However + # in the case of replicas, diskless is not always an option. + rdb-del-sync-files no + # The working directory. # # The DB will be written inside this directory, with the filename specified @@ -268,9 +351,9 @@ data: # # Note that you must specify a directory here, not a file name. dir ./ - + ################################# REPLICATION ################################# - + # Master-Replica replication. Use replicaof to make a Redis instance a copy of # another Redis server. A few things to understand ASAP about Redis replication. # @@ -291,14 +374,25 @@ data: # and resynchronize with them. # # replicaof - + # If the master is password protected (using the "requirepass" configuration # directive below) it is possible to tell the replica to authenticate before # starting the replication synchronization process, otherwise the master will # refuse the replica request. # # masterauth - + # + # However this is not enough if you are using Redis ACLs (for Redis version + # 6 or greater), and the default user is not capable of running the PSYNC + # command and/or other commands needed for replication. In this case it's + # better to configure a special user to use with replication, and specify the + # masteruser configuration as such: + # + # masteruser + # + # When masteruser is specified, the replica will authenticate against its + # master using the new AUTH form: AUTH . + # When a replica loses its connection with the master, or when the replication # is still in progress, the replica can act in two different ways: # @@ -313,7 +407,7 @@ data: # COMMAND, POST, HOST: and LATENCY. # replica-serve-stale-data yes - + # You can configure a replica instance to accept writes or not. Writing against # a replica instance may be useful to store some ephemeral data (because data # written on a replica will be easily deleted after resync with the master) but @@ -329,16 +423,14 @@ data: # security of read only replicas using 'rename-command' to shadow all the # administrative / dangerous commands. replica-read-only yes - + # Replication SYNC strategy: disk or socket. # - # ------------------------------------------------------- - # WARNING: DISKLESS REPLICATION IS EXPERIMENTAL CURRENTLY - # ------------------------------------------------------- + # New replicas and reconnecting replicas that are not able to continue the + # replication process just receiving differences, need to do what is called a + # "full synchronization". An RDB file is transmitted from the master to the + # replicas. # - # New replicas and reconnecting replicas that are not able to continue the replication - # process just receiving differences, need to do what is called a "full - # synchronization". An RDB file is transmitted from the master to the replicas. # The transmission can happen in two different ways: # # 1) Disk-backed: The Redis master creates a new process that writes the RDB @@ -348,37 +440,63 @@ data: # RDB file to replica sockets, without touching the disk at all. # # With disk-backed replication, while the RDB file is generated, more replicas - # can be queued and served with the RDB file as soon as the current child producing - # the RDB file finishes its work. With diskless replication instead once - # the transfer starts, new replicas arriving will be queued and a new transfer - # will start when the current one terminates. + # can be queued and served with the RDB file as soon as the current child + # producing the RDB file finishes its work. With diskless replication instead + # once the transfer starts, new replicas arriving will be queued and a new + # transfer will start when the current one terminates. # # When diskless replication is used, the master waits a configurable amount of - # time (in seconds) before starting the transfer in the hope that multiple replicas - # will arrive and the transfer can be parallelized. + # time (in seconds) before starting the transfer in the hope that multiple + # replicas will arrive and the transfer can be parallelized. # # With slow disks and fast (large bandwidth) networks, diskless replication # works better. repl-diskless-sync no - + # When diskless replication is enabled, it is possible to configure the delay # the server waits in order to spawn the child that transfers the RDB via socket # to the replicas. # # This is important since once the transfer starts, it is not possible to serve - # new replicas arriving, that will be queued for the next RDB transfer, so the server - # waits a delay in order to let more replicas arrive. + # new replicas arriving, that will be queued for the next RDB transfer, so the + # server waits a delay in order to let more replicas arrive. # # The delay is specified in seconds, and by default is 5 seconds. To disable # it entirely just set it to 0 seconds and the transfer will start ASAP. repl-diskless-sync-delay 5 - - # Replicas send PINGs to server in a predefined interval. It's possible to change - # this interval with the repl_ping_replica_period option. The default value is 10 - # seconds. + + # ----------------------------------------------------------------------------- + # WARNING: RDB diskless load is experimental. Since in this setup the replica + # does not immediately store an RDB on disk, it may cause data loss during + # failovers. RDB diskless load + Redis modules not handling I/O reads may also + # cause Redis to abort in case of I/O errors during the initial synchronization + # stage with the master. Use only if your do what you are doing. + # ----------------------------------------------------------------------------- + # + # Replica can load the RDB it reads from the replication link directly from the + # socket, or store the RDB to a file and read that file after it was completely + # recived from the master. + # + # In many cases the disk is slower than the network, and storing and loading + # the RDB file may increase replication time (and even increase the master's + # Copy on Write memory and salve buffers). + # However, parsing the RDB file directly from the socket may mean that we have + # to flush the contents of the current database before the full rdb was + # received. For this reason we have the following options: + # + # "disabled" - Don't use diskless load (store the rdb file to the disk first) + # "on-empty-db" - Use diskless load only when it is completely safe. + # "swapdb" - Keep a copy of the current db contents in RAM while parsing + # the data directly from the socket. note that this requires + # sufficient memory, if you don't have it, you risk an OOM kill. + repl-diskless-load disabled + + # Replicas send PINGs to server in a predefined interval. It's possible to + # change this interval with the repl_ping_replica_period option. The default + # value is 10 seconds. # # repl-ping-replica-period 10 - + # The following option sets the replication timeout for: # # 1) Bulk transfer I/O during SYNC, from the point of view of replica. @@ -390,7 +508,7 @@ data: # every time there is low traffic between the master and the replica. # # repl-timeout 60 - + # Disable TCP_NODELAY on the replica socket after SYNC? # # If you select "yes" Redis will use a smaller number of TCP packets and @@ -405,12 +523,12 @@ data: # or when the master and replicas are many hops away, turning this to "yes" may # be a good idea. repl-disable-tcp-nodelay no - + # Set the replication backlog size. The backlog is a buffer that accumulates - # replica data when replicas are disconnected for some time, so that when a replica - # wants to reconnect again, often a full resync is not needed, but a partial - # resync is enough, just passing the portion of data the replica missed while - # disconnected. + # replica data when replicas are disconnected for some time, so that when a + # replica wants to reconnect again, often a full resync is not needed, but a + # partial resync is enough, just passing the portion of data the replica + # missed while disconnected. # # The bigger the replication backlog, the longer the time the replica can be # disconnected and later be able to perform a partial resynchronization. @@ -418,7 +536,7 @@ data: # The backlog is only allocated once there is at least a replica connected. # # repl-backlog-size 1mb - + # After a master has no longer connected replicas for some time, the backlog # will be freed. The following option configures the amount of seconds that # need to elapse, starting from the time the last replica disconnected, for @@ -431,14 +549,14 @@ data: # A value of 0 means to never release the backlog. # # repl-backlog-ttl 3600 - - # The replica priority is an integer number published by Redis in the INFO output. - # It is used by Redis Sentinel in order to select a replica to promote into a - # master if the master is no longer working correctly. + + # The replica priority is an integer number published by Redis in the INFO + # output. It is used by Redis Sentinel in order to select a replica to promote + # into a master if the master is no longer working correctly. # # A replica with a low priority number is considered better for promotion, so - # for instance if there are three replicas with priority 10, 100, 25 Sentinel will - # pick the one with priority 10, that is the lowest. + # for instance if there are three replicas with priority 10, 100, 25 Sentinel + # will pick the one with priority 10, that is the lowest. # # However a special priority of 0 marks the replica as not able to perform the # role of master, so a replica with priority of 0 will never be selected by @@ -446,7 +564,7 @@ data: # # By default the priority is 100. replica-priority 100 - + # It is possible for a master to stop accepting writes if there are less than # N replicas connected, having a lag less or equal than M seconds. # @@ -468,7 +586,7 @@ data: # # By default min-replicas-to-write is set to 0 (feature disabled) and # min-replicas-max-lag is set to 10. - + # A Redis master is able to list the address and port of the attached # replicas in different ways. For example the "INFO replication" section # offers this information, which is used, among other tools, by @@ -497,23 +615,175 @@ data: # # replica-announce-ip 5.5.5.5 # replica-announce-port 1234 - + + ############################### KEYS TRACKING ################################# + + # Redis implements server assisted support for client side caching of values. + # This is implemented using an invalidation table that remembers, using + # 16 millions of slots, what clients may have certain subsets of keys. In turn + # this is used in order to send invalidation messages to clients. Please + # to understand more about the feature check this page: + # + # https://redis.io/topics/client-side-caching + # + # When tracking is enabled for a client, all the read only queries are assumed + # to be cached: this will force Redis to store information in the invalidation + # table. When keys are modified, such information is flushed away, and + # invalidation messages are sent to the clients. However if the workload is + # heavily dominated by reads, Redis could use more and more memory in order + # to track the keys fetched by many clients. + # + # For this reason it is possible to configure a maximum fill value for the + # invalidation table. By default it is set to 1M of keys, and once this limit + # is reached, Redis will start to evict keys in the invalidation table + # even if they were not modified, just to reclaim memory: this will in turn + # force the clients to invalidate the cached values. Basically the table + # maximum size is a trade off between the memory you want to spend server + # side to track information about who cached what, and the ability of clients + # to retain cached objects in memory. + # + # If you set the value to 0, it means there are no limits, and Redis will + # retain as many keys as needed in the invalidation table. + # In the "stats" INFO section, you can find information about the number of + # keys in the invalidation table at every given moment. + # + # Note: when key tracking is used in broadcasting mode, no memory is used + # in the server side so this setting is useless. + # + # tracking-table-max-keys 1000000 + ################################## SECURITY ################################### - - # Require clients to issue AUTH before processing any other - # commands. This might be useful in environments in which you do not trust - # others with access to the host running redis-server. - # - # This should stay commented out for backward compatibility and because most - # people do not need auth (e.g. they run their own servers). - # + # Warning: since Redis is pretty fast an outside user can try up to - # 150k passwords per second against a good box. This means that you should - # use a very strong password otherwise it will be very easy to break. + # 1 million passwords per second against a modern box. This means that you + # should use very strong passwords, otherwise they will be very easy to break. + # Note that because the password is really a shared secret between the client + # and the server, and should not be memorized by any human, the password + # can be easily a long string from /dev/urandom or whatever, so by using a + # long and unguessable password no brute force attack will be possible. + + # Redis ACL users are defined in the following format: + # + # user ... acl rules ... + # + # For example: + # + # user worker +@list +@connection ~jobs:* on >ffa9203c493aa99 + # + # The special username "default" is used for new connections. If this user + # has the "nopass" rule, then new connections will be immediately authenticated + # as the "default" user without the need of any password provided via the + # AUTH command. Otherwise if the "default" user is not flagged with "nopass" + # the connections will start in not authenticated state, and will require + # AUTH (or the HELLO command AUTH option) in order to be authenticated and + # start to work. + # + # The ACL rules that describe what an user can do are the following: + # + # on Enable the user: it is possible to authenticate as this user. + # off Disable the user: it's no longer possible to authenticate + # with this user, however the already authenticated connections + # will still work. + # + Allow the execution of that command + # - Disallow the execution of that command + # +@ Allow the execution of all the commands in such category + # with valid categories are like @admin, @set, @sortedset, ... + # and so forth, see the full list in the server.c file where + # the Redis command table is described and defined. + # The special category @all means all the commands, but currently + # present in the server, and that will be loaded in the future + # via modules. + # +|subcommand Allow a specific subcommand of an otherwise + # disabled command. Note that this form is not + # allowed as negative like -DEBUG|SEGFAULT, but + # only additive starting with "+". + # allcommands Alias for +@all. Note that it implies the ability to execute + # all the future commands loaded via the modules system. + # nocommands Alias for -@all. + # ~ Add a pattern of keys that can be mentioned as part of + # commands. For instance ~* allows all the keys. The pattern + # is a glob-style pattern like the one of KEYS. + # It is possible to specify multiple patterns. + # allkeys Alias for ~* + # resetkeys Flush the list of allowed keys patterns. + # > Add this passowrd to the list of valid password for the user. + # For example >mypass will add "mypass" to the list. + # This directive clears the "nopass" flag (see later). + # < Remove this password from the list of valid passwords. + # nopass All the set passwords of the user are removed, and the user + # is flagged as requiring no password: it means that every + # password will work against this user. If this directive is + # used for the default user, every new connection will be + # immediately authenticated with the default user without + # any explicit AUTH command required. Note that the "resetpass" + # directive will clear this condition. + # resetpass Flush the list of allowed passwords. Moreover removes the + # "nopass" status. After "resetpass" the user has no associated + # passwords and there is no way to authenticate without adding + # some password (or setting it as "nopass" later). + # reset Performs the following actions: resetpass, resetkeys, off, + # -@all. The user returns to the same state it has immediately + # after its creation. + # + # ACL rules can be specified in any order: for instance you can start with + # passwords, then flags, or key patterns. However note that the additive + # and subtractive rules will CHANGE MEANING depending on the ordering. + # For instance see the following example: + # + # user alice on +@all -DEBUG ~* >somepassword + # + # This will allow "alice" to use all the commands with the exception of the + # DEBUG command, since +@all added all the commands to the set of the commands + # alice can use, and later DEBUG was removed. However if we invert the order + # of two ACL rules the result will be different: + # + # user alice on -DEBUG +@all ~* >somepassword + # + # Now DEBUG was removed when alice had yet no commands in the set of allowed + # commands, later all the commands are added, so the user will be able to + # execute everything. + # + # Basically ACL rules are processed left-to-right. + # + # For more information about ACL configuration please refer to + # the Redis web site at https://redis.io/topics/acl + + # ACL LOG + # + # The ACL Log tracks failed commands and authentication events associated + # with ACLs. The ACL Log is useful to troubleshoot failed commands blocked + # by ACLs. The ACL Log is stored in and consumes memory. There is no limit + # to its length.You can reclaim memory with ACL LOG RESET or set a maximum + # length below. + acllog-max-len 128 + + # Using an external ACL file + # + # Instead of configuring users here in this file, it is possible to use + # a stand-alone file just listing users. The two methods cannot be mixed: + # if you configure users here and at the same time you activate the exteranl + # ACL file, the server will refuse to start. + # + # The format of the external ACL user file is exactly the same as the + # format that is used inside redis.conf to describe users. + # + # aclfile /etc/redis/users.acl + + # IMPORTANT NOTE: starting with Redis 6 "requirepass" is just a compatiblity + # layer on top of the new ACL system. The option effect will be just setting + # the password for the default user. Clients will still authenticate using + # AUTH as usually, or more explicitly with AUTH default + # if they follow the new protocol: both will work. # # requirepass foobared - - # Command renaming. + + # Command renaming (DEPRECATED). + # + # ------------------------------------------------------------------------ + # WARNING: avoid using this option if possible. Instead use ACLs to remove + # commands from the default user, and put them only in some admin user you + # create for administrative purposes. + # ------------------------------------------------------------------------ # # It is possible to change the name of dangerous commands in a shared # environment. For instance the CONFIG command may be renamed into something @@ -531,9 +801,9 @@ data: # # Please note that changing the name of commands that are logged into the # AOF file or transmitted to replicas may cause problems. - + ################################### CLIENTS #################################### - + # Set the max number of connected clients at the same time. By default # this limit is set to 10000 clients, however if the Redis server is not # able to configure the process file limit to allow for the specified limit @@ -544,9 +814,9 @@ data: # an error 'max number of clients reached'. # # maxclients 10000 - + ############################## MEMORY MANAGEMENT ################################ - + # Set a memory usage limit to the specified amount of bytes. # When the memory limit is reached Redis will try to remove keys # according to the eviction policy selected (see maxmemory-policy). @@ -571,15 +841,15 @@ data: # output buffers (but this is not needed if the policy is 'noeviction'). # # maxmemory - + # MAXMEMORY POLICY: how Redis will select what to remove when maxmemory - # is reached. You can select among five behaviors: + # is reached. You can select one from the following behaviors: # - # volatile-lru -> Evict using approximated LRU among the keys with an expire set. + # volatile-lru -> Evict using approximated LRU, only keys with an expire set. # allkeys-lru -> Evict any key using approximated LRU. - # volatile-lfu -> Evict using approximated LFU among the keys with an expire set. + # volatile-lfu -> Evict using approximated LFU, only keys with an expire set. # allkeys-lfu -> Evict any key using approximated LFU. - # volatile-random -> Remove a random key among the ones with an expire set. + # volatile-random -> Remove a random key having an expire set. # allkeys-random -> Remove a random key, any key. # volatile-ttl -> Remove the key with the nearest expire time (minor TTL) # noeviction -> Don't evict anything, just return an error on write operations. @@ -602,7 +872,7 @@ data: # The default is: # # maxmemory-policy noeviction - + # LRU, LFU and minimal TTL algorithms are not precise algorithms but approximated # algorithms (in order to save memory), so you can tune it for speed or # accuracy. For default Redis will check five keys and pick the one that was @@ -613,29 +883,46 @@ data: # true LRU but costs more CPU. 3 is faster but not very accurate. # # maxmemory-samples 5 - + # Starting from Redis 5, by default a replica will ignore its maxmemory setting # (unless it is promoted to master after a failover or manually). It means # that the eviction of keys will be just handled by the master, sending the # DEL commands to the replica as keys evict in the master side. # # This behavior ensures that masters and replicas stay consistent, and is usually - # what you want, however if your replica is writable, or you want the replica to have - # a different memory setting, and you are sure all the writes performed to the - # replica are idempotent, then you may change this default (but be sure to understand - # what you are doing). + # what you want, however if your replica is writable, or you want the replica + # to have a different memory setting, and you are sure all the writes performed + # to the replica are idempotent, then you may change this default (but be sure + # to understand what you are doing). # # Note that since the replica by default does not evict, it may end using more # memory than the one set via maxmemory (there are certain buffers that may - # be larger on the replica, or data structures may sometimes take more memory and so - # forth). So make sure you monitor your replicas and make sure they have enough - # memory to never hit a real out-of-memory condition before the master hits - # the configured maxmemory setting. + # be larger on the replica, or data structures may sometimes take more memory + # and so forth). So make sure you monitor your replicas and make sure they + # have enough memory to never hit a real out-of-memory condition before the + # master hits the configured maxmemory setting. # # replica-ignore-maxmemory yes - + + # Redis reclaims expired keys in two ways: upon access when those keys are + # found to be expired, and also in background, in what is called the + # "active expire key". The key space is slowly and interactively scanned + # looking for expired keys to reclaim, so that it is possible to free memory + # of keys that are expired and will never be accessed again in a short time. + # + # The default effort of the expire cycle will try to avoid having more than + # ten percent of expired keys still in memory, and will try to avoid consuming + # more than 25% of total memory and to add latency to the system. However + # it is possible to increase the expire "effort" that is normally set to + # "1", to a greater value, up to the value "10". At its maximum value the + # system will use more CPU, longer cycles (and technically may introduce + # more latency), and will tollerate less already expired keys still present + # in the system. It's a tradeoff betweeen memory, CPU and latecy. + # + # active-expire-effort 1 + ############################# LAZY FREEING #################################### - + # Redis has two primitives to delete keys. One is called DEL and is a blocking # deletion of the object. It means that the server stops processing new commands # in order to reclaim all the memory associated with an object in a synchronous @@ -676,15 +963,68 @@ data: # In all the above cases the default is to delete objects in a blocking way, # like if DEL was called. However you can configure each case specifically # in order to instead release memory in a non-blocking way like if UNLINK - # was called, using the following configuration directives: - + # was called, using the following configuration directives. + lazyfree-lazy-eviction no lazyfree-lazy-expire no lazyfree-lazy-server-del no replica-lazy-flush no - + + # It is also possible, for the case when to replace the user code DEL calls + # with UNLINK calls is not easy, to modify the default behavior of the DEL + # command to act exactly like UNLINK, using the following configuration + # directive: + + lazyfree-lazy-user-del no + + ################################ THREADED I/O ################################# + + # Redis is mostly single threaded, however there are certain threaded + # operations such as UNLINK, slow I/O accesses and other things that are + # performed on side threads. + # + # Now it is also possible to handle Redis clients socket reads and writes + # in different I/O threads. Since especially writing is so slow, normally + # Redis users use pipelining in order to speedup the Redis performances per + # core, and spawn multiple instances in order to scale more. Using I/O + # threads it is possible to easily speedup two times Redis without resorting + # to pipelining nor sharding of the instance. + # + # By default threading is disabled, we suggest enabling it only in machines + # that have at least 4 or more cores, leaving at least one spare core. + # Using more than 8 threads is unlikely to help much. We also recommend using + # threaded I/O only if you actually have performance problems, with Redis + # instances being able to use a quite big percentage of CPU time, otherwise + # there is no point in using this feature. + # + # So for instance if you have a four cores boxes, try to use 2 or 3 I/O + # threads, if you have a 8 cores, try to use 6 threads. In order to + # enable I/O threads use the following configuration directive: + # + # io-threads 4 + # + # Setting io-threads to 1 will just use the main thread as usually. + # When I/O threads are enabled, we only use threads for writes, that is + # to thread the write(2) syscall and transfer the client buffers to the + # socket. However it is also possible to enable threading of reads and + # protocol parsing using the following configuration directive, by setting + # it to yes: + # + # io-threads-do-reads no + # + # Usually threading reads doesn't help much. + # + # NOTE 1: This configuration directive cannot be changed at runtime via + # CONFIG SET. Aso this feature currently does not work when SSL is + # enabled. + # + # NOTE 2: If you want to test the Redis speedup using redis-benchmark, make + # sure you also run the benchmark itself in threaded mode, using the + # --threads option to match the number of Redis theads, otherwise you'll not + # be able to notice the improvements. + ############################## APPEND ONLY MODE ############################### - + # By default Redis asynchronously dumps the dataset on disk. This mode is # good enough in many applications, but an issue with the Redis process or # a power outage may result into a few minutes of writes lost (depending on @@ -702,13 +1042,13 @@ data: # with the better durability guarantees. # # Please check http://redis.io/topics/persistence for more information. - + appendonly no - + # The name of the append only file (default: "appendonly.aof") - + appendfilename "appendonly.aof" - + # The fsync() call tells the Operating System to actually write data on disk # instead of waiting for more data in the output buffer. Some OS will really flush # data on disk, some other OS will just try to do it ASAP. @@ -731,11 +1071,11 @@ data: # http://antirez.com/post/redis-persistence-demystified.html # # If unsure, use "everysec". - + # appendfsync always appendfsync everysec # appendfsync no - + # When the AOF fsync policy is set to always or everysec, and a background # saving process (a background save or AOF log background rewriting) is # performing a lot of I/O against the disk, in some Linux configurations @@ -754,9 +1094,9 @@ data: # # If you have latency problems turn this to "yes". Otherwise leave it as # "no" that is the safest pick from the point of view of durability. - + no-appendfsync-on-rewrite no - + # Automatic rewrite of the append only file. # Redis is able to automatically rewrite the log file implicitly calling # BGREWRITEAOF when the AOF log size grows by the specified percentage. @@ -773,10 +1113,10 @@ data: # # Specify a percentage of zero in order to disable the automatic AOF # rewrite feature. - + auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb - + # An AOF file may be found to be truncated at the end during the Redis # startup process, when the AOF data gets loaded back into memory. # This may happen when the system where Redis is running @@ -800,7 +1140,7 @@ data: # Redis will try to read more data from the AOF file but not enough bytes # will be found. aof-load-truncated yes - + # When rewriting the AOF file, Redis is able to use an RDB preamble in the # AOF file for faster rewrites and recoveries. When this option is turned # on the rewritten AOF file is composed of two different stanzas: @@ -811,9 +1151,9 @@ data: # string and loads the prefixed RDB file, and continues loading the AOF # tail. aof-use-rdb-preamble yes - + ################################ LUA SCRIPTING ############################### - + # Max execution time of a Lua script in milliseconds. # # If the maximum execution time is reached Redis will log that a script is @@ -829,15 +1169,15 @@ data: # # Set it to 0 or a negative value for unlimited execution without warnings. lua-time-limit 5000 - + ################################ REDIS CLUSTER ############################### - + # Normal Redis instances can't be part of a Redis Cluster; only nodes that are # started as cluster nodes can. In order to start a Redis instance as a # cluster node enable the cluster support uncommenting the following: # # cluster-enabled yes - + # Every cluster node has a cluster configuration file. This file is not # intended to be edited by hand. It is created and updated by Redis nodes. # Every Redis Cluster node requires a different cluster configuration file. @@ -845,13 +1185,13 @@ data: # overlapping cluster configuration file names. # # cluster-config-file nodes-6379.conf - + # Cluster node timeout is the amount of milliseconds a node must be unreachable # for it to be considered in failure state. # Most other internal time limits are multiple of the node timeout. # # cluster-node-timeout 15000 - + # A replica of a failing master will avoid to start a failover if its data # looks too old. # @@ -896,7 +1236,7 @@ data: # the cluster will always be able to continue. # # cluster-replica-validity-factor 10 - + # Cluster replicas are able to migrate to orphaned masters, that are masters # that are left without working replicas. This improves the cluster ability # to resist to failures as otherwise an orphaned master can't be failed over @@ -915,7 +1255,7 @@ data: # in production. # # cluster-migration-barrier 1 - + # By default Redis Cluster nodes stop accepting queries if they detect there # is at least an hash slot uncovered (no available node is serving it). # This way if the cluster is partially down (for example a range of hash slots @@ -928,7 +1268,7 @@ data: # option to no. # # cluster-require-full-coverage yes - + # This option, when set to yes, prevents replicas from trying to failover its # master during master failures. However the master can still perform a # manual failover, if forced to do so. @@ -938,12 +1278,28 @@ data: # in the case of a total DC failure. # # cluster-replica-no-failover no - + + # This option, when set to yes, allows nodes to serve read traffic while the + # the cluster is in a down state, as long as it believes it owns the slots. + # + # This is useful for two cases. The first case is for when an application + # doesn't require consistency of data during node failures or network partitions. + # One example of this is a cache, where as long as the node has the data it + # should be able to serve it. + # + # The second use case is for configurations that don't meet the recommended + # three shards but want to enable cluster mode and scale later. A + # master outage in a 1 or 2 shard configuration causes a read/write outage to the + # entire cluster without this option set, with it set there is only a write outage. + # Without a quorum of masters, slot ownership will not change automatically. + # + # cluster-allow-reads-when-down no + # In order to setup your cluster make sure to read the documentation # available at http://redis.io web site. - + ########################## CLUSTER DOCKER/NAT support ######################## - + # In certain deployments, Redis Cluster nodes address discovery fails, because # addresses are NAT-ted or because ports are forwarded (the typical case is # Docker and other containers). @@ -974,9 +1330,9 @@ data: # cluster-announce-ip 10.1.1.5 # cluster-announce-port 6379 # cluster-announce-bus-port 6380 - + ################################## SLOW LOG ################################### - + # The Redis Slow Log is a system to log queries that exceeded a specified # execution time. The execution time does not include the I/O operations # like talking with the client, sending the reply and so forth, @@ -989,18 +1345,18 @@ data: # command to get logged, and the other parameter is the length of the # slow log. When a new command is logged the oldest one is removed from the # queue of logged commands. - + # The following time is expressed in microseconds, so 1000000 is equivalent # to one second. Note that a negative number disables the slow log, while # a value of zero forces the logging of every command. slowlog-log-slower-than 10000 - + # There is no limit to this length. Just be aware that it will consume memory. # You can reclaim memory used by the slow log with SLOWLOG RESET. slowlog-max-len 128 - + ################################ LATENCY MONITOR ############################## - + # The Redis latency monitoring subsystem samples different operations # at runtime in order to collect data related to possible sources of # latency of a Redis instance. @@ -1019,9 +1375,9 @@ data: # monitoring can easily be enabled at runtime using the command # "CONFIG SET latency-monitor-threshold " if needed. latency-monitor-threshold 0 - + ############################# EVENT NOTIFICATION ############################## - + # Redis can notify Pub/Sub clients about events happening in the key space. # This feature is documented at http://redis.io/topics/notifications # @@ -1045,7 +1401,11 @@ data: # z Sorted set commands # x Expired events (events generated every time a key expires) # e Evicted events (events generated when a key is evicted for maxmemory) - # A Alias for g$lshzxe, so that the "AKE" string means all the events. + # t Stream commands + # m Key-miss events (Note: It is not included in the 'A' class) + # A Alias for g$lshzxet, so that the "AKE" string means all the events + # (Except key-miss events which are excluded from 'A' due to their + # unique nature). # # The "notify-keyspace-events" takes as argument a string that is composed # of zero or multiple characters. The empty string means that notifications @@ -1065,15 +1425,70 @@ data: # this feature and the feature has some overhead. Note that if you don't # specify at least one of K or E, no events will be delivered. notify-keyspace-events "" - + + ############################### GOPHER SERVER ################################# + + # Redis contains an implementation of the Gopher protocol, as specified in + # the RFC 1436 (https://www.ietf.org/rfc/rfc1436.txt). + # + # The Gopher protocol was very popular in the late '90s. It is an alternative + # to the web, and the implementation both server and client side is so simple + # that the Redis server has just 100 lines of code in order to implement this + # support. + # + # What do you do with Gopher nowadays? Well Gopher never *really* died, and + # lately there is a movement in order for the Gopher more hierarchical content + # composed of just plain text documents to be resurrected. Some want a simpler + # internet, others believe that the mainstream internet became too much + # controlled, and it's cool to create an alternative space for people that + # want a bit of fresh air. + # + # Anyway for the 10nth birthday of the Redis, we gave it the Gopher protocol + # as a gift. + # + # --- HOW IT WORKS? --- + # + # The Redis Gopher support uses the inline protocol of Redis, and specifically + # two kind of inline requests that were anyway illegal: an empty request + # or any request that starts with "/" (there are no Redis commands starting + # with such a slash). Normal RESP2/RESP3 requests are completely out of the + # path of the Gopher protocol implementation and are served as usually as well. + # + # If you open a connection to Redis when Gopher is enabled and send it + # a string like "/foo", if there is a key named "/foo" it is served via the + # Gopher protocol. + # + # In order to create a real Gopher "hole" (the name of a Gopher site in Gopher + # talking), you likely need a script like the following: + # + # https://github.com/antirez/gopher2redis + # + # --- SECURITY WARNING --- + # + # If you plan to put Redis on the internet in a publicly accessible address + # to server Gopher pages MAKE SURE TO SET A PASSWORD to the instance. + # Once a password is set: + # + # 1. The Gopher server (when enabled, not by default) will still serve + # content via Gopher. + # 2. However other commands cannot be called before the client will + # authenticate. + # + # So use the 'requirepass' option to protect your instance. + # + # To enable Gopher support uncomment the following line and set + # the option from no (the default) to yes. + # + # gopher-enabled no + ############################### ADVANCED CONFIG ############################### - + # Hashes are encoded using a memory efficient data structure when they have a # small number of entries, and the biggest entry does not exceed a given # threshold. These thresholds can be configured using the following directives. hash-max-ziplist-entries 512 hash-max-ziplist-value 64 - + # Lists are also encoded in a special way to save a lot of space. # The number of entries allowed per internal list node can be specified # as a fixed maximum size or a maximum number of elements. @@ -1088,7 +1503,7 @@ data: # The highest performing option is usually -2 (8 Kb size) or -1 (4 Kb size), # but if your use case is unique, adjust the settings as necessary. list-max-ziplist-size -2 - + # Lists may also be compressed. # Compress depth is the number of quicklist ziplist nodes from *each* side of # the list to *exclude* from compression. The head and tail of the list @@ -1104,20 +1519,20 @@ data: # 3: [head]->[next]->[next]->node->node->...->node->[prev]->[prev]->[tail] # etc. list-compress-depth 0 - + # Sets have a special encoding in just one case: when a set is composed # of just strings that happen to be integers in radix 10 in the range # of 64 bit signed integers. # The following configuration setting sets the limit in the size of the # set in order to use this special memory saving encoding. set-max-intset-entries 512 - + # Similarly to hashes and lists, sorted sets are also specially encoded in # order to save a lot of space. This encoding is only used when the length and # elements of a sorted set are below the following limits: zset-max-ziplist-entries 128 zset-max-ziplist-value 64 - + # HyperLogLog sparse representation bytes limit. The limit includes the # 16 bytes header. When an HyperLogLog using the sparse representation crosses # this limit, it is converted into the dense representation. @@ -1131,7 +1546,7 @@ data: # ~ 10000 when CPU is not a concern, but space is, and the data set is # composed of many HyperLogLogs with cardinality in the 0 - 15000 range. hll-sparse-max-bytes 3000 - + # Streams macro node max size / items. The stream data structure is a radix # tree of big nodes that encode multiple items inside. Using this configuration # it is possible to configure how big a single node can be in bytes, and the @@ -1142,7 +1557,7 @@ data: # value. stream-node-max-bytes 4096 stream-node-max-entries 100 - + # Active rehashing uses 1 millisecond every 100 milliseconds of CPU time in # order to help rehashing the main Redis hash table (the one mapping top-level # keys to values). The hash table implementation Redis uses (see dict.c) @@ -1162,7 +1577,7 @@ data: # use "activerehashing yes" if you don't have such hard requirements but # want to free memory asap when possible. activerehashing yes - + # The client output buffer limits can be used to force disconnection of clients # that are not reading data from the server fast enough for some reason (a # common reason is that a Pub/Sub client can't consume messages as fast as the @@ -1199,7 +1614,7 @@ data: client-output-buffer-limit normal 0 0 0 client-output-buffer-limit replica 256mb 64mb 60 client-output-buffer-limit pubsub 32mb 8mb 60 - + # Client query buffers accumulate new commands. They are limited to a fixed # amount by default in order to avoid that a protocol desynchronization (for # instance due to a bug in the client) will lead to unbound memory usage in @@ -1207,13 +1622,13 @@ data: # needs, such us huge multi/exec requests or alike. # # client-query-buffer-limit 1gb - + # In the Redis protocol, bulk requests, that are, elements representing single # strings, are normally limited ot 512 mb. However you can change this limit # here. # # proto-max-bulk-len 512mb - + # Redis calls an internal function to perform many background tasks, like # closing connections of clients in timeout, purging expired keys that are # never requested, and so forth. @@ -1230,7 +1645,7 @@ data: # a good idea. Most users should use the default of 10 and raise this up to # 100 only in environments where very low latency is required. hz 10 - + # Normally it is useful to have an HZ value which is proportional to the # number of clients connected. This is useful in order, for instance, to # avoid too many clients are processed for each background task invocation @@ -1240,25 +1655,25 @@ data: # offers, and enables by default, the ability to use an adaptive HZ value # which will temporary raise when there are many connected clients. # - # When dynamic HZ is enabled, the actual configured HZ will be used as + # When dynamic HZ is enabled, the actual configured HZ will be used # as a baseline, but multiples of the configured HZ value will be actually # used as needed once more clients are connected. In this way an idle # instance will use very little CPU time while a busy instance will be # more responsive. dynamic-hz yes - + # When a child rewrites the AOF file, if the following option is enabled # the file will be fsync-ed every 32 MB of data generated. This is useful # in order to commit the file to the disk more incrementally and avoid # big latency spikes. aof-rewrite-incremental-fsync yes - + # When redis saves RDB file, if the following option is enabled # the file will be fsync-ed every 32 MB of data generated. This is useful # in order to commit the file to the disk more incrementally and avoid # big latency spikes. rdb-save-incremental-fsync yes - + # Redis LFU eviction (see maxmemory setting) can be tuned. However it is a good # idea to start with the default settings and only change them after investigating # how to improve the performances and how the keys LFU change over time, which @@ -1310,13 +1725,9 @@ data: # # lfu-log-factor 10 # lfu-decay-time 1 - + ########################### ACTIVE DEFRAGMENTATION ####################### # - # WARNING THIS FEATURE IS EXPERIMENTAL. However it was stress tested - # even in production and manually tested by multiple engineers for some - # time. - # # What is active defragmentation? # ------------------------------- # @@ -1354,28 +1765,58 @@ data: # The configuration parameters are able to fine tune the behavior of the # defragmentation process. If you are not sure about what they mean it is # a good idea to leave the defaults untouched. - + # Enabled active defragmentation - # activedefrag yes - + # activedefrag no + # Minimum amount of fragmentation waste to start active defrag # active-defrag-ignore-bytes 100mb - + # Minimum percentage of fragmentation to start active defrag # active-defrag-threshold-lower 10 - + # Maximum percentage of fragmentation at which we use maximum effort # active-defrag-threshold-upper 100 - - # Minimal effort for defrag in CPU percentage - # active-defrag-cycle-min 5 - - # Maximal effort for defrag in CPU percentage - # active-defrag-cycle-max 75 - + + # Minimal effort for defrag in CPU percentage, to be used when the lower + # threshold is reached + # active-defrag-cycle-min 1 + + # Maximal effort for defrag in CPU percentage, to be used when the upper + # threshold is reached + # active-defrag-cycle-max 25 + # Maximum number of set/hash/zset/list fields that will be processed from # the main dictionary scan # active-defrag-max-scan-fields 1000 + + # Jemalloc background thread for purging will be enabled by default + jemalloc-bg-thread yes + + # It is possible to pin different threads and processes of Redis to specific + # CPUs in your system, in order to maximize the performances of the server. + # This is useful both in order to pin different Redis threads in different + # CPUs, but also in order to make sure that multiple Redis instances running + # in the same host will be pinned to different CPUs. + # + # Normally you can do this using the "taskset" command, however it is also + # possible to this via Redis configuration directly, both in Linux and FreeBSD. + # + # You can pin the server/IO threads, bio threads, aof rewrite child process, and + # the bgsave child process. The syntax to specify the cpu list is the same as + # the taskset command: + # + # Set redis server/io threads to cpu affinity 0,2,4,6: + # server_cpulist 0-7:2 + # + # Set bio threads to cpu affinity 1,3: + # bio_cpulist 1,3 + # + # Set aof rewrite child process to cpu affinity 8,9,10,11: + # aof_rewrite_cpulist 8-11 + # + # Set bgsave child process to cpu affinity 1,10,11 + # bgsave_cpulist 1,10-11 {{- if .Values.configmap }} {{- include "common.tplvalues.render" (dict "value" .Values.configmap "context" $) | nindent 4 }} {{- end }} diff --git a/bitnami/redis-cluster/templates/init-cluster.yaml b/bitnami/redis-cluster/templates/init-cluster.yaml index 24830e6517..6fa392ae75 100644 --- a/bitnami/redis-cluster/templates/init-cluster.yaml +++ b/bitnami/redis-cluster/templates/init-cluster.yaml @@ -27,11 +27,35 @@ spec: /entrypoint.sh /run.sh {{- end }} env: + - name: REDIS_TLS_ENABLED + value: {{ ternary "yes" "no" .Values.tls.enabled | quote }} + {{- if .Values.tls.enabled }} + - 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 }} + {{- end }} {{- if .Values.cluster.externalAccess.enabled }} - - name: REDIS_PORT - value: {{ .Values.cluster.externalAccess.service.port | quote }} + {{- if .Values.tls.enabled }} + - name: REDIS_TLS_PORT {{- else }} - name: REDIS_PORT + {{- end }} + value: {{ .Values.cluster.externalAccess.service.port | quote }} + {{- else }} + {{- if .Values.tls.enabled }} + - name: REDIS_TLS_PORT + {{- else }} + - name: REDIS_PORT + {{- end }} value: {{ .Values.redisPort | quote }} - name: REDIS_NODES value: "{{ $count := .Values.cluster.nodes | int }}{{ range $i, $v := until $count }}{{ include "redis-cluster.fullname" $ }}-{{ $i }}.{{ template "redis-cluster.fullname" $ }}-headless {{ end }}" @@ -47,5 +71,17 @@ spec: value: "yes" - name: REDIS_CLUSTER_REPLICAS value: {{ .Values.cluster.replicas | quote }} + {{- if .Values.tls.enabled }} + volumeMounts: + - name: redis-certificates + mountPath: /opt/bitnami/redis/certs + readOnly: true + {{- end }} restartPolicy: OnFailure + {{- if .Values.tls.enabled }} + volumes: + - name: redis-certificates + secret: + secretName: {{ required "A secret containing the certificates for the TLS traffic is required when TLS in enabled" .Values.tls.certificatesSecret }} + {{- end }} {{- end }} diff --git a/bitnami/redis-cluster/templates/redis-statefulset.yaml b/bitnami/redis-cluster/templates/redis-statefulset.yaml index 3e2b533474..6d316e6a65 100644 --- a/bitnami/redis-cluster/templates/redis-statefulset.yaml +++ b/bitnami/redis-cluster/templates/redis-statefulset.yaml @@ -123,8 +123,27 @@ spec: {{- end }} - name: REDIS_AOF_ENABLED value: {{ .Values.useAOFPersistence | quote }} + - name: REDIS_TLS_ENABLED + value: {{ ternary "yes" "no" .Values.tls.enabled | quote }} + {{- if .Values.tls.enabled }} + - name: REDIS_TLS_PORT + value: {{ .Values.redisPort | 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.redisPort | quote }} + {{- end }} {{- if .Values.extraEnvVars }} {{- include "common.tplvalues.render" ( dict "value" .Values.extraEnvVars "context" $ ) | nindent 8 }} {{- end }} @@ -189,6 +208,11 @@ spec: 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.extraVolumeMounts }} {{- include "common.tplvalues.render" ( dict "value" .Values.extraVolumeMounts "context" $ ) | nindent 8 }} {{- end }} @@ -218,11 +242,22 @@ spec: - 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" . }} + {{- end }} 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 }} ports: - name: http-metrics containerPort: 9121 @@ -300,6 +335,12 @@ spec: {{- if .Values.extraVolumes }} {{- include "common.tplvalues.render" ( dict "value" .Values.extraVolumes "context" $ ) | nindent 6 }} {{- end }} + {{- if .Values.tls.enabled }} + - name: redis-certificates + secret: + secretName: {{ required "A secret containing the certificates for the TLS traffic is required when TLS in enabled" .Values.tls.certificatesSecret }} + defaultMode: 256 + {{- end }} {{- if .Values.persistence.enabled }} volumeClaimTemplates: - metadata: diff --git a/bitnami/redis-cluster/templates/scripts-configmap.yaml b/bitnami/redis-cluster/templates/scripts-configmap.yaml index e257baa658..c70140747d 100644 --- a/bitnami/redis-cluster/templates/scripts-configmap.yaml +++ b/bitnami/redis-cluster/templates/scripts-configmap.yaml @@ -15,7 +15,15 @@ data: timeout -s 9 $1 \ redis-cli \ -h localhost \ +{{- if .Values.tls.enabled }} + -p $REDIS_TLS_PORT \ + --tls \ + --cert {{ template "redis-cluster.tlsCert" . }} \ + --key {{ template "redis-cluster.tlsCertKey" . }} \ + --cacert {{ template "redis-cluster.tlsCACert" . }} \ +{{- else }} -p $REDIS_PORT \ +{{- end }} ping ) if [ "$response" != "PONG" ]; then @@ -33,7 +41,15 @@ data: timeout -s 9 $1 \ redis-cli \ -h localhost \ +{{- if .Values.tls.enabled }} + -p $REDIS_TLS_PORT \ + --tls \ + --cert {{ template "redis-cluster.tlsCert" . }} \ + --key {{ template "redis-cluster.tlsCertKey" . }} \ + --cacert {{ template "redis-cluster.tlsCACert" . }} \ +{{- else }} -p $REDIS_PORT \ +{{- end }} ping ) if [ "$response" != "PONG" ] && [ "$response" != "LOADING Redis is loading the dataset in memory" ]; then diff --git a/bitnami/redis-cluster/templates/update-cluster.yaml b/bitnami/redis-cluster/templates/update-cluster.yaml index 9cf1a9f079..5add66c7cf 100644 --- a/bitnami/redis-cluster/templates/update-cluster.yaml +++ b/bitnami/redis-cluster/templates/update-cluster.yaml @@ -25,30 +25,54 @@ spec: . /opt/bitnami/scripts/libos.sh {{- if .Values.cluster.externalAccess.enabled }} for nodeIp in $(echo "{{ .Values.cluster.update.newExternalIPs }}" | cut -d [ -f2 | cut -d ] -f 1 ); do + {{- if .Values.tls.enabled }} + while [[ $(redis-cli -h "$nodeIp" -p "$REDIS_TLS_PORT" --tls --cert ${REDIS_TLS_CERT_FILE} --key ${REDIS_TLS_KEY_FILE} --cacert ${REDIS_TLS_CA_FILE} ping) != 'PONG' ]]; do + {{- else }} while [[ $(redis-cli -h "$nodeIp" -p "$REDIS_PORT" ping) != 'PONG' ]]; do + {{- end }} echo "Node $nodeIp not ready, waiting for all the nodes to be ready..." sleep 5 done + {{- if .Values.tls.enabled }} + redis-cli --cluster --tls --cert ${REDIS_TLS_CERT_FILE} --key ${REDIS_TLS_KEY_FILE} --cacert ${REDIS_TLS_CA_FILE} add-node "${nodeIp}:${REDIS_TLS_PORT}" "{{ index .Values.cluster.externalAccess.service.loadBalancerIP 0 }}:${REDIS_TLS_PORT}" + {{- else }} redis-cli --cluster add-node "${nodeIp}:${REDIS_PORT}" "{{ index .Values.cluster.externalAccess.service.loadBalancerIP 0 }}:${REDIS_PORT}" + {{- end }} done {{- else }} for node in $(seq $((1+{{ .Values.cluster.update.currentNumberOfNodes }})) {{ .Values.cluster.nodes }}); do new_node_index="$(($node - 1))" new_node_ip=$(wait_for_dns_lookup {{ template "redis-cluster.fullname" . }}-"$new_node_index".{{ template "redis-cluster.fullname" . }}-headless 120 5) + {{- if .Values.tls.enabled }} + while [[ $(redis-cli -h "$new_node_ip" -p "$REDIS_TLS_PORT" --tls --cert ${REDIS_TLS_CERT_FILE} --key ${REDIS_TLS_KEY_FILE} --cacert ${REDIS_TLS_CA_FILE} ping) != 'PONG' ]]; do + {{- else }} while [[ $(redis-cli -h "$new_node_ip" -p "$REDIS_PORT" ping) != 'PONG' ]]; do + {{- end }} echo "Node $new_node_ip not ready, waiting for all the nodes to be ready..." sleep 5 done firstNodeIp=$(wait_for_dns_lookup {{ template "redis-cluster.fullname" . }}-0.{{ template "redis-cluster.fullname" . }}-headless 120 5) + {{- if .Values.tls.enabled }} + redis-cli --cluster add-node --tls --cert ${REDIS_TLS_CERT_FILE} --key ${REDIS_TLS_KEY_FILE} --cacert ${REDIS_TLS_CA_FILE} "${new_node_ip}:${REDIS_TLS_PORT}" "${firstNodeIp}:${REDIS_TLS_PORT}" + {{- else }} redis-cli --cluster add-node "${new_node_ip}:${REDIS_PORT}" "${firstNodeIp}:${REDIS_PORT}" + {{- end }} done {{- end }} env: {{- if .Values.cluster.externalAccess.enabled }} - - name: REDIS_PORT - value: {{ .Values.cluster.externalAccess.service.port | quote }} + {{- if .Values.tls.enabled }} + - name: REDIS_TLS_PORT {{- else }} - name: REDIS_PORT + {{- end }} + value: {{ .Values.cluster.externalAccess.service.port | quote }} + {{- else }} + {{- if .Values.tls.enabled }} + - name: REDIS_TLS_PORT + {{- else }} + - name: REDIS_PORT + {{- end }} value: {{ .Values.redisPort | quote }} {{- end }} {{- if .Values.usePassword }} @@ -58,5 +82,15 @@ spec: name: {{ template "redis-cluster.secretName" . }} key: {{ template "redis-cluster.secretPasswordKey" . }} {{- end }} + volumeMounts: + - name: redis-certificates + mountPath: /opt/bitnami/redis/certs + readOnly: true restartPolicy: OnFailure + {{- if .Values.tls.enabled }} + volumes: + - name: redis-certificates + secret: + secretName: {{ required "A secret containing the certificates for the TLS traffic is required when TLS in enabled" .Values.tls.certificatesSecret }} + {{- end }} {{- end }} diff --git a/bitnami/redis-cluster/values-production.yaml b/bitnami/redis-cluster/values-production.yaml index 142adf9bbc..ea3d96f85c 100644 --- a/bitnami/redis-cluster/values-production.yaml +++ b/bitnami/redis-cluster/values-production.yaml @@ -18,7 +18,7 @@ image: ## Bitnami Redis image tag ## ref: https://github.com/bitnami/bitnami-docker-redis#supported-tags-and-respective-dockerfile-links ## - tag: 6.0.5-debian-10-r0 + tag: 6.0.5-debian-10-r1 ## Specify a imagePullPolicy ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images @@ -199,6 +199,31 @@ useAOFPersistence: "yes" # Redis port redisPort: 6379 +## +## TLS configuration +## +tls: + # Enable TLS traffic + enabled: false + # + # Whether to require clients to authenticate or not. + authClients: true + # + # Name of the Secret that contains the certificates + certificatesSecret: + # + # Certificate filename + certFilename: + # + # Certificate Key filename + certKeyFilename: + # + # CA Certificate filename + certCAFilename: + # + # File containing DH params (in order to support DH based ciphers) + # dhParamsFilename: + ## ## Redis parameters ## diff --git a/bitnami/redis-cluster/values.yaml b/bitnami/redis-cluster/values.yaml index 42df159116..037dfabc50 100644 --- a/bitnami/redis-cluster/values.yaml +++ b/bitnami/redis-cluster/values.yaml @@ -18,7 +18,7 @@ image: ## Bitnami Redis image tag ## ref: https://github.com/bitnami/bitnami-docker-redis#supported-tags-and-respective-dockerfile-links ## - tag: 6.0.5-debian-10-r0 + tag: 6.0.5-debian-10-r1 ## Specify a imagePullPolicy ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images @@ -199,6 +199,31 @@ useAOFPersistence: "yes" # Redis port redisPort: 6379 +## +## TLS configuration +## +tls: + # Enable TLS traffic + enabled: false + # + # Whether to require clients to authenticate or not. + authClients: true + # + # Name of the Secret that contains the certificates + certificatesSecret: + # + # Certificate filename + certFilename: + # + # Certificate Key filename + certKeyFilename: + # + # CA Certificate filename + certCAFilename: + # + # File containing DH params (in order to support DH based ciphers) + # dhParamsFilename: + ## ## Redis parameters ##