Skip to content

Commit

Permalink
[elasticsearch] use security by default (#1384)
Browse files Browse the repository at this point in the history
This commit update Elasticsearch chart to use security by default.

- Adds a new Secret template for Elasticsearch password with a
  randomized password if `secret.password` isn't defined.

- Adds instructions to retrieve the password in Elasticsearch chart
  deployment notes.

- Also, remove usage of `ELASTIC_USERNAME` variable because it
  don't seem to be supported anymore by Elasticsearch 

The other charts will be updated in follow-up PRs to use the proper
credentials

Relates to elastic/helm-charts#1375
  • Loading branch information
jmlrt authored Oct 12, 2021
1 parent 0c8f77e commit 0bf3c7e
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 49 deletions.
13 changes: 9 additions & 4 deletions elasticsearch/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@ support multiple versions with minimal changes.
| `resources` | Allows you to set the [resources][] for the StatefulSet | see [values.yaml][] |
| `roles` | A list with the specific [roles][] for the `nodeGroup` | see [values.yaml][] |
| `schedulerName` | Name of the [alternate scheduler][] | `""` |
| `secret.enabled` | Enable Secret creation for Elasticsearch credentials | `true` |
| `secret.password` | Initial password for the elastic user | `""` (generated randomly) |
| `secretMounts` | Allows you easily mount a secret as a file inside the StatefulSet. Useful for mounting certificates and other secrets. See [values.yaml][] for an example | `[]` |
| `securityContext` | Allows you to set the [securityContext][] for the container | see [values.yaml][] |
| `service.annotations` | [LoadBalancer annotations][] that Kubernetes will use for the service. This will configure load balancer if `service.type` is `LoadBalancer` | `{}` |
Expand Down Expand Up @@ -260,9 +262,12 @@ sufficient.

### How to deploy clusters with security (authentication and TLS) enabled?

This Helm chart can use existing [Kubernetes secrets][] to setup
credentials or certificates for examples. These secrets should be created
outside of this chart and accessed using [environment variables][] and volumes.
This Helm chart can generate a [Kubernetes Secret][] or use an existing one to
setup Elastic credentials.

This Helm chart can use existing [Kubernetes Secret][] to setup Elastic
certificates for example. These secrets should be created outside of this chart
and accessed using [environment variables][] and volumes.

An example of Elasticsearch cluster using security can be found in
[examples/security][].
Expand Down Expand Up @@ -438,7 +443,7 @@ about our development and testing process.
[jvm heap size]: https://www.elastic.co/guide/en/elasticsearch/reference/current/heap-size.html
[hostAliases]: https://kubernetes.io/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases/
[kind]: https://github.com/elastic/helm-charts/tree/master/elasticsearch/examples/kubernetes-kind
[kubernetes secrets]: https://kubernetes.io/docs/concepts/configuration/secret/
[kubernetes secret]: https://kubernetes.io/docs/concepts/configuration/secret/
[labels]: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
[lifecycle hooks]: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/
[loadBalancer annotations]: https://kubernetes.io/docs/concepts/services-networking/service/#ssl-support-on-aws
Expand Down
6 changes: 4 additions & 2 deletions elasticsearch/templates/NOTES.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
1. Watch all cluster members come up.
$ kubectl get pods --namespace={{ .Release.Namespace }} -l app={{ template "elasticsearch.uname" . }} -w
{{- if .Values.tests.enabled -}}
2. Test cluster health using Helm test.
2. Retrieve elastic user's password.
$ kubectl get secrets --namespace={{ .Release.Namespace }} {{ template "elasticsearch.uname" . }}-credentials -ojsonpath='{.data.password}' | base64 -d
{{- if .Values.tests.enabled }}
3. Test cluster health using Helm test.
$ helm --namespace={{ .Release.Namespace }} test {{ .Release.Name }}
{{- end -}}
23 changes: 23 additions & 0 deletions elasticsearch/templates/secret.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{{- if .Values.secret.enabled -}}
{{- $passwordValue := (randAlphaNum 16) | b64enc | quote }}
apiVersion: v1
kind: Secret
metadata:
name: {{ template "elasticsearch.uname" . }}-credentials
labels:
heritage: {{ .Release.Service | quote }}
release: {{ .Release.Name | quote }}
chart: "{{ .Chart.Name }}"
app: "{{ template "elasticsearch.uname" . }}"
{{- range $key, $value := .Values.labels }}
{{ $key }}: {{ $value | quote }}
{{- end }}
type: Opaque
data:
username: {{ "elastic" | b64enc }}
{{- if .Values.secret.password }}
password: {{ .Values.secret.password | b64enc }}
{{- else }}
password: {{ $passwordValue }}
{{- end }}
{{- end }}
18 changes: 15 additions & 3 deletions elasticsearch/templates/statefulset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,13 @@ spec:
- -c
- |
#!/usr/bin/env bash -e
# Exit if ELASTIC_PASSWORD in unset
if [ -z "${ELASTIC_PASSWORD}" ]; then
echo "ELASTIC_PASSWORD variable is missing, exiting"
exit 1
fi
# If the node is starting up wait for the cluster to be ready (request params: "{{ .Values.clusterHealthCheckParams }}" )
# Once it has started only check that the node itself is responding
START_FILE=/tmp/.es_start_file
Expand All @@ -248,9 +255,7 @@ spec:
set -- "$@" $args
fi
if [ -n "${ELASTIC_USERNAME}" ] && [ -n "${ELASTIC_PASSWORD}" ]; then
set -- "$@" -u "${ELASTIC_USERNAME}:${ELASTIC_PASSWORD}"
fi
set -- "$@" -u "elastic:${ELASTIC_PASSWORD}"
curl --output /dev/null -k "$@" "{{ .Values.protocol }}://127.0.0.1:{{ .Values.httpPort }}${path}"
}
Expand Down Expand Up @@ -313,6 +318,13 @@ spec:
value: "{{ .Values.clusterName }}"
- name: network.host
value: "{{ .Values.networkHost }}"
{{- if .Values.secret.enabled }}
- name: ELASTIC_PASSWORD
valueFrom:
secretKeyRef:
name: {{ template "elasticsearch.uname" . }}-credentials
key: password
{{- end }}
{{- if .Values.esJavaOpts }}
- name: ES_JAVA_OPTS
value: "{{ .Values.esJavaOpts }}"
Expand Down
85 changes: 45 additions & 40 deletions elasticsearch/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ envFrom: []
# - configMapRef:
# name: config-map

