Firs version of etcd chart

This commit is contained in:
tompizmor
2018-06-27 15:53:24 +02:00
parent 2e955de553
commit cf5869b165
12 changed files with 1142 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
.git
+18
View File
@@ -0,0 +1,18 @@
name: etcd
version: 0.0.1
appVersion: 3.3.8
description: etcd is a distributed key value store that provides a reliable way to store data across a cluster of machines
keywords:
- etcd
- cluster
- database
- cache
- key-value
home: https://coreos.com/etcd/
sources:
- https://github.com/bitnami/bitnami-docker-etcd
maintainers:
- name: Bitnami
email: containers@bitnami.com
engine: gotpl
icon: https://bitnami.com/assets/stacks/etcd/img/etcd-stack-110x117.png
+178
View File
@@ -0,0 +1,178 @@
# etcd
[etcd](https://www.etcd.org/) is an object-relational database management system (ORDBMS) with an emphasis on extensibility and on standards-compliance.
## TL;DR;
```console
$ helm install bitnami/etcd
```
## Introduction
This chart bootstraps a [etcd](https://github.com/bitnami/bitnami-docker-etcd) deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager.
## Prerequisites
- Kubernetes 1.4+ with Beta APIs enabled
- PV provisioner support in the underlying infrastructure
## Installing the Chart
To install the chart with the release name `my-release`:
```console
$ helm install --name my-release bitnami/etcd
```
The command deploys etcd on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation.
> **Tip**: List all releases using `helm list`
## Uninstalling the Chart
To uninstall/delete the `my-release` deployment:
```console
$ helm delete my-release
```
The command removes all the Kubernetes components associated with the chart and deletes the release.
## Configuration
The following tables lists the configurable parameters of the etcd chart and their default values.
| Parameter | Description | Default |
|------------------------------------|------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------- |
| `image.registry` | etcd image registry | `docker.io` |
| `image.repository` | etcd Image name | `bitnami/etcd` |
| `image.tag` | etcd Image tag | `{VERSION}` |
| `image.pullPolicy` | etcd image pull policy | `Always` |
| `image.pullSecrets` | Specify image pull secrets | `nil` (does not add image pull secrets to deployed pods) |
| `image.debug` | Specify if debug values should be set | `false` |
| `updateStrategy` | Update strategy for the stateful set | `RollingUpdate` |
| `podManagementPolicy` | Pod management policy for the stateful set | `OrderedReady` |
| `replicaCount` | Number of etcd nodes | `1` |
| `useConfigmap` | Switch to use the config map for etcd | `false` |
| `allowNoneAuthentication` | Allow to use etcd without configuring RBAC authentication | `true` |
| `auth.rbac.enabled` | Switch to enable the etcd authentication. | `false` |
| `auth.rbac.rootPassword` | Password for the root user | `false` |
| `auth.rbac.existingSecret` | Name of the existing secret containing the root password | `false` |
| `auth.client.secureTransport` | Switch to encrypt client communication using TLS certificates | `false` |
| `auth.client.useAutoTLS` | Switch to automatically create the TLS certificates | `false` |
| `auth.client.enableAuthentication` | Switch to enable host authentication using TLS certificates. Requires existing secret. | `secret` |
| `auth.client.existingSecret` | Name of the existing secret containing cert files for client communication. | `nil` |
| `auth.peer.secureTransport` | Switch to encrypt peer communication using TLS certificates | `false` |
| `auth.peer.useAutoTLS` | Switch to automatically create the TLS certificates | `false` |
| `auth.peer.enableAuthentication` | Switch to enable host authentication using TLS certificates. Requires existing secret. | `false` |
| `auth.peer.existingSecret` | Name of the existing secret containing cert files for peer communication. | `nil` |
| `securityContext.enabled` | Enable security context | `true` |
| `securityContext.fsGroup` | Group ID for the container | `1001` |
| `securityContext.runAsUser` | User ID for the container | `1001` |
| `service.type` | Kubernetes Service type | `ClusterIP` |
| `service.port` | etcd client port | `2379` |
| `service.peerPort` | etcd peer port | `2380` |
| `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 | `{}` |
| `nodeSelector` | Node labels for pod assignment | `{}` |
| `tolerations` | Toleration labels for pod assignment | `[]` |
| `resources` | CPU/Memory resource requests/limits | Memory: `256Mi`, CPU: `250m` |
| `livenessProbe.enabled` | would you like a livessProbed to be enabled | `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` | would you like a readinessProbe to be enabled | `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 |
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
```
The above command sets the etcd `etcd` account password to `secretpassword`. Additionally it creates a database named `my-database`.
Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example,
```console
$ helm install --name my-release -f values.yaml bitnami/etcd
```
> **Tip**: You can use the default [values.yaml](values.yaml)
## 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
$ kubectl scale statefulset my-etcd --replicas=5
```
## Enable security for etcd and Zookeeper
### Configure RBAC
In order to enable [Role-based access control for etcd](https://coreos.com/etcd/docs/latest/op-guide/authentication.html) you can run the following command:
```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.
### Configure certificated for peer communication
In order to enable secure transport between peer nodes deploy the helm chart with these options:
```console
$ helm install --name my-release --set auth.peer.secureTransport=true --set auth.peer.useAutoTLS=true bitnami/etcd
```
### Configure certificates for client comminication
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.
You can create that secret with this command:
```console
$ kubectl create secret generic etcd-client-certs --from-file=ca.crt=path/to/ca.crt --from-file=cert.pem=path/to/cert.pem --from-file=key.pem=path/to/key.pem
```
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
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 deployments. This is known to work in GCE, AWS, and minikube.
See the [Configuration](#configuration) section to configure the PVC or to disable persistence.
+75
View File
@@ -0,0 +1,75 @@
{{- if contains .Values.service.type "LoadBalancer" }}
{{- if .Values.allowNoneAuthentication }}
-------------------------------------------------------------------------------
WARNING
By specifying "service.type=LoadBalancer" and "allowNoneAuthentication=true" you
have most likely exposed the Redis service externally without any authentication
mechanism.
For security reasons, we strongly suggest that you switch to "ClusterIP" or
"NodePort". As alternative, you can also switch to "usePassword=true"
providing a valid password on "password" parameter.
-------------------------------------------------------------------------------
{{- end }}
{{- end }}
** Please be patient while the chart is being deployed **
etcd can be accessed via port 2379 on the following DNS name from within your cluster:
{{ template "etcd.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local
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
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
To connect to your etcd server from outside the cluster execute the following commands:
{{- if contains "NodePort" .Values.service.type }}
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "etcd.fullname" . }})
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
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" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "etcd.name" . }}" -o jsonpath="{.items[0].metadata.name}")
kubectl port-forward --namespace {{ .Release.Namespace }} $POD_NAME 2379:2379 &
{{- end }}
{{ 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:
export ETCD_ROOT_PASSWORD=${kubectl get secret --namespace {{ .Release.Namespace }} {{ template "etcd.fullname" . }} -o jsonpath="{.data.etcd-root-password}" | base64 --decode)}
{{ end }}
{{- if .Values.auth.client.secureTransport }}
{{- if .Values.auth.client.useAutoTLS }}
* As TLS secured transport 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 secured transport 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 }}
+66
View File
@@ -0,0 +1,66 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "etcd.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 24 -}}
{{- end -}}
{{/*
Create a default fully qualified app name.
We truncate at 24 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
*/}}
{{- define "etcd.fullname" -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- printf "%s-%s" .Release.Name $name | trunc 24 -}}
{{- end -}}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "etcd.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Return the proper etcd image name
*/}}
{{- define "etcd.image" -}}
{{- $registryName := .Values.image.registry -}}
{{- $tag := .Values.image.tag | toString -}}
{{- printf "%s/%s:%s" $registryName .Values.image.repository $tag -}}
{{- end -}}
{{/*
{{/*
Return the proper etcd peer protocol
*/}}
{{- define "etcd.peerProtocol" -}}
{{- if .Values.auth.peer.secureTransport -}}
{{- print "https" -}}
{{- else -}}
{{- print "http" -}}
{{- end -}}
{{- end -}}
{{/*
Return the proper etcd client protocol
*/}}
{{- define "etcd.clientProtocol" -}}
{{- if .Values.auth.client.secureTransport -}}
{{- print "https" -}}
{{- else -}}
{{- print "http" -}}
{{- end -}}
{{- end -}}
{{/*
Return the proper etcd data dir
*/}}
{{- define "etcd.dataDir" -}}
{{- if .Values.persistence.enabled -}}
{{- print "/bitnami/etcd/data" -}}
{{- else -}}
{{- print "/opt/bitnami/etcd/data" -}}
{{- end -}}
{{- end -}}
+108
View File
@@ -0,0 +1,108 @@
{{- if .Values.useConfigmap }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "etcd.fullname" . }}-configuration
labels:
app: "{{ template "etcd.name" . }}"
chart: {{ template "etcd.chart" . }}
release: {{ .Release.Name | quote }}
heritage: {{ .Release.Service | quote }}
data:
etcd.conf.yml: |-
# This is the configuration file for the etcd server.
# Human-readable name for this member.
name: 'default'
# Path to the data directory.
data-dir:
# Path to the dedicated wal directory.
wal-dir:
# Number of committed transactions to trigger a snapshot to disk.
snapshot-count: 10000
# Time (in milliseconds) of a heartbeat interval.
heartbeat-interval: 100
# Time (in milliseconds) for an election to timeout.
election-timeout: 1000
# Raise alarms when backend size exceeds the given quota. 0 means use the
# default quota.
quota-backend-bytes: 0
# List of comma separated URLs to listen on for peer traffic.
listen-peer-urls: http://0.0.0.0:2380
# List of comma separated URLs to listen on for client traffic.
listen-client-urls: http://0.0.0.0:2379
# Maximum number of snapshot files to retain (0 is unlimited).
max-snapshots: 5
# Maximum number of wal files to retain (0 is unlimited).
max-wals: 5
# Comma-separated white list of origins for CORS (cross-origin resource sharing).
cors:
# List of this member's peer URLs to advertise to the rest of the cluster.
# The URLs needed to be a comma-separated list.
initial-advertise-peer-urls: http://localhost:2380
# List of this member's client URLs to advertise to the public.
# The URLs needed to be a comma-separated list.
advertise-client-urls: http://localhost:2379
# Discovery URL used to bootstrap the cluster.
discovery:
# Valid values include 'exit', 'proxy'
discovery-fallback: 'proxy'
# HTTP proxy to use for traffic to discovery service.
discovery-proxy:
# DNS domain used to bootstrap initial cluster.
discovery-srv:
# Initial cluster configuration for bootstrapping.
initial-cluster:
# Initial cluster token for the etcd cluster during bootstrap.
initial-cluster-token: 'etcd-cluster'
# Initial cluster state ('new' or 'existing').
initial-cluster-state: 'new'
# Reject reconfiguration requests that would cause quorum loss.
strict-reconfig-check: false
# Accept etcd V2 client requests
enable-v2: true
# Enable runtime profiling data via HTTP server
enable-pprof: true
# Valid values include 'on', 'readonly', 'off'
proxy: 'off'
# Time (in milliseconds) an endpoint will be held in a failed state.
proxy-failure-wait: 5000
# Time (in milliseconds) of the endpoints refresh interval.
proxy-refresh-interval: 30000
# Time (in milliseconds) for a dial to timeout.
proxy-dial-timeout: 1000
# Time (in milliseconds) for a write to timeout.
proxy-write-timeout: 5000
# Time (in milliseconds) for a read to timeout.
proxy-read-timeout: 0
client-transport-security:
# Path to the client server TLS cert file.
cert-file:
# Path to the client server TLS key file.
key-file:
# Enable client cert authentication.
client-cert-auth: false
# Path to the client server TLS trusted CA cert file.
trusted-ca-file:
# Client TLS using generated certificates
auto-tls: false
peer-transport-security:
# Path to the peer server TLS cert file.
cert-file:
# Path to the peer server TLS key file.
key-file:
# Enable peer client cert authentication.
peer-client-cert-auth: false
# Path to the peer server TLS trusted CA cert file.
trusted-ca-file:
# Peer TLS using generated certificates.
auto-tls: false
# Enable debug-level logging for etcd.
debug: false
logger: zap
# Specify 'stdout' or 'stderr' to skip journald logging even when running under systemd.
log-outputs: [stderr]
# Force to create a new one member cluster.
force-new-cluster: false
auto-compaction-mode: periodic
auto-compaction-retention: "1"
{{- end -}}
+18
View File
@@ -0,0 +1,18 @@
{{- if and .Values.auth.rbac.enabled (not .Values.auth.rbac.existingSecret) -}}
apiVersion: v1
kind: Secret
metadata:
name: {{ template "etcd.fullname" . }}
labels:
app: {{ template "etcd.name" . }}
chart: {{ template "etcd.chart" . }}
release: {{ .Release.Name | quote }}
heritage: {{ .Release.Service | quote }}
type: Opaque
data:
{{- if .Values.auth.rbac.rootPassword }}
etcd-root-password: {{ .Values.auth.rbac.rootPassword | b64enc | quote }}
{{ else }}
etcd-root-password: {{ randAlphaNum 10 | b64enc | quote }}
{{- end }}
{{- end }}
+357
View File
@@ -0,0 +1,357 @@
apiVersion: apps/v1beta2
kind: StatefulSet
metadata:
name: "{{ template "etcd.fullname" . }}"
labels:
app: {{ template "etcd.name" . }}
chart: {{ template "etcd.chart" . }}
release: {{ .Release.Name | quote }}
heritage: {{ .Release.Service | quote }}
spec:
serviceName: {{ template "etcd.fullname" . }}-headless
podManagementPolicy: {{ .Values.podManagementPolicy }}
replicas: {{ .Values.replicaCount }}
updateStrategy:
type: {{ .Values.updateStratey }}
selector:
matchLabels:
app: {{ template "etcd.name" . }}
chart: {{ template "etcd.chart" . }}
release: {{ .Release.Name | quote }}
heritage: {{ .Release.Service | quote }}
template:
metadata:
name: "{{ template "etcd.fullname" . }}"
labels:
app: {{ template "etcd.name" . }}
chart: {{ template "etcd.chart" . }}
release: {{ .Release.Name | quote }}
heritage: {{ .Release.Service | quote }}
spec:
{{- if .Values.image.pullSecrets }}
imagePullSecrets:
{{- range .Values.image.pullSecrets }}
- name: {{ . }}
{{- end}}
{{- end }}
{{- if .Values.securityContext.enabled }}
securityContext:
fsGroup: {{ .Values.securityContext.fsGroup }}
runAsUser: {{ .Values.securityContext.runAsUser }}
{{- end }}
{{- if .Values.nodeSelector }}
nodeSelector:
{{ toYaml .Values.nodeSelector | indent 8 }}
{{- end }}
{{- if .Values.tolerations }}
tolerations:
{{ toYaml .Values.tolerations | indent 8 }}
{{- end }}
containers:
# Variables to populate static cluster
{{- $replicaCount := int .Values.replicaCount }}
{{- $clientPort := int .Values.service.port }}
{{- $peerPort := int .Values.service.peerPort }}
{{- $etcdFullname := include "etcd.fullname" . }}
{{- $etcdHeadlessServiceName := printf "%s-%s" $etcdFullname "headless" }}
{{- $etcdPeerProtocol := include "etcd.peerProtocol" . }}
{{- $etcdClientProtocol := include "etcd.clientProtocol" . }}
- name: "{{ template "etcd.fullname" . }}"
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=""
if [ ! -z "$ETCD_ROOT_PASSWORD" ]; then
echo "==> Setting RBAC options for command line..."
AUTH_OPTIONS+="-u root:${ETCD_ROOT_PASSWORD}"
fi
if [ ! -z "$ETCD_CERT_FILE" ] && [ ! -z "$ETCD_KEY_FILE" ]; then
echo "==> Setting cert and key options for command line..."
AUTH_OPTIONS+=" --cert-file $ETCD_CERT_FILE --key-file $ETCD_KEY_FILE"
fi
if [ ! -z "$ETCD_TRUSTED_CA_FILE" ]; then
echo "==> Setting trusted ca file option for command line..."
AUTH_OPTIONS+=" --ca-file $ETCD_TRUSTED_CA_FILE"
fi
## 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}
fi
## Re-joining failed node
if [ -d '${DATA_DIR}/member/' ]; then
echo "==> Data exists. Re-joining etcd member"
member_id=$(cat ${DATA_DIR}/member_id)
echo "==> Updating member in existing cluster."
export ETCDCTL_ENDPOINTS="{{ $etcdClientProtocol }}://{{ $etcdFullname }}-0.{{ $etcdHeadlessServiceName }}.default.svc.cluster.local:{{ $clientPort }}"
etcdctl ${AUTH_OPTIONS} member update ${member_id} {{ $etcdPeerProtocol }}://`hostname -s`.{{ $etcdHeadlessServiceName }}.default.svc.cluster.local:{{ $peerPort }}
## Adding new member to the cluster
elif [ "${ID}" -ge {{ $replicaCount }} ]; then
echo "==> Adding member to existing cluster."
export ETCDCTL_ENDPOINTS="{{ $etcdClientProtocol }}://{{ $etcdFullname }}-0.{{ $etcdHeadlessServiceName }}.default.svc.cluster.local:{{ $clientPort }}"
echo "==> Adding new member"
etcdctl ${AUTH_OPTIONS} member add `hostname -s` {{ $etcdPeerProtocol }}://`hostname -s`.{{ $etcdHeadlessServiceName }}.default.svc.cluster.local:{{ $peerPort }} | grep "^ETCD_" > ${DATA_DIR}/new_member_envs
echo "==> Loading env vars of existing cluster"
source ${DATA_DIR}/new_member_envs
store_member_id &
## Setting up new cluster
else
echo "==> There is no data at all. Creating new cluster"
store_member_id &
if [ ! -z "$ETCD_ROOT_PASSWORD" ] && [ `hostname -s` == '{{ $etcdFullname }}-0' ]; then
echo "==> Configuring RBAC authentication!"
etcd > /dev/null 2>&1 &
ETCD_PID=$!
sleep 5
echo "$ETCD_ROOT_PASSWORD" | etcdctl user add root
etcdctl auth enable
etcdctl -u root:"$ETCD_ROOT_PASSWORD" role revoke guest -path '/*' --readwrite
kill $ETCD_PID
sleep 5
fi
fi
{{- if .Values.useConfigmap }}
exec /opt/bitnami/etcd/bin/etcd --config-file /opt/bitnami/etcd/conf/etcd.conf.yml
{{ else }}
exec /opt/bitnami/etcd/bin/etcd
{{- end }}
resources:
{{ toYaml .Values.resources | indent 10 }}
env:
{{- if .Values.image.debug }}
- name: BASH_DEBUG
value: "1"
- name: NAMI_DEBUG
value: "1"
- name: NAMI_LOG_LEVEL
value: "trace8"
{{- end }}
- name: MY_POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
## Basic configuration
- name: ETCD_NAME
value: "$(MY_POD_NAME)"
- name: ETCD_DATA_DIR
value: {{ template "etcd.dataDir" . }}
- name: ETCD_ADVERTISE_CLIENT_URLS
value: "{{ $etcdClientProtocol }}://$(MY_POD_NAME):{{ .Values.service.port }}"
- name: ETCD_LISTEN_CLIENT_URLS
value: "{{ $etcdClientProtocol }}://0.0.0.0:{{ .Values.service.port }}"
- name: ETCD_INITIAL_ADVERTISE_PEER_URLS
value: "{{ $etcdPeerProtocol }}://$(MY_POD_NAME):{{ .Values.service.peerPort }}"
- name: ETCD_LISTEN_PEER_URLS
value: "{{ $etcdPeerProtocol }}://0.0.0.0:{{ .Values.service.peerPort }}"
## Clustering configuration
{{- if gt $replicaCount 1 }}
- name: ETCD_INITIAL_CLUSTER_TOKEN
value: "etcd-cluster-k8s"
- name: ETCD_INITIAL_CLUSTER_STATE
value: "new"
- name: ETCD_INITIAL_CLUSTER
value: {{range $i, $e := until $replicaCount }}{{ $etcdFullname }}-{{ $e }}={{ $etcdPeerProtocol }}://{{ $etcdFullname }}-{{ $e }}.{{ $etcdHeadlessServiceName }}.default.svc.cluster.local:{{ $peerPort }},{{ end }}
{{- end }}
## RBAC authentication
- name: ALLOW_NONE_AUTHENTICATION
{{- if .Values.auth.rbac.enabled }}
value: "no"
{{- else if .Values.allowNoneAuthentication }}
value: "yes"
{{- else }}
value: "no"
{{- end }}
{{- if .Values.auth.rbac.enabled }}
- name: ETCD_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: {{ if .Values.auth.existingSecret }}{{ .Values.auth.existingSecret }}{{ else }}{{ template "etcd.fullname" . }}{{ end }}
key: etcd-root-password
{{- end }}
## Client-to-server communication
{{- if and .Values.auth.client.secureTransport .Values.auth.client.useAutoTLS }}
- name: ETCD_AUTO_TLS
value: "true"
{{- else if .Values.auth.client.secureTransport }}
- name: ETCD_CERT_FILE
value: "/opt/bitnami/etcd/certs/client/cert.pem"
- name: ETCD_KEY_FILE
value: "/opt/bitnami/etcd/certs/client/key.pem"
{{- if .Values.auth.client.enableAuthentication }}
- name: ETCD_CLIENT_CERT_AUTH
value: "true"
- name: ETCD_TRUSTED_CA_FILE
value: "/opt/bitnami/etcd/certs/client/ca.crt"
{{- end }}
{{- end }}
## Peer-to-peer communication
{{- if and .Values.auth.peer.secureTransport .Values.auth.peer.useAutoTLS }}
- name: ETCD_PEER_AUTO_TLS
value: "true"
{{- else if .Values.auth.peer.secureTransport }}
- name: ETCD_PEER_CERT_FILE
value: "/opt/bitnami/etcd/certs/peer/cert.pem"
- name: ETCD_PEER_KEY_FILE
value: "/opt/bitnami/etcd/certs/peer/key.pem"
{{- if .Values.auth.peer.enableAuthentication }}
- name: ETCD_PEER_CLIENT_CERT_AUTH
value: "true"
- name: ETCD_PEER_TRUSTED_CA_FILE
value: "/opt/bitnami/etcd/certs/peer/ca.crt"
{{- end }}
{{- end }}
ports:
- name: client
containerPort: {{ .Values.service.port }}
- name: peer
containerPort: {{ .Values.service.port }}
lifecycle:
preStop:
exec:
command:
- "/bin/sh"
- "-ec"
- |
AUTH_OPTIONS=""
if [ ! -z "$ETCD_ROOT_PASSWORD" ]; then
echo "==> Setting RBAC options for command line..."
AUTH_OPTIONS+="-u root:${ETCD_ROOT_PASSWORD}"
fi
if [ ! -z "$ETCD_CERT_FILE" ] && [ ! -z "$ETCD_KEY_FILE" ]; then
echo "==> Setting cert and key options for command line..."
AUTH_OPTIONS+=" --cert-file $ETCD_CERT_FILE --key-file $ETCD_KEY_FILE"
fi
if [ ! -z "$ETCD_TRUSTED_CA_FILE" ]; then
echo "==> Setting trusted ca file option for command line..."
AUTH_OPTIONS+=" --ca-file $ETCD_TRUSTED_CA_FILE"
fi
DATA_DIR={{ template "etcd.dataDir" . }}
MEMBER_ID=$(etcdctl member list | grep name=`hostname -s` | awk {'print $1'} | awk -F ":" {'print $1'})
export ETCDCTL_ENDPOINTS="{{ $etcdClientProtocol }}://{{ $etcdFullname }}-0.{{ $etcdHeadlessServiceName }}.default.svc.cluster.local:{{ $clientPort }}"
echo "==> Removing $MEMBER_ID from etcd cluster"
etcdctl ${AUTH_OPTIONS} member remove $MEMBER_ID
if [ $? -eq 0 ]; then
rm -rf ${DATA_DIR}/*
fi
{{- if .Values.livenessProbe.enabled }}
livenessProbe:
tcpSocket:
port: client
initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.livenessProbe.periodSeconds }}
timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }}
successThreshold: {{ .Values.livenessProbe.successThreshold }}
failureThreshold: {{ .Values.livenessProbe.failureThreshold }}
{{- end }}
{{- if .Values.readinessProbe.enabled }}
readinessProbe:
tcpSocket:
port: client
initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }}
successThreshold: {{ .Values.readinessProbe.successThreshold }}
failureThreshold: {{ .Values.readinessProbe.failureThreshold }}
{{- end }}
volumeMounts:
{{- if .Values.persistence.enabled }}
- name: data
mountPath: /bitnami/etcd
{{ end }}
{{ if .Values.useConfigmap }}
- 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 ) ) }}
- 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 ) ) }}
- name: etcd-peer-certs
mountPath: /opt/bitnami/etcd/certs/peer/
readOnly: true
{{ end }}
volumes:
{{ if .Values.useConfigmap }}
- name: etcd-config
configMap:
name: {{ template "etcd.fullname" . }}-configuration
{{ 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 ) ) }}
- name: etcd-peer-certs
secret:
secretName: {{ required "A secret containinig the peer certificates is required" .Values.auth.peer.existingSecret }}
defaultMode: 256
{{ end }}
{{- if .Values.persistence.enabled }}
volumeClaimTemplates:
- metadata:
name: data
annotations:
{{- range $key, $value := .Values.persistence.annotations }}
{{ $key }}: {{ $value }}
{{- end }}
spec:
accessModes:
{{- range .Values.persistence.accessModes }}
- {{ . | quote }}
{{- end }}
resources:
requests:
storage: {{ .Values.persistence.size | quote }}
{{- if .Values.persistence.storageClass }}
{{- if (eq "-" .Values.persistence.storageClass) }}
storageClassName: ""
{{- else }}
storageClassName: "{{ .Values.persistence.storageClass }}"
{{- end }}
{{- end }}
{{- else }}
- name: data
emptyDir: {}
{{- end }}
+24
View File
@@ -0,0 +1,24 @@
apiVersion: v1
kind: Service
metadata:
name: {{ template "etcd.fullname" . }}-headless
annotations:
service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
labels:
app: {{ template "etcd.name" . }}
chart: {{ template "etcd.chart" . }}
release: "{{ .Release.Name }}"
heritage: "{{ .Release.Service }}"
spec:
type: ClusterIP
clusterIP: None
ports:
- name: client
port: 2379
targetPort: client
- name: peer
port: 2380
targetPort: peer
selector:
app: {{ template "etcd.name" . }}
release: "{{ .Release.Name }}"
+21
View File
@@ -0,0 +1,21 @@
apiVersion: v1
kind: Service
metadata:
name: {{ template "etcd.fullname" . }}
labels:
app: {{ template "etcd.name" . }}
chart: {{ template "etcd.chart" . }}
release: "{{ .Release.Name }}"
heritage: "{{ .Release.Service }}"
spec:
type: {{ .Values.service.type }}
ports:
- name: client
port: 2379
targetPort: client
- name: peer
port: 2380
targetPort: peer
selector:
app: {{ template "etcd.name" . }}
release: {{ .Release.Name | quote }}
+138
View File
@@ -0,0 +1,138 @@
## Bitnami etcd image version
## ref: https://hub.docker.com/r/bitnami/etcd/tags/
##
image:
registry: docker.io
repository: bitnami/etcd
tag: 3.3.8
## 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
##
pullPolicy: Always
## Optionally specify an array of imagePullSecrets.
## Secrets must be manually created in the namespace.
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
##
# pullSecrets:
# - myRegistrKeySecretName
## Set to true if you would like to see extra information on logs
## It turns BASH and NAMI debugging in minideb
## ref: https://github.com/bitnami/minideb-extras/#turn-on-bash-debugging
debug: false
updateStrategy: RollingUpdate
podManagementPolicy: OrderedReady
replicaCount: 3
## Take into account that if you use a config map you need to provide the whole configuration
## as the env vars defined in the statefulset.yaml will not be applied
##
useConfigmap: false
## etcd docker image available customizations
## https://github.com/bitnami/bitnami-docker-etcd#configuration
##
## Allow to use etcd without configuring RBAC authentication
allowNoneAuthentication: true
## Authentication parameteres
## https://github.com/bitnami/bitnami-docker-etcd#security
##
auth:
rbac:
enabled: true
## etcd root user password. The root user is always `root`.
# rootPassword:
## Name of the existing secret containing credentials for the root user.
# existingSecret:
client:
## Switch to encrypt client communication using TLS certificates
secureTransport: true
## Switch to automatically create the TLS certificates
useAutoTLS: false
## Switch to enable host authentication using TLS certificates. Requires existing secret.
enableAuthentication: true
## Name of the existing secret containing cert files for client communication.
# existingSecret:
peer:
## Switch to encrypt client communication using TLS certificates
secureTransport: true
## Switch to automatically create the TLS certificates
useAutoTLS: true
## Switch to enable host authentication using TLS certificates. Requires existing secret.
enableAuthentication: false
## Name of the existing secret containing cert files for client communication.
# existingSecret:
## Kubernetes Security Context
## https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
##
securityContext:
enabled: true
fsGroup: 1001
runAsUser: 1001
## Kubernetes configuration
## For minikube, set this to NodePort, elsewhere use LoadBalancer
##
service:
type: ClusterIP
port: 2379
peerPort: 2380
## etcd data Persistent Volume Storage Class
## If defined, storageClassName: <storageClass>
## If set to "-", storageClassName: "", which disables dynamic provisioning
## If undefined (the default) or set to null, no storageClassName spec is
## set, choosing the default provisioner. (gp2 on AWS, standard on
## GKE, AWS & OpenStack)
##
persistence:
enabled: false
# storageClass: "-"
accessModes:
- ReadWriteOnce
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/
##
resources:
# limits:
# cpu: 200m
# memory: 1Gi
# requests:
# memory: 256Mi
# cpu: 250m
## Configure extra options for liveness and readiness probes
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes)
livenessProbe:
enabled: false
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 2
successThreshold: 1
readinessProbe:
enabled: false
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 6
successThreshold: 1
+138
View File
@@ -0,0 +1,138 @@
## Bitnami etcd image version
## ref: https://hub.docker.com/r/bitnami/etcd/tags/
##
image:
registry: docker.io
repository: bitnami/etcd
tag: 3.3.8
## 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
##
pullPolicy: Always
## Optionally specify an array of imagePullSecrets.
## Secrets must be manually created in the namespace.
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
##
# pullSecrets:
# - myRegistrKeySecretName
## Set to true if you would like to see extra information on logs
## It turns BASH and NAMI debugging in minideb
## ref: https://github.com/bitnami/minideb-extras/#turn-on-bash-debugging
debug: false
updateStrategy: RollingUpdate
podManagementPolicy: OrderedReady
replicaCount: 1
## Take into account that if you use a config map you need to provide the whole configuration
## as the env vars defined in the statefulset.yaml will not be applied
##
useConfigmap: false
## etcd docker image available customizations
## https://github.com/bitnami/bitnami-docker-etcd#configuration
##
## Allow to use etcd without configuring RBAC authentication
allowNoneAuthentication: true
## Authentication parameteres
## https://github.com/bitnami/bitnami-docker-etcd#security
##
auth:
rbac:
enabled: true
## etcd root user password. The root user is always `root`.
# rootPassword:
## Name of the existing secret containing credentials for the root user.
# existingSecret:
client:
## Switch to encrypt client communication using TLS certificates
secureTransport: false
## Switch to automatically create the TLS certificates
useAutoTLS: false
## Switch to enable host authentication using TLS certificates. Requires existing secret.
enableAuthentication: false
## Name of the existing secret containing cert files for client communication.
# existingSecret:
peer:
## Switch to encrypt client communication using TLS certificates
secureTransport: false
## Switch to automatically create the TLS certificates
useAutoTLS: false
## Switch to enable host authentication using TLS certificates. Requires existing secret.
enableAuthentication: false
## Name of the existing secret containing cert files for client communication.
# existingSecret:
## Kubernetes Security Context
## https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
##
securityContext:
enabled: true
fsGroup: 1001
runAsUser: 1001
## Kubernetes configuration
## For minikube, set this to NodePort, elsewhere use LoadBalancer
##
service:
type: ClusterIP
port: 2379
peerPort: 2380
## etcd data Persistent Volume Storage Class
## If defined, storageClassName: <storageClass>
## If set to "-", storageClassName: "", which disables dynamic provisioning
## If undefined (the default) or set to null, no storageClassName spec is
## set, choosing the default provisioner. (gp2 on AWS, standard on
## GKE, AWS & OpenStack)
##
persistence:
enabled: false
# storageClass: "-"
accessModes:
- ReadWriteOnce
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/
##
resources:
# limits:
# cpu: 200m
# memory: 1Gi
# requests:
# memory: 256Mi
# cpu: 250m
## Configure extra options for liveness and readiness probes
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes)
livenessProbe:
enabled: false
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 2
successThreshold: 1
readinessProbe:
enabled: false
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 6
successThreshold: 1