One day, I was preparing to remove a no longer needed namespace of one Kubernetes cluster. Before I did that, I checked what’s inside again to be sure.
So I typed $ kubectl get all
and see if I missed something. It turned out that several things were not listed in the output, like the ingresses I was expecting.
NAME READY STATUS RESTARTS AGE
pod/someapp-api-558675c7cb-tzhfz 1/1 Running 0 16h
pod/someapp-cronjobs-1581948600-28wx8 0/1 Completed 0 16m
pod/someapp-cronjobs-1581949200-dfrnr 0/1 Completed 0 5m56s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/someapp-api ClusterIP 172.20.140.192 <none> 10020/TCP 61d
service/someapp-svc ExternalName <none> some.fake.domain <none> 61d
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/someapp-api 1/1 1 1 61d
NAME DESIRED CURRENT READY AGE
replicaset.apps/someapp-api-758675c7cb 1 1 1 4d9h
(...omitted)
We all know that some resources in Kubernetes are namespaced, which means these resources are put inside a certain scope (a namespace, or virtual cluster). For example, deployment
, pod
, role
, and pvc
are namespaced. Others are not, like namespace
, pv
, node
, and clusterrole
, etc.
Since $ kubectl get all
doesn’t list everything, we need to combine another command $ kubectl api-resources
to achieve that. This command will print all the supported API resoruces.
To get everything inside a namespace, we will use $ kubectl api-resources --namespaced=true
:
NAME SHORTNAMES APIGROUP NAMESPACED KIND
bindings true Binding
componentstatuses cs false ComponentStatus
configmaps cm true ConfigMap
endpoints ep true Endpoints
namespaces ns false Namespace
nodes no false Node
persistentvolumeclaims pvc true PersistentVolumeClaim
persistentvolumes pv false PersistentVolume
pods po true Pod
(...omitted)
mutatingwebhookconfigurations admissionregistration.k8s.io false MutatingWebhookConfiguration
validatingwebhookconfigurations admissionregistration.k8s.io false ValidatingWebhookConfiguration
customresourcedefinitions crd,crds apiextensions.k8s.io false CustomResourceDefinition
apiservices apiregistration.k8s.io false APIService
controllerrevisions apps true ControllerRevision
daemonsets ds apps true DaemonSet
deployments deploy apps true Deployment
replicasets rs apps true ReplicaSet
(...omitted)
That gave us what we need to pipe into $ kubectl get <api resource>
, but still needs some extra works like cut -d ' ' -f 1
.
It’s not that bad, just not elegant enough. Let’s see whether $ kubectl api-resources --help
can help us:
Options:
--api-group='': Limit to resources in the specified API group.
--cached=false: Use the cached list of resources if available.
--namespaced=true: If false, non-namespaced resources will be returned, otherwise returning namespaced resources
by default.
--no-headers=false: When using the default or custom-column output format, don't print headers (default print
headers).
-o, --output='': Output format. One of: wide|name.
--sort-by='': If non-empty, sort nodes list using specified field. The field can be either 'name' or 'kind'.
--verbs=[]: Limit to resources that support the specified verbs.
Looks like --output=name
is what we need here. It’s really exciting to see command line options that perfectly meet the needs, feels like the developers think (or users make a feature request) way ahead of you.
Anyway, let’s try to put everything together:
$ kubectl api-resources --namespaced=true --output=name | xargs -n 1 kubectl get
Error from server (MethodNotAllowed): the server does not allow this method on the requested resource
NAME AGE
controller-manager <unknown>
scheduler <unknown>
etcd-0 <unknown>
(...omitted)
Oops, it seems there are errors, and we don’t’ know what’s the kind of API resources of each line.
Out of ideas, I had to put the kind and the name as headers for these objects. At least I can see there is indeed an ingress inside the namespace this time.
$ kubectl api-resources --namespaced=true --output=name | xargs -n 1 kubectl get -o custom-columns=KIND:.kind,NAME:.metadata.name
KIND NAME
Error from server (MethodNotAllowed): the server does not allow this method on the requested resource
(...omitted)
KIND NAME
Job someapp-cronjobs-1581949800
KIND NAME
Ingress search
(...omitted)
However, it still won’t tell you what’s the resource you can’t get with $ kubectl get
.
To make it more slightly understandable, I changed the command line a little bit:
$ kubectl api-resources --namespaced=true --output=name | xargs -n 1 -I 🤷♂️ sh -c "echo '***🤷♂️***:'; kubectl get 🤷♂️"
***bindings***:
Error from server (MethodNotAllowed): the server does not allow this method on the requested resource
***configmaps***:
NAME DATA AGE
someapp-config 5 60d
(...omitted)
In the end, the solution is still not elegant enough. At least it works, though. It’s time to stop.