# Disable it to use your own elastic-credential Secret.
secret:
enabled: true
password: "" # generated randomly if not defined

# A list of secrets and their paths to mount inside the pod
# This is useful for mounting certificates for security and for mounting
# the X-Pack license
Expand All @@ -69,7 +74,7 @@ imageTag: "8.0.0-SNAPSHOT"
imagePullPolicy: "IfNotPresent"

podAnnotations: {}
# iam.amazonaws.com/role: es-cluster
# iam.amazonaws.com/role: es-cluster

# additionals labels
labels: {}
Expand All @@ -85,17 +90,17 @@ resources:
memory: "2Gi"

initResources: {}
# limits:
# cpu: "25m"
# # memory: "128Mi"
# requests:
# cpu: "25m"
# memory: "128Mi"
# limits:
# cpu: "25m"
# # memory: "128Mi"
# requests:
# cpu: "25m"
# memory: "128Mi"

networkHost: "0.0.0.0"

volumeClaimTemplate:
accessModes: [ "ReadWriteOnce" ]
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 30Gi
Expand Down Expand Up @@ -133,23 +138,23 @@ persistence:
annotations: {}

extraVolumes: []
# - name: extras
# emptyDir: {}
# - name: extras
# emptyDir: {}

extraVolumeMounts: []
# - name: extras
# mountPath: /usr/share/extras
# readOnly: true
# - name: extras
# mountPath: /usr/share/extras
# readOnly: true

extraContainers: []
# - name: do-something
# image: busybox
# command: ['do', 'something']
# - name: do-something
# image: busybox
# command: ['do', 'something']

extraInitContainers: []
# - name: do-something
# image: busybox
# command: ['do', 'something']
# - name: do-something
# image: busybox
# command: ['do', 'something']

# This is the PriorityClass settings as defined in
# https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass
Expand Down Expand Up @@ -207,7 +212,7 @@ podSecurityContext:
securityContext:
capabilities:
drop:
- ALL
- ALL
# readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
Expand Down Expand Up @@ -241,8 +246,8 @@ tolerations: []
ingress:
enabled: false
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
hosts:
- host: chart-example.local
paths:
Expand All @@ -257,24 +262,24 @@ fullnameOverride: ""
healthNameOverride: ""

lifecycle: {}
# preStop:
# exec:
# command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"]
# postStart:
# exec:
# command:
# - bash
# - -c
# - |
# #!/bin/bash
# # Add a template to adjust number of shards/replicas
# TEMPLATE_NAME=my_template
# INDEX_PATTERN="logstash-*"
# SHARD_COUNT=8
# REPLICA_COUNT=1
# ES_URL=http://localhost:9200
# while [[ "$(curl -s -o /dev/null -w '%{http_code}\n' $ES_URL)" != "200" ]]; do sleep 1; done
# curl -XPUT "$ES_URL/_template/$TEMPLATE_NAME" -H 'Content-Type: application/json' -d'{"index_patterns":['\""$INDEX_PATTERN"\"'],"settings":{"number_of_shards":'$SHARD_COUNT',"number_of_replicas":'$REPLICA_COUNT'}}'
# preStop:
# exec:
# command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"]
# postStart:
# exec:
# command:
# - bash
# - -c
# - |
# #!/bin/bash
# # Add a template to adjust number of shards/replicas
# TEMPLATE_NAME=my_template
# INDEX_PATTERN="logstash-*"
# SHARD_COUNT=8
# REPLICA_COUNT=1
# ES_URL=http://localhost:9200
# while [[ "$(curl -s -o /dev/null -w '%{http_code}\n' $ES_URL)" != "200" ]]; do sleep 1; done
# curl -XPUT "$ES_URL/_template/$TEMPLATE_NAME" -H 'Content-Type: application/json' -d'{"index_patterns":['\""$INDEX_PATTERN"\"'],"settings":{"number_of_shards":'$SHARD_COUNT',"number_of_replicas":'$REPLICA_COUNT'}}'

sysctlInitContainer:
enabled: true
Expand Down

0 comments on commit 0bf3c7e

Please sign in to comment.