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:
- config maps
- secrets
- persistent volumes
- persistent volume claims
- ingresses
- service accounts
- others
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
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.