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?
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
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'
})
}