nodejs api that returns the region and zone where the pod is running in a GCP K8S cluster

3/18/2018

I have nodejs code running inside a pod. From inside the pod I want to find the zone of the node where this pod is running. What is the best way do do that? Do I need extra permissions?

-- gae123
google-cloud-platform
google-kubernetes-engine
kubernetes

2 Answers

3/18/2018

You can use failure-domain.beta.kubernetes.io/region and failure-domain.beta.kubernetes.io/zone labels of the pod to getting its region and AZ.

But, please keep in mind, that:

Only GCE and AWS are currently supported automatically (though it is easy to add similar support for other clouds or even bare metal, by simply arranging for the appropriate labels to be added to nodes and volumes).

To get access to labels, you can use DownwardAPI for attaching a Volume with your current labels and annotations of the pod. You don't need any extra permissions for use it, just mount them as a volume.

Here is an example from a documentation:

apiVersion: v1 kind: Pod metadata: name: kubernetes-downwardapi-volume-example labels: zone: us-est-coast cluster: test-cluster1 rack: rack-22 annotations: build: two builder: john-doe spec: containers: - name: client-container image: k8s.gcr.io/busybox command: ["sh", "-c"] args: - while true; do if [[ -e /etc/podinfo/labels ]]; then echo -en '\n\n'; cat /etc/podinfo/labels; fi; if [[ -e /etc/podinfo/annotations ]]; then echo -en '\n\n'; cat /etc/podinfo/annotations; fi; sleep 5; done; volumeMounts: - name: podinfo mountPath: /etc/podinfo readOnly: false volumes: - name: podinfo downwardAPI: items: - path: "labels" fieldRef: fieldPath: metadata.labels - path: "annotations" fieldRef: fieldPath: metadata.annotations

When you have a mounted volume with labels, you can read a file /etc/labels which will contain information about AZ and Region as a Key-Pairs, like this: failure-domain.beta.kubernetes.io/region=us-east-1 failure-domain.beta.kubernetes.io/zone=us-east-1c

-- Anton Kostenko
Source: StackOverflow

3/21/2018

I have not been able to find a library but I post the code that does it below. The getContent function was slightly adapted from this post This code should work inside a GKE pod or and GCE host.

Use it as following:

const gcp = require('./gcp.js')
gcp.zone().then(z  => console.log('Zone is: ' + z))

Module: gcp.js

const getContent = function(lib, options) {
  // return new pending promise
  return new Promise((resolve, reject) => {
    // select http or https module, depending on reqested url
    const request = lib.get(options, (response) => {
      // handle http errors
      if (response.statusCode < 200 || response.statusCode > 299) {
         reject(new Error('Failed to load page, status code: ' + response.statusCode));
       }
      // temporary data holder
      const body = [];
      // on every content chunk, push it to the data array
      response.on('data', (chunk) => body.push(chunk));
      // we are done, resolve promise with those joined chunks
      response.on('end', () => resolve(body.join('')));
    });
    // handle connection errors of the request
    request.on('error', (err) => reject(err))
    })
};

exports.zone = () => {
    return getContent(
        require('http'),
        {
            hostname: 'metadata.google.internal',
            path: '/computeMetadata/v1/instance/zone',
            headers: {
                'Metadata-Flavor': 'Google'
            },
            method: 'GET'
        }) 
}
-- gae123
Source: StackOverflow