[bitnami/etcd] Support auto disaster recovery

This commit is contained in:
juan131
2019-06-21 11:46:15 -05:00
parent e18f1c7c6c
commit 860a00f111
12 changed files with 537 additions and 222 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
apiVersion: v1
name: etcd
version: 2.3.3
version: 3.0.0
appVersion: 3.3.13
description: etcd is a distributed key value store that provides a reliable way to store data across a cluster of machines
keywords:
+89 -39
View File
@@ -45,13 +45,13 @@ The command removes all the Kubernetes components associated with the chart and
The following tables lists the configurable parameters of the etcd chart and their default values.
| Parameter | Description | Default |
| Parameter | Description | Default |
|---------------------------------------|----------------------------------------------------------------------------------------------------------|------------------------------------------------------------------- |
| `global.imageRegistry` | Global Docker image registry | `nil` |
| `global.imagePullSecrets` | Global Docker registry secret names as an array | `[]` (does not add image pull secrets to deployed pods) |
| `image.registry` | etcd image registry | `docker.io` |
| `image.repository` | etcd Image name | `bitnami/etcd` |
| `image.tag` | etcd Image tag | `{TAG_NAME}` |
| `image.repository` | etcd image name | `bitnami/etcd` |
| `image.tag` | etcd image tag | `{TAG_NAME}` |
| `image.pullPolicy` | etcd image pull policy | `IfNotPresent` |
| `image.pullSecrets` | Specify docker-registry secret names as an array | `[]` (does not add image pull secrets to deployed pods) |
| `image.debug` | Specify if debug values should be set | `false` |
@@ -77,48 +77,53 @@ The following tables lists the configurable parameters of the etcd chart and the
| `securityContext.enabled` | Enable security context | `true` |
| `securityContext.fsGroup` | Group ID for the container | `1001` |
| `securityContext.runAsUser` | User ID for the container | `1001` |
| `service.dnsBase` | Kubernetes service cluster dns base name | svc.cluster.local |
| `service.dnsBase` | Kubernetes service cluster dns base name | `svc.cluster.local` |
| `service.type` | Kubernetes Service type | `ClusterIP` |
| `service.port` | etcd client port | `2379` |
| `service.nodePort` | Port to bind to for NodePort service type (client port) | `nil` |
| `service.peerPort` | etcd peer port | `2380` |
| `service.peerNodePort` | Port to bind to for NodePort service type (peer port) | `nil` |
| `service.annotations` | Annotations for etcd service | {} |
| `service.annotations` | Annotations for etcd service | `{}` |
| `service.loadBalancerIP` | loadBalancerIP if etcd service type is `LoadBalancer` | `nil` |
| `persistence.enabled` | Enable persistence using PVC | `true` |
| `persistence.storageClass` | PVC Storage Class for etcd volume | `nil` |
| `persistence.accessMode` | PVC Access Mode for etcd volume | `ReadWriteOnce` |
| `persistence.size` | PVC Storage Request for etcd volume | `8Gi` |
| `persistence.annotations` | Annotations for the PVC | `{}` |
| `affinity` | Affinity and AntiAffinity rules for pod assignment | `{}` |
| `nodeSelector` | Node labels for pod assignment | `{}` |
| `tolerations` | Toleration labels for pod assignment | `[]` |
| `resources` | CPU/Memory resource requests/limits | Memory: `256Mi`, CPU: `250m` |
| `livenessProbe.enabled` | Turn on and off liveness probe | `true` |
| `livenessProbe.initialDelaySeconds` | Delay before liveness probe is initiated | 10 |
| `livenessProbe.periodSeconds` | How often to perform the probe | 10 |
| `livenessProbe.timeoutSeconds` | When the probe times out | 5 |
| `livenessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded. | 2 |
| `livenessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed | 1 |
| `readinessProbe.enabled` | Turn on and off readiness probe | `true` |
| `readinessProbe.initialDelaySeconds` | Delay before liveness probe is initiated | 5 |
| `readinessProbe.periodSeconds` | How often to perform the probe | 10 |
| `readinessProbe.timeoutSeconds` | When the probe times out | 5 |
| `readinessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded. | 6 |
| `readinessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed | 1 |
| `podAnnotations` | Annotations to be added to pods | {} |
| `metrics.enabled` | Enable prometheus to access etcd metrics endpoint | `false` |
| `livenessProbe.enabled` | Turn on and off liveness probe | `true` |
| `livenessProbe.initialDelaySeconds` | Delay before liveness probe is initiated | `10` |
| `livenessProbe.periodSeconds` | How often to perform the probe | `10` |
| `livenessProbe.timeoutSeconds` | When the probe times out | `5` |
| `livenessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded. | `2` |
| `livenessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed | `1` |
| `readinessProbe.enabled` | Turn on and off readiness probe | `true` |
| `readinessProbe.initialDelaySeconds` | Delay before liveness probe is initiated | `15` |
| `readinessProbe.periodSeconds` | How often to perform the probe | `10` |
| `readinessProbe.timeoutSeconds` | When the probe times out | `5` |
| `readinessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded. | `6` |
| `readinessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed | `1` |
| `podAnnotations` | Annotations to be added to pods | `{}` |
| `nodeAffinity` | Node Affinity rules for pod assignment. The value is evaluated as a template. | `{}` |
| `podAffinity` | Affinity rules for pod assignment. The value is evaluated as a template. | `{}` |
| `podAntiAffinity` | Anti-Affinity rules for pod assignment. Allowed values: `soft` and `hard` | `soft` |
| `nodeSelector` | Node labels for pod assignment. The value is evaluated as a template. | `{}` |
| `tolerations` | Tolerations for pod assignment. The value is evaluated as a template. | `{}` |
| `metrics.enabled` | Enable Prometheus exporter to expose etcd metrics | `false` |
| `metrics.podAnnotations` | Annotations for enabling prometheus to access the metrics endpoint | {`prometheus.io/scrape: "true",prometheus.io/port: "2379"`} |
| `disasterRecovery.enabled` | Enable auto disaster recovery by periodically snapshotting the keyspace | `false` |
| `disasterRecovery.interval` | Interval (in seconds) to save snapshots | `300` |
| `disasterRecovery.size` | PVC Storage Request | `2Gi` |
| `disasterRecovery.storageClassName` | PVC Storage ClassName, choose a storageClassName with ReadWriteMany support | `nfs` |
Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example,
```console
$ helm install --name my-release \
--set auth.rootPassword=secretpassword bitnami/etcd
--set auth.rbac.rootPassword=secretpassword bitnami/etcd
```
The above command sets the etcd `etcd` account password to `secretpassword`. Additionally it creates a database named `my-database`.
The above command sets the etcd `root` account password to `secretpassword`.
Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example,
@@ -188,7 +193,7 @@ Bitnami will release a new chart updating its containers if a new version of the
In order to use custom configuration parameters, two options are available:
- Using environment variables: etcd allows setting environment variables that map to configuration settings. In order to set extra environment variables, use the `envVarsConfigMap` value to point to a ConfigMap that contains them. Example:
- Using environment variables: etcd allows setting environment variables that map to configuration settings. In order to set extra environment variables, use the `envVarsConfigMap` value to point to a ConfigMap that contains them. Example:
```console
$ cat << EOF > /tmp/configurationEnvVars.yaml
@@ -203,18 +208,32 @@ data:
EOF
$ kubectl create -f /tmp/configurationEnvVars.yaml
$ helm install bitnami/etcd --set envVarsConfigMap=etcd-env-vars
```
- Using a custom etcd.conf.yml: The etcd chart allows mounting a custom etcd.conf.yml file using the `configFileConfigMap` value. Example:
- Using a custom `etcd.conf.yml`: The etcd chart allows mounting a custom etcd.conf.yml file using the `configFileConfigMap` value. Example:
```console
$ kubectl create configmap etcd-conf --from-file=etcd.conf.yml
$ helm install bitnami/etcd --set configFileConfigMap=etcd-conf
```
## Production and horizontal scaling
The following repo contains the recommended production settings for etcd server in an alternative [values file](values-production.yaml). Please read carefully the comments in the values-production.yaml file to set up your environment.
```console
$ helm install --name my-release -f ./values-production.yaml bitnami/etcd
```
To horizontally scale this chart once it has been deployed:
```console
$ helm upgrade my-release bitnami/etcd \
-f ./values-production.yaml
--set statefulset.replicaCount=5
```
## Enable security for etcd
### Configure RBAC
@@ -223,11 +242,9 @@ In order to enable [Role-based access control for etcd](https://coreos.com/etcd/
```console
$ helm install --name my-release --set auth.rbac.enabled --set auth.rbac.rootPassword=YOUR-PASSWORD bitnami/etcd
```
The previous command will deploy etcd creating a `root` user with its associate `root` role with access to everything.
The rest of users will use the `guest` role and won't have permissions to do anything.
The previous command will deploy etcd creating a `root` user with its associate `root` role with access to everything. The rest of users will use the `guest` role and won't have permissions to do anything.
### Configure certificated for peer communication
@@ -235,10 +252,9 @@ In order to enable secure transport between peer nodes deploy the helm chart wit
```console
$ helm install --name my-release --set auth.peer.secureTransport=true --set auth.peer.useAutoTLS=true bitnami/etcd
```
### Configure certificates for client comminication
### Configure certificates for client communication
In order to enable secure transport between client and server you have to create a secret containing the cert and key files and the CA used to sign those client certificates.
@@ -252,22 +268,56 @@ Once the secret is created, you can deploy the helm chart with these options:
```console
$ helm install --name my-release --set auth.client.secureTransport=true --set auth.client.enableAuthentication=true --set auth.client.existingSecret=etcd-client-certs bitnami/etcd
```
> Ref: [etcd security model](https://coreos.com/etcd/docs/latest/op-guide/security.html)
>
> Ref: [Generate self-signed certificagtes for etcd](https://coreos.com/os/docs/latest/generate-self-signed-certificates.html)
## Persistence
## Persistence and Disaster recovery
The [Bitnami etcd](https://github.com/bitnami/bitnami-docker-etcd) image stores the etcd data at the `/bitnami/etcd` path of the container.
### Persistence
Persistent Volume Claims are used to keep the data across deployments. This is known to work in GCE, AWS, and minikube.
See the [Configuration](#configuration) section to configure the PVC or to disable persistence.
The [Bitnami etcd](https://github.com/bitnami/bitnami-docker-etcd) image stores the etcd data at the `/bitnami/etcd` path of the container. Persistent Volume Claims are used to keep the data across statefulsets. This is known to work in GCE, AWS, and Minikube. To enable persistence, deploy the helm chart with these options:
```console
$ helm install --name my-release bitnami/etcd \
--set persistence.enable=true \
--set persistence.size=8Gi
```
### Disaster recovery
You can enable auto disaster recovery by periodically snapshotting the keyspace. If the cluster permanently loses more than (N-1)/2 members, it tries to recover the cluster from a previous snapshot.
```console
$ helm install --name my-release bitnami/etcd \
--set persistence.enable=true \
--set disasterRecovery.enabled=true \
--set disasterRecovery.interval=300 \
--set disasterRecovery.size=2Gi \
--set disasterRecovery.storageClassName=nfs
```
> **Note**: Disaster recovery feature requires using volumes with ReadWriteMany access mode. For instance, you can use the stable/nfs-server-provisioner chart to provide NFS PVCs:
```console
$ helm install --name nfs-server-provisioner stable/nfs-server-provisioner \
--set persistence.enabled=true --set persistence.size=10Gi
```
## Upgrading
### To 3.0.0
Backwards compatibility is not guaranteed. The following notables changes were included:
- **etcdctl** uses v3 API.
- Adds support for auto disaster recovery.
- Labels are adapted to follow the Helm charts best practices.
To upgrade from previous charts versions, create a snapshot of the keyspace and restore it in a new etcd cluster. Only v3 API data can be restored.
### To 1.0.0
Backwards compatibility is not guaranteed unless you modify the labels used on the chart's deployments.
+22 -15
View File
@@ -4,7 +4,7 @@
WARNING
By specifying "service.type=LoadBalancer" and "allowNoneAuthentication=true" you
have most likely exposed the Redis service externally without any authentication
have most likely exposed the etcd service externally without any authentication
mechanism.
For security reasons, we strongly suggest that you switch to "ClusterIP" or
@@ -23,13 +23,13 @@ etcd can be accessed via port {{ .Values.service.port }} on the following DNS na
To set a key run the following command:
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "etcd.name" . }}" -o jsonpath="{.items[0].metadata.name}")
kubectl exec -it $POD_NAME -- etcdctl set /message Hello
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ template "etcd.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
kubectl exec -it $POD_NAME -c etcd -- etcdctl put /message Hello
To get a key run the following command:
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "etcd.name" . }}" -o jsonpath="{.items[0].metadata.name}")
kubectl exec -it $POD_NAME -- etcdctl get /message
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ template "etcd.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
kubectl exec -it $POD_NAME -c etcd -- etcdctl get /message
To connect to your etcd server from outside the cluster execute the following commands:
@@ -45,40 +45,47 @@ To connect to your etcd server from outside the cluster execute the following co
Watch the status with: 'kubectl get svc --namespace {{ .Release.Namespace }} -w {{ template "etcd.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "etcd.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo "etcd URL: http://$SERVICE_IP:2379/"
echo "etcd URL: http://$SERVICE_IP:{{ .Values.service.port }}/"
{{- else if contains "ClusterIP" .Values.service.type }}
kubectl port-forward --namespace {{ .Release.Namespace }} svc/{{ template "etcd.fullname" . }} 2379:2379 &
echo "etcd URL: http://127.0.0.1:2379"
kubectl port-forward --namespace {{ .Release.Namespace }} svc/{{ template "etcd.fullname" . }} {{ .Values.service.port }}:{{ .Values.service.port }} &
echo "etcd URL: http://127.0.0.1:{{ .Values.service.port }}"
{{- end }}
{{- if .Values.auth.rbac.enabled }}
{{ if .Values.auth.rbac.enabled }}
* As rbac is enabled you should add the flag `-u root:$ETCD_ROOT_PASSWORD` to the etcdctl commands. Export the password with this command:
* As rbac is enabled you should add the flag `--user root:$ETCD_ROOT_PASSWORD` to the etcdctl commands. Use the command below to export the password:
export ETCD_ROOT_PASSWORD=$(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "etcd.fullname" . }} -o jsonpath="{.data.etcd-root-password}" | base64 --decode)
{{ end }}
{{- end }}
{{- if .Values.auth.client.secureTransport }}
{{- if .Values.auth.client.useAutoTLS }}
* As TLS is enabled you should add the flag `--cert-file {{ template "etcd.dataDir" . }}/fixtures/client/cert.pem --key-file {{ template "etcd.dataDir" .}}/fixtures/client/key.pem` to the etcdctl commands.
{{- else }}
* As TLS is enabled you should add the flag `--cert-file /opt/bitnami/etcd/certs/client/cert.pem --key-file /opt/bitnami/etcd/certs/client/key.pem` to the etcdctl commands.
{{- end }}
* You should also export a proper etcdctl endpoint using the https schema. Eg.
export ETCDCTL_ENDPOINTS=https://{{ template "etcd.fullname" . }}-0:{{ .Values.service.port }}
{{- end }}
{{ if .Values.auth.client.enableAuthentication }}
* As TLS host authentication is enabled you should add the flag `--ca-file /opt/bitnami/etcd/certs/client/ca.crt` to the etcdctl commands.
{{- end }}
{{- if .Values.auth.client.enableAuthentication }}
* As TLS host authentication is enabled you should add the flag `--ca-file /opt/bitnami/etcd/certs/client/ca.crt` to the etcdctl commands.
{{- end }}
{{- if and (contains "bitnami/" .Values.image.repository) (not (.Values.image.tag | toString | regexFind "-r\\d+$|sha256:")) }}
WARNING: Rolling tag detected ({{ .Values.image.repository }}:{{ .Values.image.tag }}), please note that it is strongly recommended to avoid using rolling tags in a production environment.
+info https://docs.bitnami.com/containers/how-to/understand-rolling-tags-containers/
{{- end }}
{{ include "etcd.validateValues" . }}
+36 -3
View File
@@ -82,9 +82,9 @@ Return the proper etcd data dir
Return the proper etcdctl authentication options
*/}}
{{- define "etcd.authOptions" -}}
{{- $rbacOption := "-u root:$ETCD_ROOT_PASSWORD" -}}
{{- $certsOption := " --cert-file $ETCD_CERT_FILE --key-file $ETCD_KEY_FILE" -}}
{{- $caOption := " --ca-file $ETCD_TRUSTED_CA_FILE" -}}
{{- $rbacOption := "--user root:$ETCD_ROOT_PASSWORD" -}}
{{- $certsOption := " --cert=\"$ETCD_CERT_FILE\" --key=\"$ETCD_KEY_FILE\"" -}}
{{- $caOption := " --cacert=\"$ETCD_TRUSTED_CA_FILE\"" -}}
{{- if .Values.auth.rbac.enabled -}}
{{- printf "%s" $rbacOption -}}
{{- end -}}
@@ -138,3 +138,36 @@ imagePullSecrets:
{{- end }}
{{- end -}}
{{- end -}}
{{/*
Compile all warnings into a single message, and call fail.
*/}}
{{- define "etcd.validateValues" -}}
{{- $messages := list -}}
{{- $messages := append $messages (include "etcd.validateValues.disasterRecovery" .) -}}
{{- $messages := append $messages (include "etcd.validateValues.podAntiAffinity" .) -}}
{{- $messages := without $messages "" -}}
{{- $message := join "\n" $messages -}}
{{- if $message -}}
{{- printf "\nVALUES VALIDATION:\n%s" $message | fail -}}
{{- end -}}
{{- end -}}
{{/* Validate values of etcd - persistence must be enabled when disasterRecovery is enabled */}}
{{- define "etcd.validateValues.disasterRecovery" -}}
{{- if and .Values.disasterRecovery.enabled (not .Values.persistence.enabled) -}}
etcd: disasterRecovery
Persistence must be enabled when disasterRecovery is enabled!!
Please enable persistence (--set persistence.enabled=true)
{{- end -}}
{{- end -}}
{{/* Validate values of etcd - must provide a valid podAntiAffinity ("soft" or "hard") */}}
{{- define "etcd.validateValues.podAntiAffinity" -}}
{{- if and (ne .Values.podAntiAffinity "soft") (ne .Values.podAntiAffinity "hard") -}}
etcd: mode
Invalid podAntiAffinity selected. Valid values are "soft" and
"hard". Please set a valid mode (--set podAntiAffinity="xxxx")
{{- end -}}
{{- end -}}
@@ -0,0 +1,156 @@
{{- $replicaCount := int .Values.statefulset.replicaCount }}
{{- $clientPort := int .Values.service.port }}
{{- $peerPort := int .Values.service.peerPort }}
{{- $etcdAuthOptions := include "etcd.authOptions" . }}
{{- $etcdDataDir := include "etcd.dataDir" . }}
{{- $etcdFullname := include "etcd.fullname" . }}
{{- $releaseNamespace := .Release.Namespace }}
{{- $etcdHeadlessServiceName := printf "%s-%s" $etcdFullname "headless" }}
{{- $dnsBase := .Values.service.dnsBase }}
{{- $etcdPeerProtocol := include "etcd.peerProtocol" . }}
{{- $etcdClientProtocol := include "etcd.clientProtocol" . }}
apiVersion: v1
kind: ConfigMap
metadata:
labels:
app.kubernetes.io/name: {{ template "etcd.name" . }}
helm.sh/chart: {{ template "etcd.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
name: {{ template "etcd.fullname" . }}-scripts
data:
setup.sh: |-
#!/bin/bash
set -o errexit
set -o pipefail
set -o nounset
# Constants
HOSTNAME="$(hostname -s)"
AUTH_OPTIONS="{{ $etcdAuthOptions }}"
ETCDCTL_ENDPOINTS="{{range $i, $e := until $replicaCount }}{{ $etcdClientProtocol }}://{{ $etcdFullname }}-{{ $e }}.{{ $etcdHeadlessServiceName }}.{{ $releaseNamespace }}.{{ $dnsBase }}:{{ $clientPort }},{{ end }}"
# Remove the last comma "," introduced in the string
export ETCDCTL_ENDPOINTS="${ETCDCTL_ENDPOINTS::-1}"
# Functions
## Store member id for later member replacement
store_member_id() {
while ! etcdctl $AUTH_OPTIONS member list >/dev/null 2>&1; do sleep 1; done
etcdctl $AUTH_OPTIONS member list | grep "$HOSTNAME" | awk '{ print $1}' | awk -F "," '{ print $1}' > "$ETCD_DATA_DIR/member_id"
exit 0
}
## Configure RBAC
configure_rbac() {
# When there's more than one replica, we can assume the 1st member
# to be created is "{{ $etcdFullname }}-0" since a statefulset is used
if [[ -n "$ETCD_ROOT_PASSWORD" ]] && [[ "$HOSTNAME" == "{{ $etcdFullname }}-0" ]]; then
echo "==> Configuring RBAC authentication!"
etcd > /dev/null 2>&1 &
ETCD_PID=$!
while ! etcdctl member list >/dev/null 2>&1; do sleep 1; done
echo "$ETCD_ROOT_PASSWORD" | etcdctl user add root --interactive=false
etcdctl auth enable
kill "$ETCD_PID"
sleep 5
fi
}
if [[ ! -d "$ETCD_DATA_DIR" ]]; then
echo "==> Creating data dir..."
mkdir -p "$ETCD_DATA_DIR"
echo "==> There is no data at all. Initializing a new member of the cluster..."
store_member_id &
configure_rbac
else
echo "==> Detected data from previous deployments..."
if ! etcdctl $AUTH_OPTIONS endpoint status >/dev/null 2>&1; then
echo "==> Cluster not responding!!"
{{- if .Values.disasterRecovery.enabled }}
if [[ -f "/snapshots/db" ]]; then
echo "==> Restoring etcd cluster from snapshot..."
rm -rf $ETCD_DATA_DIR
etcdctl snapshot restore /snapshots/db \
--name $ETCD_NAME \
--data-dir $ETCD_DATA_DIR \
--initial-cluster $ETCD_INITIAL_CLUSTER \
--initial-cluster-token $ETCD_INITIAL_CLUSTER_TOKEN \
--initial-advertise-peer-urls $ETCD_INITIAL_ADVERTISE_PEER_URLS
store_member_id &
else
echo "==> There was no snapshot to perform data recovery!!"
exit 1
fi
{{- else }}
exit 1
{{- end }}
elif [[ -d "$ETCD_DATA_DIR/member/snap" ]] && [[ -f "$ETCD_DATA_DIR/member_id" ]]; then
echo "==> Updating member in existing cluster..."
etcdctl $AUTH_OPTIONS member update "$(cat "$ETCD_DATA_DIR/member_id")" --peer-urls="{{ $etcdPeerProtocol }}://${HOSTNAME}.{{ $etcdHeadlessServiceName }}.{{ .Release.Namespace }}.{{ $dnsBase }}:{{ $peerPort }}"
else
echo "==> Adding new member to existing cluster..."
etcdctl $AUTH_OPTIONS member add "$HOSTNAME" --peer-urls="{{ $etcdPeerProtocol }}://${HOSTNAME}.{{ $etcdHeadlessServiceName }}.{{ .Release.Namespace }}.{{ $dnsBase }}:{{ $peerPort }}" | grep "^ETCD_" > "$ETCD_DATA_DIR/new_member_envs"
sed -ie 's/^/export /' "$ETCD_DATA_DIR/new_member_envs"
echo "==> Loading env vars of existing cluster..."
source "$ETCD_DATA_DIR/new_member_envs"
store_member_id &
fi
fi
{{- if .Values.configFileConfigMap }}
exec etcd --config-file /opt/bitnami/etcd/conf/etcd.conf.yml
{{- else }}
exec etcd
{{- end }}
prestop-hook.sh: |-
#!/bin/bash
set -o errexit
set -o pipefail
set -o nounset
# Constants
HOSTNAME="$(hostname -s)"
AUTH_OPTIONS="{{ $etcdAuthOptions }}"
ETCDCTL_ENDPOINTS="{{range $i, $e := until $replicaCount }}{{ $etcdClientProtocol }}://{{ $etcdFullname }}-{{ $e }}.{{ $etcdHeadlessServiceName }}.{{ $releaseNamespace }}.{{ $dnsBase }}:{{ $clientPort }},{{ end }}"
# Remove the last comma "," introduced in the string
export ETCDCTL_ENDPOINTS="${ETCDCTL_ENDPOINTS::-1}"
etcdctl $AUTH_OPTIONS member remove "$(cat "$ETCD_DATA_DIR/member_id")" && rm -rf $ETCD_DATA_DIR/*
probes.sh: |-
#!/bin/bash
set -o errexit
set -o pipefail
set -o nounset
# Constants
AUTH_OPTIONS="{{ $etcdAuthOptions }}"
ETCDCTL_ENDPOINTS="{{range $i, $e := until $replicaCount }}{{ $etcdClientProtocol }}://{{ $etcdFullname }}-{{ $e }}.{{ $etcdHeadlessServiceName }}.{{ $releaseNamespace }}.{{ $dnsBase }}:{{ $clientPort }},{{ end }}"
# Remove the last comma "," introduced in the string
export ETCDCTL_ENDPOINTS="${ETCDCTL_ENDPOINTS::-1}"
etcdctl $AUTH_OPTIONS endpoint status >/dev/null 2>&1
{{- if .Values.disasterRecovery.enabled }}
sidecar.sh: |-
#!/bin/bash
set -o errexit
set -o pipefail
set -o nounset
# Constants
AUTH_OPTIONS="{{ $etcdAuthOptions }}"
ETCDCTL_ENDPOINTS="{{range $i, $e := until $replicaCount }}{{ $etcdClientProtocol }}://{{ $etcdFullname }}-{{ $e }}.{{ $etcdHeadlessServiceName }}.{{ $releaseNamespace }}.{{ $dnsBase }}:{{ $clientPort }},{{ end }}"
# Remove the last comma "," introduced in the string
export ETCDCTL_ENDPOINTS="${ETCDCTL_ENDPOINTS::-1}"
mkdir -p "/snapshots"
while true; do
if etcdctl $AUTH_OPTIONS endpoint status >/dev/null 2>&1; then
echo "Snapshotting the keyspace..."
etcdctl $AUTH_OPTIONS snapshot save "/snapshots/db"
fi
sleep {{ default "600" .Values.disasterRecovery.interval }}
done
{{- end }}
+5 -5
View File
@@ -4,10 +4,10 @@ kind: Secret
metadata:
name: {{ template "etcd.fullname" . }}
labels:
app: {{ template "etcd.name" . }}
chart: {{ template "etcd.chart" . }}
release: {{ .Release.Name | quote }}
heritage: {{ .Release.Service | quote }}
app.kubernetes.io/name: {{ template "etcd.name" . }}
helm.sh/chart: {{ template "etcd.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
type: Opaque
data:
{{- if .Values.auth.rbac.rootPassword }}
@@ -15,4 +15,4 @@ data:
{{ else }}
etcd-root-password: {{ randAlphaNum 10 | b64enc | quote }}
{{- end }}
{{- end }}
{{- end }}
+18
View File
@@ -0,0 +1,18 @@
{{- if .Values.disasterRecovery.enabled -}}
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: {{ template "etcd.fullname" . }}-snapshot
labels:
app.kubernetes.io/name: {{ template "etcd.name" . }}
helm.sh/chart: {{ template "etcd.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: {{ .Values.disasterRecovery.size | quote }}
storageClassName: nfs
{{- end -}}
+109 -130
View File
@@ -1,17 +1,17 @@
apiVersion: apps/v1beta2
kind: StatefulSet
metadata:
name: "{{ template "etcd.fullname" . }}"
name: {{ template "etcd.fullname" . }}
labels:
app: {{ template "etcd.name" . }}
chart: {{ template "etcd.chart" . }}
release: {{ .Release.Name | quote }}
heritage: {{ .Release.Service | quote }}
app.kubernetes.io/name: {{ template "etcd.name" . }}
helm.sh/chart: {{ template "etcd.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
spec:
selector:
matchLabels:
app: {{ template "etcd.name" . }}
release: "{{ .Release.Name }}"
app.kubernetes.io/name: {{ template "etcd.name" . }}
app.kubernetes.io/instance: {{ .Release.Name | quote }}
serviceName: {{ template "etcd.fullname" . }}-headless
podManagementPolicy: {{ .Values.statefulset.podManagementPolicy }}
replicas: {{ .Values.statefulset.replicaCount }}
@@ -27,10 +27,10 @@ spec:
metadata:
name: "{{ template "etcd.fullname" . }}"
labels:
app: {{ template "etcd.name" . }}
chart: {{ template "etcd.chart" . }}
release: {{ .Release.Name | quote }}
heritage: {{ .Release.Service | quote }}
app.kubernetes.io/name: {{ template "etcd.name" . }}
helm.sh/chart: {{ template "etcd.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
{{- if or .Values.podAnnotations .Values.metrics.enabled }}
annotations:
{{- if .Values.podAnnotations }}
@@ -47,17 +47,37 @@ spec:
fsGroup: {{ .Values.securityContext.fsGroup }}
runAsUser: {{ .Values.securityContext.runAsUser }}
{{- end }}
{{- if .Values.affinity }}
affinity:
{{ toYaml .Values.affinity | indent 8 }}
{{- with .Values.nodeAffinity }}
nodeAffinity: {{ tpl (toYaml .) $ | nindent 8 }}
{{- end }}
{{- with .Values.podAffinity }}
podAffinity: {{ tpl (toYaml .) $ | nindent 8 }}
{{- end }}
{{- if eq .Values.podAntiAffinity "hard" }}
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- topologyKey: "kubernetes.io/hostname"
labelSelector:
matchLabels:
app.kubernetes.io/name: {{ template "etcd.name" . }}
app.kubernetes.io/instance: {{ .Release.Name | quote }}
{{- else if eq .Values.podAntiAffinity "soft" }}
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
podAffinityTerm:
topologyKey: "kubernetes.io/hostname"
labelSelector:
matchLabels:
app.kubernetes.io/name: {{ template "etcd.name" . }}
app.kubernetes.io/instance: {{ .Release.Name | quote }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector: {{ tpl (toYaml .) $ | nindent 8 }}
{{- end }}
{{- if .Values.nodeSelector }}
nodeSelector:
{{ toYaml .Values.nodeSelector | indent 8 }}
{{- end }}
{{- if .Values.tolerations }}
tolerations:
{{ toYaml .Values.tolerations | indent 8 }}
{{- with .Values.tolerations }}
tolerations: {{ tpl (toYaml .) $ | nindent 8 }}
{{- end }}
containers:
# Variables to populate static cluster
@@ -70,76 +90,16 @@ spec:
{{- $dnsBase := .Values.service.dnsBase }}
{{- $etcdPeerProtocol := include "etcd.peerProtocol" . }}
{{- $etcdClientProtocol := include "etcd.clientProtocol" . }}
- name: "{{ template "etcd.fullname" . }}"
- name: etcd
image: "{{ template "etcd.image" . }}"
imagePullPolicy: "{{ .Values.image.pullPolicy }}"
command:
- bash
- -ec
- |
HOSTNAME=$(hostname -s)
ID=${HOSTNAME:(-1)}
echo "==> The ID of the host is $ID"
DATA_DIR={{ template "etcd.dataDir" . }}
AUTH_OPTIONS="{{ template "etcd.authOptions" . }}"
## Store member id for later member replacement
store_member_id() {
while ! etcdctl ${AUTH_OPTIONS} member list &>/dev/null; do sleep 1; done
etcdctl ${AUTH_OPTIONS} member list | grep `hostname -s` | awk '{ print $1}' | awk -F ":" '{ print $1}' > ${DATA_DIR}/member_id
exit 0
}
## Create data dir if not exists
if [ ! -d "${DATA_DIR}" ]; then
echo "==> Creating data dir..."
mkdir -p "${DATA_DIR}"
## Setting up new cluster
echo "==> There is no data at all. Creating new cluster"
export ETCDCTL_ENDPOINTS="{{range $i, $e := until $replicaCount }}{{ $etcdClientProtocol }}://{{ $etcdFullname }}-{{ $e }}.{{ $etcdHeadlessServiceName }}.{{ $releaseNamespace }}.{{ $dnsBase }}:{{ $clientPort }},{{ end }}"
store_member_id &
if [ -n "${ETCD_ROOT_PASSWORD}" ] && [ "${HOSTNAME}" == "{{ $etcdFullname }}-0" ]; then
echo "==> Configuring RBAC authentication!"
etcd > /dev/null 2>&1 &
ETCD_PID=$!
while ! etcdctl member list &>/dev/null; do sleep 1; done
echo "${ETCD_ROOT_PASSWORD}" | etcdctl user add root
etcdctl auth enable
etcdctl ${AUTH_OPTIONS} role revoke guest -path '/*' --readwrite
kill "${ETCD_PID}"
sleep 5
fi
else
## Re-joining failed node
if [ -d "${DATA_DIR}/member/snap" ]; then
echo "==> Data exists. Re-joining etcd member"
member_id=$(cat "${DATA_DIR}/member_id")
if [ "${HOSTNAME}" != "{{ $etcdFullname }}-0" ]; then
echo "==> Updating member in existing cluster."
export ETCDCTL_ENDPOINTS="{{range $i, $e := until $replicaCount }}{{ $etcdClientProtocol }}://{{ $etcdFullname }}-{{ $e }}.{{ $etcdHeadlessServiceName }}.{{ $releaseNamespace }}.{{ $dnsBase }}:{{ $clientPort }},{{ end }}"
etcdctl ${AUTH_OPTIONS} member update ${member_id} {{ $etcdPeerProtocol }}://`hostname -s`.{{ $etcdHeadlessServiceName }}.{{ .Release.Namespace }}.{{ $dnsBase }}:{{ $peerPort }}
fi
## Adding new member to the cluster
else
echo "==> Adding member to existing cluster."
export ETCDCTL_ENDPOINTS="{{range $i, $e := until $replicaCount }}{{ $etcdClientProtocol }}://{{ $etcdFullname }}-{{ $e }}.{{ $etcdHeadlessServiceName }}.{{ $releaseNamespace }}.{{ $dnsBase }}:{{ $clientPort }},{{ end }}"
etcdctl ${AUTH_OPTIONS} member add `hostname -s` {{ $etcdPeerProtocol }}://`hostname -s`.{{ $etcdHeadlessServiceName }}.{{ .Release.Namespace }}.{{ $dnsBase }}:{{ $peerPort }} | grep "^ETCD_" > ${DATA_DIR}/new_member_envs
sed -ie 's/^/export /' /bitnami/etcd/data/new_member_envs
echo "==> Loading env vars of existing cluster"
source "${DATA_DIR}/new_member_envs"
store_member_id &
fi
fi
{{- if .Values.configFileConfigMap }}
exec /opt/bitnami/etcd/bin/etcd --config-file /opt/bitnami/etcd/conf/etcd.conf.yml
{{ else }}
exec /opt/bitnami/etcd/bin/etcd
{{- end }}
- /scripts/setup.sh
lifecycle:
preStop:
exec:
command:
- /scripts/prestop-hook.sh
resources:
{{ toYaml .Values.resources | indent 10 }}
{{- if .Values.envVarsConfigMap }}
@@ -166,6 +126,8 @@ spec:
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: ETCDCTL_API
value: "3"
- name: ETCD_NAME
value: "$(MY_POD_NAME)"
- name: ETCD_DATA_DIR
@@ -195,13 +157,7 @@ spec:
## RBAC authentication
- name: ALLOW_NONE_AUTHENTICATION
{{- if .Values.auth.rbac.enabled }}
value: "no"
{{- else if .Values.allowNoneAuthentication }}
value: "yes"
{{- else }}
value: "no"
{{- end }}
value: {{ ternary "yes" "no" (or .Values.auth.rbac.enabled .Values.allowNoneAuthentication) | quote }}
{{- if .Values.auth.rbac.enabled }}
- name: ETCD_ROOT_PASSWORD
valueFrom:
@@ -246,29 +202,14 @@ spec:
ports:
- name: client
containerPort: {{ .Values.service.port }}
containerPort: 2379
- name: peer
containerPort: {{ .Values.service.port }}
lifecycle:
preStop:
exec:
command:
- "/bin/sh"
- "-ec"
- |
AUTH_OPTIONS="{{ template "etcd.authOptions" . }}"
DATA_DIR={{ template "etcd.dataDir" . }}
MEMBER_ID=$(etcdctl member list | grep name=`hostname -s` | awk {'print $1'} | awk -F ":" {'print $1'})
export ETCDCTL_ENDPOINTS="{{range $i, $e := until $replicaCount }}{{ $etcdClientProtocol }}://{{ $etcdFullname }}-{{ $e }}.{{ $etcdHeadlessServiceName }}.{{ $releaseNamespace }}.{{ $dnsBase }}:{{ $clientPort }},{{ end }}"
echo "==> Removing $MEMBER_ID from etcd cluster"
etcdctl ${AUTH_OPTIONS} member remove $MEMBER_ID
if [ $? -eq 0 ]; then
rm -rf ${DATA_DIR}/*
fi
containerPort: 2380
{{- if .Values.livenessProbe.enabled }}
livenessProbe:
tcpSocket:
port: client
exec:
command:
- /scripts/probes.sh
initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.livenessProbe.periodSeconds }}
timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }}
@@ -277,8 +218,9 @@ spec:
{{- end }}
{{- if .Values.readinessProbe.enabled }}
readinessProbe:
tcpSocket:
port: client
exec:
command:
- /scripts/probes.sh
initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }}
@@ -286,42 +228,79 @@ spec:
failureThreshold: {{ .Values.readinessProbe.failureThreshold }}
{{- end }}
volumeMounts:
{{- if .Values.persistence.enabled }}
- name: scripts
mountPath: /scripts
- name: data
mountPath: /bitnami/etcd
{{ end }}
{{ if .Values.configFileConfigMap }}
{{- if .Values.disasterRecovery.enabled }}
- name: snapshot-volume
mountPath: /snapshots
{{- end }}
{{- if .Values.configFileConfigMap }}
- name: etcd-config
mountPath: /opt/bitnami/etcd/conf/
{{ end }}
{{ if or .Values.auth.client.enableAuthentication (and .Values.auth.client.secureTransport (not .Values.auth.client.useAutoTLS ) ) }}
{{- end }}
{{- if or .Values.auth.client.enableAuthentication (and .Values.auth.client.secureTransport (not .Values.auth.client.useAutoTLS ) ) }}
- name: etcd-client-certs
mountPath: /opt/bitnami/etcd/certs/client/
readOnly: true
{{ end }}
{{ if or .Values.auth.peer.enableAuthentication (and .Values.auth.peer.secureTransport (not .Values.auth.peer.useAutoTLS ) ) }}
{{- end }}
{{- if or .Values.auth.peer.enableAuthentication (and .Values.auth.peer.secureTransport (not .Values.auth.peer.useAutoTLS ) ) }}
- name: etcd-peer-certs
mountPath: /opt/bitnami/etcd/certs/peer/
readOnly: true
{{ end }}
{{- end }}
{{- if .Values.disasterRecovery.enabled }}
- name: snapshotter-sidecar
image: "{{ template "etcd.image" . }}"
imagePullPolicy: "{{ .Values.image.pullPolicy }}"
command:
- /scripts/sidecar.sh
env:
- name: ETCDCTL_API
value: "3"
{{- if .Values.auth.rbac.enabled }}
- name: ETCD_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: {{ if .Values.auth.rbac.existingSecret }}{{ .Values.auth.rbac.existingSecret }}{{ else }}{{ template "etcd.fullname" . }}{{ end }}
key: etcd-root-password
{{- end }}
volumeMounts:
- name: scripts
mountPath: /scripts
- name: data
mountPath: /bitnami/etcd
- name: snapshot-volume
mountPath: /snapshots
{{- end }}
volumes:
{{ if .Values.configFileConfigMap }}
- name: scripts
configMap:
name: {{ template "etcd.fullname" . }}-scripts
defaultMode: 0755
{{- if .Values.disasterRecovery.enabled }}
- name: snapshot-volume
persistentVolumeClaim:
claimName: {{ template "etcd.fullname" . }}-snapshot
{{- end }}
{{- if .Values.configFileConfigMap }}
- name: etcd-config
configMap:
name: {{ template "etcd.configFileCM" . }}
{{ end }}
{{ if or .Values.auth.client.enableAuthentication (and .Values.auth.client.secureTransport (not .Values.auth.client.useAutoTLS ) ) }}
{{- end }}
{{- if or .Values.auth.client.enableAuthentication (and .Values.auth.client.secureTransport (not .Values.auth.client.useAutoTLS ) ) }}
- name: etcd-client-certs
secret:
secretName: {{ required "A secret containinig the client certificates is required" .Values.auth.client.existingSecret }}
defaultMode: 256
{{ end }}
{{ if or .Values.auth.peer.enableAuthentication (and .Values.auth.peer.secureTransport (not .Values.auth.peer.useAutoTLS ) ) }}
{{- end }}
{{- if or .Values.auth.peer.enableAuthentication (and .Values.auth.peer.secureTransport (not .Values.auth.peer.useAutoTLS ) ) }}
- name: etcd-peer-certs
secret:
secretName: {{ required "A secret containinig the peer certificates is required" .Values.auth.peer.existingSecret }}
defaultMode: 256
{{ end }}
{{- end }}
{{- if .Values.persistence.enabled }}
volumeClaimTemplates:
- metadata:
+8 -8
View File
@@ -5,20 +5,20 @@ metadata:
annotations:
service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
labels:
app: {{ template "etcd.name" . }}
chart: {{ template "etcd.chart" . }}
release: "{{ .Release.Name }}"
heritage: "{{ .Release.Service }}"
app.kubernetes.io/name: {{ template "etcd.name" . }}
helm.sh/chart: {{ template "etcd.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
spec:
type: ClusterIP
clusterIP: None
ports:
- name: client
port: 2379
port: {{ .Values.service.port }}
targetPort: client
- name: peer
port: 2380
port: {{ .Values.service.peerPort }}
targetPort: peer
selector:
app: {{ template "etcd.name" . }}
release: {{ .Release.Name | quote }}
app.kubernetes.io/name: {{ template "etcd.name" . }}
app.kubernetes.io/instance: {{ .Release.Name | quote }}
+8 -8
View File
@@ -3,10 +3,10 @@ kind: Service
metadata:
name: {{ template "etcd.fullname" . }}
labels:
app: {{ template "etcd.name" . }}
chart: {{ template "etcd.chart" . }}
release: "{{ .Release.Name }}"
heritage: "{{ .Release.Service }}"
app.kubernetes.io/name: {{ template "etcd.name" . }}
helm.sh/chart: {{ template "etcd.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
{{- if .Values.service.annotations }}
annotations:
{{ toYaml .Values.service.annotations | indent 4 }}
@@ -18,17 +18,17 @@ spec:
{{- end }}
ports:
- name: client
port: 2379
port: {{ .Values.service.port }}
targetPort: client
{{- if and (eq .Values.service.type "NodePort") (not (empty .Values.service.nodePort)) }}
nodePort: {{ .Values.service.nodePort }}
{{- end }}
- name: peer
port: 2380
port: {{ .Values.service.peerPort }}
targetPort: peer
{{- if and (eq .Values.service.type "NodePort") (not (empty .Values.service.peerNodePort)) }}
nodePort: {{ .Values.service.peerNodePort }}
{{- end }}
selector:
app: {{ template "etcd.name" . }}
release: {{ .Release.Name | quote }}
app.kubernetes.io/name: {{ template "etcd.name" . }}
app.kubernetes.io/instance: {{ .Release.Name | quote }}
+42 -6
View File
@@ -149,12 +149,6 @@ persistence:
size: 8Gi
annotations: {}
## Node labels and tolerations for pod assignment
## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector
## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature
nodeSelector: {}
tolerations: []
## Configure resource requests and limits
## ref: http://kubernetes.io/docs/user-guide/compute-resources/
##
@@ -189,8 +183,50 @@ readinessProbe:
##
podAnnotations: {}
## Node Affinity. The value is evaluated as a template.
## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#node-affinity-beta-feature
##
nodeAffinity: {}
## Pod Affinity. The value is evaluated as a template.
## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity
##
podAffinity: {}
## Pod AntiAffinity
## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity
##
podAntiAffinity: soft
## Node labels for pod assignment. The value is evaluated as a template.
## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector
##
nodeSelector: {}
## Tolerations for pod assignment. The value is evaluated as a template.
## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature
##
tolerations: {}
## Add the corresponding annotations so Prometheus can collect etcd metrics
##
metrics:
enabled: true
podAnnotations:
prometheus.io/scrape: "true"
prometheus.io/port: "2379"
## Enable auto disaster recovery by periodically snapshotting the keyspace
## - It creates a sidecar container to periodically snapshotting the keyspace
## - It also creates a ReadWriteMany PVC to store the snapshots
## If the cluster permanently loses more than (N-1)/2 members, it tries to recover
## the cluster from a previous snapshot.
##
disasterRecovery:
enabled: true
## Interval (in seconds) to save snapshots
##
interval: 300
## PVC Storage Request
##
size: 2Gi
## storageClassName, choose a storageClassName with ReadWriteMany support
##
storageClassName: nfs
+43 -7
View File
@@ -149,12 +149,6 @@ persistence:
size: 8Gi
annotations: {}
## Node labels and tolerations for pod assignment
## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector
## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature
nodeSelector: {}
tolerations: []
## Configure resource requests and limits
## ref: http://kubernetes.io/docs/user-guide/compute-resources/
##
@@ -178,7 +172,7 @@ livenessProbe:
readinessProbe:
enabled: false
initialDelaySeconds: 5
initialDelaySeconds: 15
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 6
@@ -189,8 +183,50 @@ readinessProbe:
##
podAnnotations: {}
## Node Affinity. The value is evaluated as a template.
## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#node-affinity-beta-feature
##
nodeAffinity: {}
## Pod Affinity. The value is evaluated as a template.
## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity
##
podAffinity: {}
## Pod AntiAffinity
## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity
##
podAntiAffinity: soft
## Node labels for pod assignment. The value is evaluated as a template.
## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector
##
nodeSelector: {}
## Tolerations for pod assignment. The value is evaluated as a template.
## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature
##
tolerations: {}
## Add the corresponding annotations so Prometheus can collect etcd metrics
##
metrics:
enabled: false
podAnnotations:
prometheus.io/scrape: "true"
prometheus.io/port: "2379"
## Enable auto disaster recovery by periodically snapshotting the keyspace
## - It creates a sidecar container to periodically snapshotting the keyspace
## - It also creates a ReadWriteMany PVC to store the snapshots
## If the cluster permanently loses more than (N-1)/2 members, it tries to recover
## the cluster from a previous snapshot.
##
disasterRecovery:
enabled: false
## Interval (in seconds) to save snapshots
##
interval: 300
## PVC Storage Request
##
size: 2Gi
## storageClassName, choose a storageClassName with ReadWriteMany support
##
storageClassName: nfs