Deploying Helm chart to local Kubernetes gives FileSystemException

I'm trying to deploy Elasticsearch 7.9.3 to my local Kubernetes cluster running in Docker Desktop.
I cloned the helm charts for Elasticsearch from GitHub ( helm-charts/elasticsearch at main · elastic/helm-charts (github.com) to include it as a subchart of an overarching umbrella chart.

When I try to deploy using the Helm chart, I see the following error in the logs of the Elasticsearch pod:

Likely root cause: java.nio.file.FileSystemException: /usr/share/elasticsearch/data/nodes/0: Not a directory
        at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:100)
        at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106)
        at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
        at java.base/sun.nio.fs.UnixFileSystemProvider.createDirectory(UnixFileSystemProvider.java:388)
        at java.base/java.nio.file.Files.createDirectory(Files.java:694)
        at java.base/java.nio.file.Files.createAndCheckIsDirectory(Files.java:801)
        at java.base/java.nio.file.Files.createDirectories(Files.java:787)
        at org.elasticsearch.env.NodeEnvironment.lambda$new$0(NodeEnvironment.java:274)
        at org.elasticsearch.env.NodeEnvironment$NodeLock.<init>(NodeEnvironment.java:211)
        at org.elasticsearch.env.NodeEnvironment.<init>(NodeEnvironment.java:271)
        at org.elasticsearch.node.Node.<init>(Node.java:344)
        at org.elasticsearch.node.Node.<init>(Node.java:277)
        at org.elasticsearch.bootstrap.Bootstrap$5.<init>(Bootstrap.java:227)
        at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:227)
        at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:393)
        at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:170)
        at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:161)
        at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:86)
        at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:127)
        at org.elasticsearch.cli.Command.main(Command.java:90)
        at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:126)
        at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:92)

It looks like it cannot create the mount path of the volume mount.
In statefulset.yaml of the Helm chart:

          {{- if .Values.persistence.enabled }}
          - name: "{{ template "elasticsearch.uname" . }}"
            mountPath: /usr/share/elasticsearch/data
          {{- end }}

How can I make the chart play nice with Docker Desktop?

I modified statefulset.yaml a little bit.

{{- if .Values.persistence.enabled }}
- name: "{{ template "elasticsearch.uname" . }}"
  mountPath: /run/desktop/mnt/host/c/data/elasticsearch
{{- end }}

Then the Elasticsearch pod gets created succesfully, but no files are being created in C:\data\Elasticsearch on the host (my laptop). So every time I run the Helm deployment, I have a clean sheet in terms of Elasticsearch data. How can I persist data between deployments?

Here's the stateful.yaml that gets deployed:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: dev-elasticsearch-master
  labels:
    heritage: "Helm"
    release: "dev"
    chart: "elasticsearch"
    app: "dev-elasticsearch-master"
  annotations:
    esMajorVersion: "7"
