others-prepare for cks exam with me 15: How to print docker images of all pods in kubernetes?

1. Purpose

In this post, I would continue to write about preparing for the CKS (Certified Kubernetes Security Specialist) exam. I would write my own notes about the exam, and you can refer to these articles to prepare your own.

List of the series of posts:

-prepare for cks exam with me 1: Linux user and group management

-prepare for cks exam with me 2: Linux ssh hardening

-prepare for cks exam with me 3: Linux remove obsolete packages and services

-prepare for cks exam with me 4: Linux kernal hardening

-prepare for cks exam with me 5: Linux UFW(Uncomplicated firewall)

-prepare for cks exam with me 6: Seccomp in Linux, Docker and Kubernetes

-prepare for cks exam with me 7: Apparmor in Linux, Docker and Kubernetes

-prepare for cks exam with me 8: Security context in Kubernetes

-prepare for cks exam with me 9: Admission controllers in Kubernetes

-prepare for cks exam with me 10: Pod security policy in Kubernetes

-prepare for cks exam with me 11: Open policy agent in Kubernetes

-prepare for cks exam with me 12: Secrets in Kubernetes

-prepare for cks exam with me 13: Container runtimes(gvisor/kata containers) in Kubernetes

-prepare for cks exam with me 14: Container Image security in Docker and Kubernetes

-prepare for cks exam with me 15: How to print docker images of all pods in kubernetes

In this post, I would demo how to print docker images of all pods in kubernetes.

2. Environment

  • Kubernetes 1.18+
  • CKS
  • Ubuntu System

3. The solution

3.1 The problem

Suppose we have some pods in default namespace in kubernetes:

➜  ~ kubectl get pods
NAME                                      READY   STATUS             RESTARTS   AGE
mytomcat-c64f9c47b                        1/1     Running            0          20d
nfs-client-provisioner-5baabbb7b8-lndm5   1/1     Running            0          54d
redis-68123498bb-x6gzk                    1/1     Running            0          14d

Now if we want to get all the docker image names from these pods, we can do this:

➜  ~ kubectl describe pod redis-68123498bb|grep Image
    Image:         10.2.1.1:8443/base/redis:latest
    Image ID:      docker-pullable://10.2.1.1:8443/base/redis@sha256:c23e824688f38323

we must repeat the above command three times, it’s so annoying. How to show all the docker image names in one command?

3.2 The solution

We can print the docker image names of all the pods in the namespace with one command:

➜  ~ kubectl get pods -o json|jq -r '.items[].spec.containers[].image'
10.2.1.1:8443/library/tomcat:8.0
10.2.1.1:8443/quay.io/external_storage/nfs-client-provisioner:latest
10.2.1.1:8443/base/redis:latest
➜  ~

3.3 The theory

Why did the below command work?

➜  ~ kubectl get pods -o json|jq -r '.items[].spec.containers[].image'

First, we need a json string of the pods:

➜  ~ kubectl get pods -o json

{
    "apiVersion": "v1",
    "items": [
        {
            "apiVersion": "v1",
            "kind": "Pod",
            "metadata": {
                "creationTimestamp": "2021-06-08T09:40:17Z",
                "generateName": "mytomcat-c64f9c47b-",
                "labels": {
                    "app": "mytomcat",
                    "pod-template-hash": "c64f9c47b"
                },
                "name": "mytomcat-c64f9c47b-bb4dh",
                "namespace": "default",
                "ownerReferences": [
                    {
                        "apiVersion": "apps/v1",
                        "blockOwnerDeletion": true,
                        "controller": true,
                        "kind": "ReplicaSet",
                        "name": "mytomcat-c64f9c47b",
                        "uid": "18db7aa9-8175-41d0-bd1a-2fc27cc7b515"
                    }
                ]
            },
            "spec": {
                "containers": [
                    {
                        "image": "10.2.1.1:8443/library/tomcat:8.0",
                        "imagePullPolicy": "IfNotPresent",
                        "name": "tomcat",
                        "resources": {},

Then we need to parse the json to get the container’s image name, for the above json, we know that the jsonpath of it is as follows:

.items[].spec.containers[].image

You can learn more about jsonpath here:

Then we use jq command to parse the json:

jq -r '.items[].spec.containers[].image'

What is jq?

➜  ~ jq --help
jq - commandline JSON processor [version 1.6]

Usage:	jq [options] <jq filter> [file...]
	jq [options] --args <jq filter> [strings...]
	jq [options] --jsonargs <jq filter> [JSON_TEXTS...]

jq is a tool for processing JSON inputs, applying the given filter to
its JSON text inputs and producing the filter's results as JSON on
standard output.

The simplest filter is ., which copies jq's input to its output
unmodified (except for formatting, but note that IEEE754 is used
for number representation internally, with all that that implies).

For more advanced filters see the jq(1) manpage ("man jq")
and/or https://stedolan.github.io/jq

Example:

	$ echo '{"foo": 0}' | jq .
	{
		"foo": 0
	}

Some of the options include:
  -c               compact instead of pretty-printed output;
  -n               use `null` as the single input value;
  -e               set the exit status code based on the output;
  -s               read (slurp) all inputs into an array; apply filter to it;
  -r               output raw strings, not JSON texts;
  -R               read raw strings, not JSON texts;
  -C               colorize JSON;
  -M               monochrome (don't colorize JSON);
  -S               sort keys of objects on output;
  --tab            use tabs for indentation;
  --arg a v        set variable $a to value <v>;
  --argjson a v    set variable $a to JSON value <v>;
  --slurpfile a f  set variable $a to an array of JSON texts read from <f>;
  --rawfile a f    set variable $a to a string consisting of the contents of <f>;
  --args           remaining arguments are string arguments, not files;
  --jsonargs       remaining arguments are JSON arguments, not files;
  --               terminates argument processing;

Named arguments are also available as $ARGS.named[], while
positional arguments are available as $ARGS.positional[].

See the manpage for more options.

We use -r option to tell jq only print the text not the json:

  -r               output raw strings, not JSON texts;

That is the whole inner parts of the magic.

4. Summary

In this post, I tried to demonstrate how to print docker images of all pods in kubernetes pods.