1. Introduction

Running kubectl get all to retrieve a list of all resources in a namespace has a limited effect. While it returns a list of various resources in a namespace, it omits some resource types. Of course, this is undesirable when we really need an exhaustive list of all resources in the namespace.

In this tutorial, we’ll learn how to list all resources in a namespace in Kubernetes.

2. Using kubectl get all

As mentioned earlier, we can get a list of some resources in a namespace by running kubectl get all:

$  kubectl get all
NAME                                  READY   STATUS                       RESTARTS   AGE
pod/app-deployment-5dc467b756-4zwcp   0/1     CreateContainerConfigError   0          5d19h
pod/app-deployment-5dc467b756-qplj6   0/1     CreateContainerConfigError   0          5d19h

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   5d22h

NAME                             READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/app-deployment   0/2     2            0           5d19h

NAME                                        DESIRED   CURRENT   READY   AGE
replicaset.apps/app-deployment-5dc467b756   2         2         0       5d19h

Wherever applicable, kubectl get all returns a list of pods, services, daemon sets, deployments, replica sets, jobs, cronjobs, and stateful sets. These are the built-in resource types.

Yet, custom resource types would be missing from the returned list:

To get such resources, we might need to turn to other commands.

3. Using kubectl api-resources

When we want a more encompassing list of all resources in a namespace, we can combine the kubectl api-resources command with kubectl-get.

3.1. Understanding the kubectl api-resources Command

To begin with, the api-resources subcommand of kubectl shows all API resources that the current server supports:

$ kubectl api-resources --verbs=list --namespaced -o name

We expand this command with several options to filter down resources further:

  • –verbs=list ensures any returned resources support the list verb
  • –namespace**d only returns API resources that are namespaced
  • -o name outputs only the name of the resources that match the criteria

Once we have the names of the desired resources, we can get information about them via kubectl. To process each resource, we use xargs by redirecting the output of the previous command:

$ kubectl api-resources --verbs=list --namespaced -o name | xargs -n 1 kubectl get --ignore-not-found --show-kind -n <namespace>

Here, xargs passes the arguments one by one (-n 1) to kubectl. Next, kubectl get uses the –ignore-not-found flag to avoid any missing resource types if an instance of a requested resource doesn’t exist in the namespace, while –show-kind ensures we get the types.

In summary, we only pass one name from the kubectl api-resources output per iteration of the kubectl get command, suppress any No resources found in namespace. messages, and show the resource types.

3.2. Example Usage

Let’s try the command on the default namespace of the cluster:

$ kubectl api-resources --verbs=list --namespaced -o name | xargs -n 1 kubectl get --ignore-not-found --show-kind
NAME                         DATA   AGE
configmap/db-config          1      137m
...truncated..
NAME                   ENDPOINTS           AGE
endpoints/kubernetes   192.168.49.2:8443   6d1h
LAST SEEN   TYPE     REASON      OBJECT                                MESSAGE
76s         Normal   Pulling     pod/app-deployment-5dc467b756-4zwcp   Pulling image "adeyomola/app:latest"
...truncated...
NAME                              STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/www-web-0   Bound    pvc-43444fce-40e5-4b85-9336-95776ffe332e   1Gi        RWO            standard       139m
...truncated...
NAME                                  READY   STATUS                       RESTARTS   AGE
pod/app-deployment-5dc467b756-4zwcp   0/1     CreateContainerConfigError   0          5d22h
...truncated...
NAME                     SECRETS   AGE
serviceaccount/default   0         10d
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   6d1h
NAME                             READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/app-deployment   0/2     2            0           5d22h
NAME                                        DESIRED   CURRENT   READY   AGE
replicaset.apps/app-deployment-5dc467b756   2         2         0       5d22h
...truncated...
NAME                                        CLASS           HOSTS   ADDRESS   PORTS   AGE
ingress.networking.k8s.io/minimal-ingress   nginx-example   *                 80      44m

From the output, we can see that ingresses, endpoints, service accounts, persistent volume claims, and config maps are among the returned resources. This is unlike the restrictive list from kubectl get all.

4. Using kubectl api-resources and for Loop

In place of xargs -n 1, we can pass the name of each resource type returned by the custom kubectl api-resources command to kubectl get via a for loop:

$ for i in $(kubectl api-resources --namespaced --verbs=list -o name | tr "\n" " "); do
  kubectl get $i --show-kind --ignore-not-found;
done

We get pretty much the same output as when using kubectl api-resources and kubectl get with xargs.

5. Retrieving a List of Multiple Resource Types

Sometimes, we might not really be interested in a list of all resources in a namespace. However, we may still want a list of all resources of specific resource types in a namespace. In such cases, combining kubectl get and kubectl api-resources would be an overkill since the combination doesn’t filter by type.

Adding multiple, comma-separated arguments to kubectl get enables us to list all resources of specific resource types in a namespace:

