<p>I am trying to load <strong>my existing</strong> local <strong>elastic search</strong>  indices into <strong>kubernetes</strong> (version - <strong>minikube v1.9.2</strong>) elastic search pod.</p>

<p>What I finally understood is I have to use <strong>mountpath</strong> and <strong>hostpath</strong> combination to do that. Additionlay if I want to provide a custom index file (not the default one), then I have to use a <strong>configMap</strong> to override <strong>path.data</strong> of  <strong>config/elasticsearch.yml</strong></p>

<p>I did those as below and it created a directory in  <strong>mount path</strong> and update <strong>config/elasticsearch.yml</strong> file but a <strong>mount path</strong> directory <strong>does not</strong> contain the host path directory’s content.</p>

<p>I could not figure out the reason behind it. Could some one let me know what am I doing wrong here?</p>

<p>Then went I head and <strong>manually</strong> copied indexes from local host to kubernetes pod using</p>

<blockquote>
  <p><em>kubectl cp localelasticsearhindexdirectory podname:/data/elk/</em></p>
</blockquote>

<p>But then I tried do a elastic search and it gives me a <strong>empty result</strong> ( even though index manually copied).</p>

<p>If I use the same index  with a local elastic search ( not on kubernetes) then I can get the result.</p>

<p>Could someone please give some advice to diagnose following issues</p>

<ol>
<li>Why mount path does not have the hostpjths content</li>
<li>How to debug / What steps should I follow understand why it’s not able to get the result with the elasticsearch on pod?</li>
</ol>

<pre><code>kind: Deployment
metadata:
  name: elasticsearch
spec:
  selector:
    matchLabels:
      run: elasticsearch
  replicas: 1
  template:
    metadata:
      labels:
        run: elasticsearch
    spec:
      containers:
        - image: docker.elastic.co/elasticsearch/elasticsearch:6.6.1
          name: elasticsearch
          imagePullPolicy: IfNotPresent
          env:
            - name: discovery.type
              value: single-node
            - name: cluster.name
              value: elasticsearch
          ports:
          - containerPort: 9300
            name: nodes
          - containerPort: 9200
            name: client
          volumeMounts:
          - name: storage
            mountPath: /data/elk
          - name: config-volume
            mountPath: /usr/share/elasticsearch/config/elasticsearch.yml
            subPath: elasticsearch.yml
      volumes:
      - name: config-volume
        configMap:
         name: elasticsearch-config
      - name: storage
        hostPath:
         path: ~/elasticsearch-6.6.1/data     
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: elasticsearch-config
data:
  elasticsearch.yml: |
    cluster:
      name: ${CLUSTER_NAME:elasticsearch-default}

    node:
      master: ${NODE_MASTER:true}
      data: ${NODE_DATA:true}
      name: ${NODE_NAME:node-1}
      ingest: ${NODE_INGEST:true}
      max_local_storage_nodes: ${MAX_LOCAL_STORAGE_NODES:1}

    processors: ${PROCESSORS:1}

    network.host: ${NETWORK_HOST:_site_}

    path:
      data: ${DATA_PATH:"/data/elk"}
      repo: ${REPO_LOCATIONS:[]}

    bootstrap:
      memory_lock: ${MEMORY_LOCK:false}

    http:
      enabled: ${HTTP_ENABLE:true}
      compression: true
      cors:
        enabled: true
        allow-origin: "*"

    discovery:
      zen:
        ping.unicast.hosts: ${DISCOVERY_SERVICE:elasticsearch-discovery}
        minimum_master_nodes: ${NUMBER_OF_MASTERS:1}

    xpack:
      license.self_generated.type: basic            ```


**service.yaml**


```apiVersion: v1
kind: Service
metadata:
  name: elasticsearch
  labels:
    service: elasticsearch
spec:
  ports:
    - name: client
      port: 9200
      protocol: TCP
      targetPort: 9200
    - name: nodes
      port: 9300
      protocol: TCP
      targetPort: 9300
  type: NodePort

  selector:
    run: elasticsearch```
</code></pre>

<p>Solution in <a href="https://stackoverflow.com/questions/38682114/hostpath-with-minikube-kubernetes">HostPath with minikube - Kubernetes</a> worked for me.
To mount a local directory into a pod in minikube (version - v1.9.2), you have to mount that local directory into minikube then use minikube mounted path in hostpath
(<a href="https://minikube.sigs.k8s.io/docs/handbook/mount/" rel="nofollow noreferrer">https://minikube.sigs.k8s.io/docs/handbook/mount/</a>).</p>

<pre><code> minikube mount ~/esData:/indexdata
📁  Mounting host path /esData into VM as /indexdata ...
    ▪ Mount type:   &lt;no value&gt;
    ▪ User ID:      docker
    ▪ Group ID:     docker
    ▪ Version:      9p2000.L
    ▪ Message Size: 262144
    ▪ Permissions:  755 (-rwxr-xr-x)


       ▪ Options:      map[]
        ▪ Bind Address: 192.168.5.6:55230
    🚀  Userspace file server: ufs starting
    ✅  Successfully mounted ~/esData to /indexdata

📌  NOTE: This process must stay alive for the mount to be accessible ...
</code></pre>

<p><em>You have to run minikube mount in a separate terminal because it starts a process and stays there until you unmount.</em></p>

<p>Instead of doing it as Deployment as in the original question, now I am doing it as Statefulset but the same solution will work for Deployment also.</p>

<p>Another issue which I faced during mounting was elastic search server pod was throwing  <code>java.nio.file.AccessDeniedException: /usr/share/elasticsearch/data/nodes</code> . Then I saw <a href="https://stackoverflow.com/questions/56150949/how-to-do-chown-10001000-on-the-elasticsearch-data-directory-in-kubernetes">here</a> that I have to use <strong>initContainers</strong> to set full permission in /usr/share/elasticsearch/data/nodes.</p>

<p>Please see my final yaml</p>

<pre><code>apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: elasticsearch
spec:
  serviceName: "elasticsearch"
  replicas: 1
  selector:
    matchLabels:
      app: elasticsearch
  template:
    metadata:
      labels:
        app: elasticsearch
    spec:
      initContainers:
      - name: set-permissions
        image: registry.hub.docker.com/library/busybox:latest
        command: ['sh', '-c', 'mkdir -p /usr/share/elasticsearch/data &amp;&amp; chown 1000:1000 /usr/share/elasticsearch/data' ]
        volumeMounts:
        - name: data
          mountPath: /usr/share/elasticsearch/data
      containers:
      - name: elasticsearch
        image: docker.elastic.co/elasticsearch/elasticsearch:6.6.1
        env:
        - name: discovery.type
          value: single-node
        ports:
        - containerPort: 9200
          name: client
        - containerPort: 9300
          name: nodes
        volumeMounts:
        - name: data
          mountPath: /usr/share/elasticsearch/data
      volumes:
      - name: data
        hostPath:
          path: /indexdata
---
apiVersion: v1
kind: Service
metadata:
  name: elasticsearch
  labels:
    service: elasticsearch
spec:
  ports:
  - port: 9200
    name: client
  - port: 9300
    name: nodes
  type: NodePort  
  selector:
    app: elasticsearch
</code></pre>
