<p>I have a use case with elastic search for rack awareness, which requires me to identify the zone that a pod has been scheduled in.</p>

<p>I've seen many requests for this outside of SO, such as:</p>

<p><a href="https://github.com/kubernetes/kubernetes/issues/40610" rel="nofollow noreferrer">https://github.com/kubernetes/kubernetes/issues/40610</a></p>

<p>The zone is not exposed in the downward API due to it being a node label, not a pod label.</p>

<p>The two "answers" I have come up with are:</p>

<p>a) Curl request to the google metadata endpoint to retrieve the node from the compute engine metadata</p>

<p>b) Identify the node name via the downward API, and make a call to the Kube API with the node name to retrieve the node object, and use a tool such as JQ to filter the JSON response to get the zone. </p>

<p>I don't like option B due to it being more or less hardcoded against the API call, and I would need to provision a custom docker image with JQ and curl included. Option A feels a bit 'hacky' given it's not Kube native.</p>

<p>Are there any better solutions that I've missed?</p>

<p>Thanks in advance,</p>

dwillams782
<p>I don't particularly like doing it this way but I've yet to find a better answer, and none of the feature requests or bug reports on github seem to be going anywhere.</p>

<p>I opted to use a config map with a bash script which would do the curl request and some string manipulation, and then mount this into the container with volumes/volumeMounts and set a custom entry point to execute the script; injecting values into elasticsearch.yml, and then execute ES itself:</p>

<pre><code>apiVersion: v1
kind: ConfigMap
metadata:
  name: elastic
data:
  elastic.sh: |-
    set -e
    elasticConfig="/usr/share/elasticsearch/config/elasticsearch.yml"

    #this gives the us the node zone in the format projects/{projectnumber}/zones/{zone}
    zone=$(curl -sS http://metadata.google.internal/computeMetadata/v1/instance/zone -H 'Metadata-Flavor: Google')

    #Split and retain the text after the last /
    zone=${zone##*/}

    #Append it to elasticsearch.yml

    echo "\nnode.attr.zone: ${zone}" &gt;&gt; $elasticConfig
    echo "\ncluster.routing.allocation.awareness.attributes: zone" &gt;&gt; $elasticConfig

    echo "\ncluster.routing.allocation.awareness.force.zone.values: {{ .Values.elastic.shardAwareness.zones }}" &gt;&gt; $elasticConfig
</code></pre>

<p>I don't particularly like this solution as it adds unnecessary overhead and isn't kube native. Querying the kube API is possible but has its own set of complications and hacks. I hope one day either the downward API will expose zone / region labels, or that maybe I'm missing something and there is a better way than this after all.</p>

<p>If nothing else, perhaps this will help someone else and stop them wasting time googling for answers that don't seem to be out there!</p>
