Custom-columns of Endpoints in Kubernetes

103 views Asked by At

Good day, thank you for your time.

I try to extract the custom column value from endpoints to get a name and IP address like this:

kubectl get endpoints -o custom-columns=NAME:.metadata.name,ENDPOINTS:subsets[0].addresses[0][0].ip

but I got no result, trying different combinations of this command.

The Endpoints format:

Name: "mysvc",
 Subsets: [
   {
     Addresses: [{"ip": "10.10.1.1"}, {"ip": "10.10.2.2"}],
     Ports: [{"name": "a", "port": 8675}, {"name": "b", "port": 309}]
   },
   {
     Addresses: [{"ip": "10.10.3.3"}],
     Ports: [{"name": "a", "port": 93}, {"name": "b", "port": 76}]
   },
]

Thank you for your time and attention. Best regards Andrei

2

There are 2 answers

3
DazWilkin On BEST ANSWER

IIUC, you want the metadata.name and all (!?) ip's?

subset contains an array addresses so:

You can't addresses[0][0]

But you could addresses[0].ip

Or, if you want all of the IPs, you could addresses[*].ip

kubectl get endpoints \
--output=custom-columns=NAME:.metadata.name,ENDPOINTS:subsets[0].addresses[].ip \
--all-namespaces

Or:

kubectl get endpoints \
--output=custom-columns=NAME:.metadata.name,ENDPOINTS:subsets[0].addresses[*].ip \
--all-namespaces
0
Андрей Белый On

In case someone is searching to accomplish the result of which ingress belongs to which pod there is the code:

import subprocess
import json
import pandas as pd


def get_kubectl_data(command):
    result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, text=True)
    if result.returncode != 0:
        print(f"Error executing '{command}': {result.stderr}")
        return None
    try:
        return json.loads(result.stdout)
    except json.JSONDecodeError as e:
        print(f"Error decoding JSON from '{command}': {e}")
        return None


def main():
    # Fetching Ingresses
    ingresses = get_kubectl_data("kubectl get ingress --all-namespaces -o json")

    # Parsing data
    data = []
    for ingress in ingresses['items']:
        ingress_name = ingress['metadata']['name']
        namespace = ingress['metadata']['namespace']
        ingress_address = ', '.join([addr.get('ip', '') or addr.get('hostname', '') for addr in
                                     ingress.get('status', {}).get('loadBalancer', {}).get('ingress', [])])

        for rule in ingress.get('spec', {}).get('rules', []):
            hostname = rule.get('host', 'N/A')  # Extract hostname
            for path in rule.get('http', {}).get('paths', []):
                service_name = path.get('backend', {}).get('service', {}).get('name')
                if service_name:
                    # Fetching pods for each service
                    selector_data = get_kubectl_data(f"kubectl get svc {service_name} -n {namespace} -o json")
                    if selector_data:
                        selector = selector_data.get('spec', {}).get('selector', {})
                        selector_str = ",".join(f"{k}={v}" for k, v in selector.items())
                        pods = get_kubectl_data(f"kubectl get pods -n {namespace} -l {selector_str} -o json")
                        if pods:
                            for pod in pods.get('items', []):
                                pod_name = pod['metadata']['name']
                                data.append([pod_name, service_name, ingress_name, ingress_address, hostname])
                        else:
                            print(f"Skipping pods for service {service_name} as they could not be fetched.")
                    else:
                        print(f"Skipping service {service_name} as it could not be fetched.")

    # Creating DataFrame
    df = pd.DataFrame(data, columns=['Pod', 'Service', 'Ingress', 'Ingress Address', 'Hostname'])

    # Writing to Excel
    df.to_excel('k8s_data_prod.xlsx', index=False)


if __name__ == "__main__":
    main()