spec:
  serviceName: dev-elasticsearch-master-headless
  selector:
    matchLabels:
      app: "dev-elasticsearch-master"
  replicas: 1
  podManagementPolicy: Parallel
  updateStrategy:
    type: RollingUpdate
  volumeClaimTemplates:
  - metadata:
      name: dev-elasticsearch-master
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 100M
      storageClassName: hostPath
  template:
    metadata:
      name: "dev-elasticsearch-master"
      labels:
        heritage: "Helm"
        release: "dev"
        chart: "elasticsearch"
        app: "dev-elasticsearch-master"
      annotations:

    spec:
      securityContext:
        fsGroup: 1000
        runAsUser: 1000
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 1
            podAffinityTerm:
              topologyKey: kubernetes.io/hostname
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - "dev-elasticsearch-master"
      terminationGracePeriodSeconds: 120
      volumes:
      enableServiceLinks: true
      initContainers:
      - name: configure-sysctl
        securityContext:
          runAsUser: 0
          privileged: true
        image: "docker.elastic.co/elasticsearch/elasticsearch:7.9.3"
        imagePullPolicy: "IfNotPresent"
        command: ["sysctl", "-w", "vm.max_map_count=262144"]
        resources:
          {}

      containers:
      - name: "dev-elasticsearch"
        securityContext:
          capabilities:
            drop:
            - ALL
          runAsNonRoot: true
          runAsUser: 1000
        image: "docker.elastic.co/elasticsearch/elasticsearch:7.9.3"
        imagePullPolicy: "IfNotPresent"
        readinessProbe:
          exec:
            command:
              - sh
              - -c
              - |
                #!/usr/bin/env bash -e
                # If the node is starting up wait for the cluster to be ready (request params: "wait_for_status=yellow&timeout=1s" )
                # Once it has started only check that the node itself is responding
                START_FILE=/tmp/.es_start_file

                # Disable nss cache to avoid filling dentry cache when calling curl
                # This is required with Elasticsearch Docker using nss < 3.52
                export NSS_SDB_USE_CACHE=no

                http () {
                  local path="${1}"
                  local args="${2}"
                  set -- -XGET -s

                  if [ "$args" != "" ]; then
                    set -- "$@" $args
                  fi

                  if [ -n "${ELASTIC_USERNAME}" ] && [ -n "${ELASTIC_PASSWORD}" ]; then
                    set -- "$@" -u "${ELASTIC_USERNAME}:${ELASTIC_PASSWORD}"
                  fi

                  curl --output /dev/null -k "$@" "http://127.0.0.1:9200${path}"
                }

                if [ -f "${START_FILE}" ]; then
                  echo 'Elasticsearch is already running, lets check the node is healthy'
                  HTTP_CODE=$(http "/" "-w %{http_code}")
                  RC=$?
                  if [[ ${RC} -ne 0 ]]; then
                    echo "curl --output /dev/null -k -XGET -s -w '%{http_code}' \${BASIC_AUTH} http://127.0.0.1:9200/ failed with RC ${RC}"
                    exit ${RC}
                  fi
                  # ready if HTTP code 200, 503 is tolerable if ES version is 6.x
                  if [[ ${HTTP_CODE} == "200" ]]; then
                    exit 0
                  elif [[ ${HTTP_CODE} == "503" && "7" == "6" ]]; then
                    exit 0
                  else
                    echo "curl --output /dev/null -k -XGET -s -w '%{http_code}' \${BASIC_AUTH} http://127.0.0.1:9200/ failed with HTTP code ${HTTP_CODE}"
                    exit 1
                  fi

                else
                  echo 'Waiting for elasticsearch cluster to become ready (request params: "wait_for_status=yellow&timeout=1s" )'
                  if http "/_cluster/health?wait_for_status=yellow&timeout=1s" "--fail" ; then
                    touch ${START_FILE}
                    exit 0
                  else
                    echo 'Cluster is not yet ready (request params: "wait_for_status=yellow&timeout=1s" )'
                    exit 1
                  fi
                fi
          failureThreshold: 3
          initialDelaySeconds: 10
          periodSeconds: 10
          successThreshold: 3
          timeoutSeconds: 5
        ports:
        - name: http
          containerPort: 9200
        - name: transport
          containerPort: 9300
        resources:
          limits:
            cpu: 1000m
            memory: 512M
          requests:
            cpu: 100m
            memory: 512M
        env:
          - name: node.name
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: cluster.initial_master_nodes
            value: "dev-elasticsearch-master-0,"
          - name: discovery.seed_hosts
            value: "dev-elasticsearch-master-headless"
          - name: cluster.name
            value: "elasticsearch"
          - name: network.host
            value: "0.0.0.0"
          - name: ES_JAVA_OPTS
            value: "-Xmx128m -Xms128m"
          - name: node.data
            value: "true"
          - name: node.ingest
            value: "true"
          - name: node.master
            value: "true"
        volumeMounts:
          - name: "dev-elasticsearch-master"
            #mountPath: /usr/share/elasticsearch/data
            mountPath: /run/desktop/mnt/host/c/data/elasticsearch

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.