$ kubectl get <resource type>,<resource type>,<resource type>,... -n <namespace>

So, let’s retrieve a list of config maps, persistent volumes, endpoints, ingress, and service accounts in the kube-system namespace:

$ kubectl get configmaps,pv,endpoints,ingress,serviceaccounts -n kube-system
NAME                                           DATA   AGE
configmap/coredns                              1      10d
...truncated...

NAME                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM               STORAGECLASS   REASON   AGE
persistentvolume/pvc-43444fce-40e5-4b85-9336-95776ffe332e   1Gi        RWO            Delete           Bound    default/www-web-0   standard                4h36m
persistentvolume/pvc-a6f90403-b427-4483-a6a4-7cf07d2d7852   1Gi        RWO            Delete           Bound    default/www-web-1   standard                4h36m

NAME                                 ENDPOINTS                                           AGE
endpoints/k8s.io-minikube-hostpath   <none>                                              10d
endpoints/kube-dns                   10.244.0.161:53,10.244.0.161:53,10.244.0.161:9153   6d4h

NAME                                                SECRETS   AGE
serviceaccount/attachdetach-controller              0         10d
serviceaccount/bootstrap-signer                     0         10d
...truncated...

Thus, we can use the resource names to indicate the desired types. However, to list them, we have to know which names we can work with.

6. Retrieve a List of All Resource Types

Notably, if we want to filter by resources or only check certain types, we may need to acquire a full list of type names.

6.1. Built-in Types

To be comprehensive, let’s begin with the main types that a default Kubernetes installation comes with:

  • Pod
  • Deployment
  • ReplicaSet
  • StatefulSet
  • DaemonSet
  • PersistentVolume
  • PersistentVolumeClaim
  • Service
  • Namespace
  • ConfigMap
  • Secret
  • Job

By using the kubectl get all command, we usually have access to all of the above. Yet, as mentioned, some custom types don’t show up.

6.2. Custom Types

To see what’s defined on the current Kubernetes environment, we can again utilize the api-resources subcommand of kubectl:

$ kubectl api-resources

In fact, this command produces a list of all resources with their names, versions, kinds, and supported verbs.

So, let’s see parts of an example output:

NAME                SHORTNAMES   APIVERSION                  NAMESPACED   KIND                 VERBS
bindings                         v1                          true         Binding              create
componentstatuses   cs           v1                          false        ComponentStatus      get,list
configmaps          cm           v1                          true         ConfigMap            create,delete,deletecollection,get,list,patch,update,watch
endpoints           ep           v1                          true         Endpoints            create,delete,deletecollection,get,list,patch,update,watch
...
apiservices                      apiregistration.k8s.io/v1   false        APIService           create,delete,deletecollection,get,list,patch,update,watch
controllerrevisions              apps/v1                     true         ControllerRevision   create,delete,deletecollection,get,list,patch,update,watch
daemonsets          ds           apps/v1                     true         DaemonSet            create,delete,deletecollection,get,list,patch,update,watch
...

Notably, the NAME doesn’t always directly match the KIND, so the way we filter should consider the difference, if any.

6.3. Custom RBAC Types and Subtypes

Although very convenient, the api-resources subcommand also only goes so far. To get subtypes and RBAC types, we usually have to create a query and send that to the appropriate api endpoint.

Specifically, we first start the kubectl proxy on port 8080:

$ kubectl proxy --port=8080 &

At this point, we can create a short script that uses the local access for several curl queries and processes the results with jq:

#!/bin/bash
SERVER="localhost:8080"

APIS=$(curl -s $SERVER/apis | jq -r '[.groups | .[].name] | join(" ")')

# core resources under core
api="core"
curl -s $SERVER/api/v1 | jq -r --arg api "$api" '.resources | .[] | "\($api) \(.name): \(.verbs | join(" "))"'

# non-core resources
for api in $APIS; do
  version=$(curl -s $SERVER/apis/$api | jq -r '.preferredVersion.version')
  curl -s $SERVER/apis/$api/$version | jq -r --arg api "$api" '.resources | .[]? | "\($api) \(.name): \(.verbs | join(" "))"'
done

In short, we get the local server address and port and perform a curl query to extract all defined API names, storing them in the APIS variable. After that, we get the core resources. Finally, we go through each API in APIS and query it. At each point, we output the data in the respective format.

This way, we get a list of all main and subtype regular, custom, and RBAC resources.

7. Conclusion

In this article, we discussed how to list all resources in the namespaces of a Kubernetes cluster. We also saw how to list resources of multiple (specific) resource types in a namespace.

Of course, many times, running kubectl get all might be enough to show us a list of all resources we need to see in a namespace. That’s because most of the resources it returns are the ones we commonly work with. Still, whenever we need comprehensiveness, we can redirect names of API resource types from kubectl api-resources to kubectl get. To that end, we can get a comprehensive list, we can use the api-resources subcommand by itself and specifically-crafted API requests.