How to collect Kubernetes Metadata? - kubernetes

I am looking for a way to get all object's metadata within a k8s cluster and send it out to an external server.
By metadata, I refer to objects Name, Kind, Labels, Annotations, etc.
The intention is to build an offline inventory of a cluster.
What would be the best approach to build it? Is there any tool that already does something similar?
Thanks

Posting this as a community wiki, feel free to edit and expand.
There are different ways to achieve it.
From this GitHub issue comment it's possible to iterate through all resources to get all available objects.
in yaml:
kubectl api-resources --verbs=list -o name | xargs -n 1 kubectl get --show-kind --ignore-not-found -o yaml
in json:
kubectl api-resources --verbs=list -o name | xargs -n 1 kubectl get --show-kind --ignore-not-found -o json
And then parse the output.
Use kubernetes clients.
There are already developed kubernetes clients (available for different languages) which can be used to get required information and work with it later.
Use kubectl plugin - ketall (didn't test it)
There's a developed plugin for kubectl which returns all cluster resources. Please find github repo - ketall. Again after cluster objects are gotten, you will need to parse/work with them.

Try this commands
kubectl get all --all-namespaces -o yaml
or
kubectl get all --all-namespaces -o json
you can parse and use as you find fit

Related

Argocd application resource stuck at deletion

I've started experimenting with Argocd as part of my cluster setup and set it up to watch a test repo containing some yaml files for a small application I wanted to use for the experiment. While getting to know the system a bit, I broke the repo connection and instead of fixing it I decided that I had what I wanted, and decided to do a clean install with the intention of configuring it towards my actual project.
I pressed the button in the web UI for deleting the application, which got stuck. After which I read that adding spec.syncPolicy.allowEmpty: true and removing the metadata.finalizers declaration from the application yaml file. This did not allow me to remove the application resource.
I then ran an uninstall command with the official manifests/install.yaml as an argument, which cleaned up most resources installed, but left the application resource and the namespace. Command: kubectl delete -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
Have tried to use the kubectl delete application NAME --force flag and the --cascade=orphans flag on the application resource as well as on the argocd namespace itself. Now I have both of them stuck at terminating without getting any further.
Now I'm proper stuck as I can't reinstall the argocd in any way I know due to the resources and namespace being marked for deletion, and I'm at my wits end as to what else I can try in order to get rid of the dangling application resource.
Any and all suggestions as to what to look into is much appreciated.
If your problem is that the namespace cannot be deleted, the following two solutions may help you:
Check what resources are stuck in the deletion process, delete these resources, and then delete ns
Edit the namespace of argocd, check if there is a finalizer field in the spec, delete that field and the content of the field
Hopefully it helped you.
I've found that using the following commands help greatly...
kubectl api-resources --verbs=list --namespaced -o name | \
xargs -n 1 kubectl get --show-kind \
--ignore-not-found -n <namespace>
kubectl api-resources -n <namespace> | grep argo | grep ...
...help greatly to identify the resources that are "stuck".
Then you have to either use some awk to generate delete or delete --all to "prune" the resources. If some get stuck, then you have to resort to editing them to remove the finalisers so that they can then be deleted.
It can get ugly, but awk and printf combinations can help

How to write Kubernetes annotations to the underlying YAML files?

I am looking to apply existing annotations on a Kubernetes resource to the underlying YAML configuration files. For example, this command will successfully find all pods with a label of "app=helloworld" or "app=testapp" and annotate them with "xyz=test_anno":
kubectl annotate pods -l 'app in (helloworld, testapp)' xyz=test_anno
However, this only applies the annotations to the running pods and doesn't change the YAML files. How do I force those changes to the YAML files so they're permanent, either after the fact or as part of kubectl annotate to start with?
You could use the kubectl patch command with a little tricks
kubectl patch $(k get po -l 'app in (helloworld, testapp)') -p '{"metadata":{"annotations":{"xyz":"test_anno"}}}'

Figure out where ConfigMap values are used in the cluster

In my team we have a single huge ConfigMap Resource that holds all the important variables distributed to all our pods.
After some time we realized that it is very hard to follow up where those variables are finally used. I was wondering if there is any way with Helm or kubectl to figure out where the values of the ConfigMap are actually used. Like a list of all the pods being supplied by the ConfigMap etc.
I researched for it but somehow it seems nobody is talking about that. Therefore I might understand the concept wrong here?
Am thankful for any guidance here.
You cannot directly use kubectl field selectors to get the result. You can output all the pods in json and use jq to query from the output. For example, this query outputs name of all pods that uses configMap "kube-proxy" as volumes
$ kubectl get pods --all-namespaces -o json | jq '.items[] | select(.spec.volumes[].configMap.name=="kube-proxy")' | jq .metadata.name

kubectl: describe vs get -o <format>

In kubectl, both describe and get -o <format> can be used to get the details of a resource, I'm wondering what's the difference between the two? why does describe even exist if get can do the same thing and more?
kubectl get shows tables by default. (You can view/visualize large no of objects easily)
kubectl describe shows the detailed description. (Better for a single object)
kubectl describe is more flattened, has lesser data and easier to read than the full object data given by kubectl get -o yaml
Help output for reference.
kubectl describe -h
Show details of a specific resource or group of resources
Print a detailed description of the selected resources, including related resources such as events or controllers. You
may select a single object by name, all objects of that type, provide a name prefix, or label selector. For example:
$ kubectl describe TYPE NAME_PREFIX
will first check for an exact match on TYPE and NAME_PREFIX. If no such resource exists, it will output details for
every resource that has a name prefixed with NAME_PREFIX.
Use "kubectl api-resources" for a complete list of supported resources.
kubectl get -h
Display one or many resources
Prints a table of the most important information about the specified resources. You can filter the list using a label
selector and the --selector flag. If the desired resource type is namespaced you will only see results in your current
namespace unless you pass --all-namespaces.
Uninitialized objects are not shown unless --include-uninitialized is passed.
By specifying the output as 'template' and providing a Go template as the value of the --template flag, you can filter
the attributes of the fetched resources.
Use "kubectl api-resources" for a complete list of supported resources.
A simple explanation could be:
kubectl describe .. == Filterred kubectl get .. -o <format> + relevant events
For debugging purposes it can be useful to look at both describe and get -o <format> since each one has relevant information that is not shown in the other.
Note that events can also be shown by running kubectl get events (for default namespace), or kubectl get event --all-namespaces (for all namespaces).
Some digging:
Running kubectl describe with extended logging --v=8 shows that it calls the events API (the third call) with involvedObject.name%3Dsome-pod.
$ kubectl --v=8 describe pod some-pod 2>&1 | grep GET
I1216 17:09:00.453529 6918 round_trippers.go:416] GET https://100.190.50.200/api/v1/namespaces/default/pods/some-pod
I1216 17:09:01.098053 6918 round_trippers.go:416] GET https://100.190.50.200/api/v1/namespaces/default/pods/some-pod
I1216 17:09:01.265924 6918 round_trippers.go:416] GET https://100.190.50.200/api/v1/namespaces/default/events?fieldSelector=involvedObject.name%3Dsome-pod%2CinvolvedObject.namespace%3Ddefault%2CinvolvedObject.uid%3Dbf664be1-1cde-11ea-bce6-42010af00267
kubectl get pod some-pod -o yaml only calls the pods API.
kubectl --v=8 get pod some-pod -o yaml 2>&1 | grep GET
I1216 17:13:21.084386 28256 round_trippers.go:416] GET https://100.190.50.200/api/v1/namespaces/default/pods/some-pod
According to kubernetes documentation:
kubectl -n <NAMESPACE> get <NAME_OF_RESOURCE>
Prints a table of the most important information about the specified
resources. You can filter the list using a label selector and the
--selector flag. If the desired resource type is namespaced you will only see results in your current namespace unless you pass
--all-namespaces.
Source: https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#get
kubectl -n <NAMESPACE> describe <NAME_OF_RESOURCE>
Print a detailed description of the selected resources, including
related resources such as events or controllers. You may select a
single object by name, all objects of that type, provide a name
prefix, or label selector.
Source: https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#describe
kubectl describe is supposed to give you more information .Even if, I agree with you, some resources have quiete the same informations with kubectl get or kubectl describe.
One important difference need to mention: describe accepts the prefix but get need the exactly name.
$ kubectl describe TYPE NAME_PREFIX
$ kubectl get TYPE NAME
You can get the summary of a specific resource using:
kubectl get < resource > < name >
While you can get detailed information with:
kubectl describe < resource > < name >

Where is the full Kubernetes YAML spec?

There must be "full-configuration" and example templates of Kubernetes YAML configs somewhere with comments itemizing what parameters do what with runnable examples somewhere.
Does anyone know where something like this might be? Or where the "full API" of the most commonly used Kubernetes components are?
There is documentation for every k8s api version available, for example check this link.
The way I found what every key in yaml file represent and what does it mean is via kubectl explain command.
For example:
$kubectl explain deploy.spec
Trick I use while doing CKAD to see full list could be:
$kubectl explain deploy --recursive > deployment_spec.txt
This will list all available options for kubernetes deployment that could you use in yaml file.
To generate some template there is option to use --dry-run and -o yaml in kubectl command, for example to create template for CronJob:
$kubectl run cron_job_name --image=busybox --restart=OnFailure --schedule="*/1 * * * * " --dry-run -o yaml > cron_job_name.yaml