Kubernetes: Python script show containers

This blog is about a Python script which is based on Kubectl commands to display containers of each pod in a Kubernetes (k8s) cluster. AFAIK, there is no direct or simpler command to show the list of containers only.

There was a request to automate backups of all Postgres DB across all namespaces in the prod k8s clusters. I was very new to k8s and eager to learn how this stuff works. Then I was introduced to Minikube by Burr Sutter @burrsutter (burrsutter.com) who is a Java Champion and a true believer of Open Source, Community and developers. I dedicate this blog to Burr Sutter for his great work on imparting his knowledge and wisdom on K8s. I would recommend my followers and readers to go through this course who want to have deeper understanding of k8s and cloud native application development.

Coming back to the this simple Python script… This would go through each namepaces and pods to list all the containers in them. In this script, containers having word postgre is shown by matching the regex. Similarly it can be further customized according to the requirements.

#!/usr/bin/env python

from subprocess import Popen, PIPE
from re import search


def runcmd(list1):
    try:
        process = Popen(list1, stdout=PIPE, stderr=PIPE)
        stdout, stderr = process.communicate()
        return(stdout)
    except Exception as err:
        print("Error occured")
        return (stderr)


ns_cmd = ['sudo', 'kubectl', 'get', 'namespaces',
          '-o', 'jsonpath={.items[*].metadata.name}']

check = 'postgre' # Replace this with the search string
postgres = []
ns = runcmd(ns_cmd)
namespaces = ns.split()
print("namespace     >>       pod       >>     p_container")
for namespace in namespaces:
    p_cmd = ['sudo', 'kubectl', 'get', 'pods', '-n',
             namespace, '-o', 'jsonpath={.items[*].metadata.name}']

    # print(p_cmd)
    p = runcmd(p_cmd)
    # print(c)
    pods = p.split()
    for pod in pods:
        c_cmd = ['sudo', 'kubectl', 'get', 'pods', pod, '-n',
                 namespace, '-o', 'jsonpath={.spec.containers[*].name}']
        c = runcmd(c_cmd)

        containers = c.split()
        if containers:
            p_containers = [x for x in containers if search(check, x)]
            if p_containers:
                for p_container in p_containers:

                    print(namespace + ' >> ' + pod + ' >> ' + p_container)

OUTPUT:

debian:ben# minikube start --vm-driver=none --memory=3000mb --cpus=2
 ⚠️  minikube 1.3.1 is available! Download it: https://github.com/kubernetes/minikube/releases/tag/v/1.3.1
 💡  To disable this notice, run: 'minikube config set WantUpdateNotification false'
 😄  minikube v1.3.0 on Debian bullseye/sid (vbox/amd64)
 💡  Tip: Use 'minikube start -p ' to create a new cluster, or 'minikube delete' to delete this one.
 🔄  Starting existing none VM for "minikube" …
 ⌛  Waiting for the host to be provisioned …
 🐳  Preparing Kubernetes v1.15.2 on Docker 19.03.1 …
 🔄  Relaunching Kubernetes using kubeadm … 
 ⌛  Waiting for: apiserver proxy etcd scheduler controller dns
 🏄  Done! kubectl is now configured to use "minikube"

debian:ben# python list.py 
 namespace     >>       pod       >>     p_container
 alpha >> alpha-postgresql-0 >> alpha-postgresql
 beta >> beta-postgresql-0 >> beta-postgresql
 cuda >> cuda-postgresql-0 >> cuda-postgresql
 delta >> delta-postgresql-0 >> delta-postgresql

In the above output, minikube with single k8s cluster was started. I’ve created four namespaces viz alpha, beta, cuda and delta. In these namespaces created pods having postgresql containers. After running the above script we can see the simple and easy to read list of containers of each namespaces and pods.

I’ve further extended the logic to take backup of PostgreSQL with EMC Networker and DataDomain. Please reach out to me if you need the complete script.

Final words… for the new entrants into the k8s world, I would recommend you to read the blog YAML fundamentals for Kubernetes by Samrat Sen. In his first blog, he’s done a great job by explaining YAML in the most simplest way.