Virtual memory
editVirtual memory
editBy default, Elasticsearch uses memory mapping (mmap
) to efficiently access indices.
Usually, default values for virtual address space on Linux distributions are too low for Elasticsearch to work properly, which may result in out-of-memory exceptions. This is why the quickstart example disables mmap
through the node.store.allow_mmap: false
setting. For production workloads, it is strongly recommended to increase the kernel setting vm.max_map_count
to 262144
and leave node.store.allow_mmap
unset.
The kernel setting vm.max_map_count=262144
can be set on the host directly, by a dedicated init container which must be privileged, or a dedicated Daemonset.
For more information, check the Elasticsearch documentation on Virtual memory.
Optionally, you can select a different type of file system implementation for the storage. For possible options, check the store module documentation.
spec: nodeSets: - name: default count: 3 config: index.store.type: niofs
Using an Init Container to set virtual memory
editTo add an init container that changes the host kernel setting before your Elasticsearch container starts, you can use the following example Elasticsearch spec:
cat <<EOF | kubectl apply -f - apiVersion: elasticsearch.k8s.elastic.co/v1 kind: Elasticsearch metadata: name: quickstart spec: version: 8.16.1 nodeSets: - name: default count: 3 podTemplate: spec: initContainers: - name: sysctl securityContext: privileged: true runAsUser: 0 command: ['sh', '-c', 'sysctl -w vm.max_map_count=262144'] EOF
Note that this requires the ability to run privileged containers, which is likely not the case on many secure clusters.
Using a Daemonset to set virtual memory
editTo use a Daemonset that changes the host kernel setting on all nodes:
cat <<EOF | kubectl apply -n elastic-system -f - apiVersion: apps/v1 kind: DaemonSet metadata: name: max-map-count-setter labels: k8s-app: max-map-count-setter spec: selector: matchLabels: name: max-map-count-setter template: metadata: labels: name: max-map-count-setter spec: initContainers: - name: max-map-count-setter image: docker.io/bash:5.2.15 resources: limits: cpu: 100m memory: 32Mi securityContext: privileged: true runAsUser: 0 command: ['/usr/local/bin/bash', '-e', '-c', 'echo 262144 > /proc/sys/vm/max_map_count'] containers: - name: sleep image: gcr.io/google-containers/pause-amd64:3.2 EOF
To run an Elasticsearch instance that waits for the kernel setting to be in place:
cat <<EOF | kubectl apply -f -
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
name: elasticsearch-sample
spec:
version: 8.16.1
nodeSets:
- name: default
count: 1
# Only uncomment the below section if you are not using the previous Daemonset to set max_map_count.
# config:
# node.store.allow_mmap: false
podTemplate:
spec:
# This init container ensures that the max_map_count
setting has been applied before starting Elasticsearch.
# This is not required, but is encouraged when using the previous Daemonset to set max_map_count.
# Do not use this if setting config.node.store.allow_mmap: false
initContainers:
- name: max-map-count-check
command: ['sh', '-c', "while true; do mmc=$(cat /proc/sys/vm/max_map_count); if [ ${mmc} -eq 262144 ]; then exit 0; fi; sleep 1; done"]
EOF