9

How can I get a list of the pods running on the same Kubernetes node as my own (privileged) pod, using the official Python Kubernetes client? That is, how can a pod identify the concrete Kubernetes node it is running on and then query for a full list of pods on this node only?

TheDiveO
  • 2,183
  • 2
  • 19
  • 38
  • 2
    If this is a dumb question, then please tell why instead of useless downvoting. I searched SO and the Kubernetes documents first, but could not find any indication how an in-pod Python Kubernetes client can detect the node it is running on. So, you -1ers, be helpful instead of spiteful. Otherwise, you're making SO a bad place to ask serious questions. – TheDiveO Oct 12 '18 at 19:46
  • I don't think this is necessarily a dumb question, it's just all the information is available very easily with a few google searches. – jaxxstorm Oct 12 '18 at 22:17
  • Just curious - why do you need pods details on the same node? – Praveen Sripati Oct 13 '18 at 00:28
  • @jaxxstorm please don't assume lazyness or dumbness in searching, but as I'm new to the stuff, the results I googled weren't yet falling into place. For this reason I decided to ask without listing the pieces since I wanted to make sure that I also get answers that might take a different solution route. Turns out that SO setns to be hostile to this way, and prefers spilling out the details of a possible solution in the question...? – TheDiveO Oct 13 '18 at 06:04
  • @PraveenSripati that's for virtual network layer 2/3 diagnosis on the node hosts. – TheDiveO Oct 13 '18 at 06:17
  • @jaxxstorm - typically I look for what has been done by whomever has posted the query. In this case a snippet of Python code which hasn't worked. This way there is a better probability of getting a response. – Praveen Sripati Oct 13 '18 at 06:27

1 Answers1

11

I'm making the assumption here that you've deployed a pod to the cluster, and now you're trying to query the node it's running on.

This is actually two distinct problems:

That is, how can a pod identify the concrete Kubernetes node it is running on

There's two ways you can do this, but they both involved the downward API. You can either push the pod name down or push the node name down (or both). You need to do this first to enable the lookups you need. So the pod running the kubernetes python client needs to be deployed like so:

apiVersion: v1
kind: Pod
metadata:
  name: example-app
spec:
  containers:
    - name: python-kubernetes-client
      image: my-image
      command: [ "start_my_app" ]
      env:
        - name: MY_NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: MY_POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
  restartPolicy: Never

Okay, so now you have the pod information and the node information available to your running pod.

and then query for a full list of pods on this node only

Now that you know the node name the pod is running on, querying for the pods running on it is relatively straightforward using the python API:

#!/usr/bin/env python
from kubernetes import client, config
import os

def main():

    # it works only if this script is run by K8s as a POD
    config.load_incluster_config()
    # use this outside pods
    # config.load_kube_config()

    # grab the node name from the pod environment vars
    node_name = os.environ.get('MY_NODE_NAME', None)

    v1 = client.CoreV1Api()
    print("Listing pods with their IPs on node: ", node_name)
    # field selectors are a string, you need to parse the fields from the pods here
    field_selector = 'spec.nodeName='+node_name
    ret = v1.list_pod_for_all_namespaces(watch=False, field_selector=field_selector)
    for i in ret.items:
        print("%s\t%s\t%s" %
              (i.status.pod_ip, i.metadata.namespace, i.metadata.name))


if __name__ == '__main__':
    main()
jaxxstorm
  • 12,422
  • 5
  • 57
  • 67
  • I had hoped that there would be an always existing env var, similar to the remote api server address information. But that clarifies to me that this metadata needs to be explicitly handed down into the Pod ... so I need to see how Rancher v2 allows me to add that spec env references. Thank you very much. – TheDiveO Oct 13 '18 at 05:59
  • For the field selector: might there be some escaping needed for the nose name, or does the noise make syntax guarantee that the selector string is syntactically valid for all noise names without any working or escaping? – TheDiveO Oct 13 '18 at 06:07
  • You’ll have to do the escaping yourself, it’s just a node name, it can’t be syntactically invalid – jaxxstorm Oct 13 '18 at 18:21
  • The problem I now face on a Minikube/Rancher2 setup is that the Pod doesn't have the required API access rights for listing pods, so I need to set up the RBAC and enable the Pod to those roles/role binding. Unfortunately, I'm left as to how to do: I've found several RBAC posts but I yet lack the understanding how to enable to Pod/PodSpec to use those roles/role bindings? – TheDiveO Oct 14 '18 at 15:45
  • Please post another question, that’s an entirely different topic – jaxxstorm Oct 14 '18 at 15:57
  • I think you can load the kubeconfig that has all thoase rights into you python pod as secret volume so that your python script can use that and get the list of pods – Ijaz Ahmad Oct 14 '18 at 19:39
  • @IjazKhan no, that's not the way to do this. – jaxxstorm Oct 14 '18 at 19:42
  • @jaxxstorm then whats the purpose of configmaps and secrets? he needs that to access the kubernetes API to get the pods – Ijaz Ahmad Oct 14 '18 at 19:46
  • that's completely unrelated to the problem. The issue is that the default service account in the pod doesn't have the necessary RBAC permissions to query the API. Setting a Role and RoleBinding will solve the problem. – jaxxstorm Oct 14 '18 at 19:59
  • solved the RBAC permission setup; would it make sense to document it? And if so, how? – TheDiveO Oct 17 '18 at 08:39
  • @IjazKhan the pod needs to be tied to a ServiceAccount that lives in the same namespace as the pod. The ServiceAccount then gets via a ClusterRoleBinding a ClusterRole with get/list access to pods. It needs to be a ClusterRole/ClusterRoleBinding as otherwise the pod cannot list accross namespaces, but only within the namespace it lives in. – TheDiveO Oct 17 '18 at 08:41