How can I `kubectl explain` the entire structure of a custom resource? - kubernetes

I have a CR in the cluster. I know that there is a filed specialField somewhere in this CRD. I do not know where it is. Right now I am randomly exploring the CRD using kubectl explain path.to.some.filed to try to fiend the filed. Is there some way to explain the entire nested structure using kubectl explain?
What I am looking for is something like this
kubectl explain-magic my-crd
my-crd
a
b
c
other
field
more
fields
very
nested
field
or as an alternative
my-crd
a
a.b
a.b.c
other
other.field
more
more.fields
very
very.nested
very.nested.field

Add the --recursive flag to display all of the fields at once without descriptions. Information about each field is
retrieved from the server in OpenAPI format.
from kubectl help explain.
Just do: kubectl explain --recursive my-crd

Related

Ad Hoc Kubernetes Queries

Is there a way to easily query Kubernetes resources in an intuitive way? Basically I want to run queries to extract info about objects which match my criteria. Currently I face an issue where my match labels isn't quite working and I would like to run the match labels query manually to try and debug my issue.
Basically in a pseudo code way:
Select * from pv where labels in [red,blue,green]
Any third party tools who do something like this? Currently all I have to work with is the search box on the dashboard which isn't quite robust enough.
You could use kubectl with JSONPath (https://kubernetes.io/docs/reference/kubectl/jsonpath/). More information on JSONPath: https://github.com/json-path/JsonPath
It allows you to query any resource property, example:
kubectl get pods -o=jsonpath='{$.items[?(#.metadata.namespace=="default")].metadata.name}'
This would list all pod names in namespace "default". Your pseudo code would be something along the lines:
kubectl get pv -o=jsonpath='{$.items[?(#.metadata.label in ["red","blue","green"])]}'

Best way to update Kubernetes secret from command line

The kubernetes dashboard allows one to see secrets in plain text (not base64 encoded) and make an easy change to any key-value pair within a Secret. I cannot find a way to easily make a similar change on the command line.
My best attempt has been to write a script which uses kubectl get secret to pull all of the data in Json format, grab each key-value pair, base64 decode the values, update the one I actually want, then feed them all back in to kubectl apply. After running into multiple issues I figured there is probably a kubectl option that I'm overlooking which will allow me to update just one key-value pair in a given Secret.
How can I do this?
Usually you would have your secrets manifest stashed somewhere where it is secure.
I dont usually change the secrets using the dashboard, but instead do a kubectl apply -f mysecret.yaml. the mysecret.yaml file keeps the latest and greatest values. No in-place editing. This way you get consistency across deployments.

Tracking events with prometheus and grafana

There's an article "Tracking Every Release" which tells about displaying a vertical line on graphs for every code deployment. They are using Graphite. I would like to do something similar with Prometheus 2.2 and Grafana 5.1. More specifically I want to get an "application start" event displayed on a graph.
Grafana annotations seem to be the appropriate mechanism for this but I can't figure out what type of prometheus metric to use and how to query it.
The simplest way to do this is via the same basic approach as in the article, by having your deployment tool tell Grafana when it performs a deployment.
Grafan has a built-in system for storing annotations, which are displayed on graphs as vertical lines and can have text associated with them. It would be as simple as creating an API key in your Grafana instance and adding a curl call to your deploy script:
curl -H "Authorization: Bearer <apikey>" http://grafana:3000/api/annotations -H "Content-Type: application/json" -d '{"text":"version 1.2.3 deployed","tags":["deploy","production"]}'
For more info on the available options check the documentation:
http://docs.grafana.org/http_api/annotations/
Once you have your deployments being added as annotations, you can display those on your dashboard by going to the annotations tab in the dashboard settings and adding a new annotation source:
Then the annotations will be shown on the panels in your dashboard:
You can get the same result purely from Prometheus metrics, no need to push anything into Grafana:
If you wanted to track all restarts your search expression could be something like:
changes(start_time_seconds{job="foo",env="prod"} > 0
Or something like this if you only wanted to track version changes (and you had some sort of info metric that provided the version):
alertmanager_build_info unless max_over_time(alertmanager_build_info[1d] offset 5m)
The latter expression should only produce an output for 5 minutes whenever a new alertmanager_build_info metric appears (i.e. one with different labels such as version). You can further tweak it to only produce an output when version changes, e.g. by aggregating away all other labels.
A note here as technology has evolved. We get deployment job state information in Prometheus metrics format scraped directly from the community edition of Hashicorp's Nomad and we view this information in Grafana.
In your case, you would just add an additional query to an existing panel to overlay job start events, which is equivalent to a new deployment for us. There are a lot of related metrics "out of the box," such as for a change in job version that can be considered as well. The main point is no additional work is required besides adding a query in Grafana.

kubernetes strategic merge patch

Hi I am following this doc https://github.com/kubernetes/kubernetes/blob/master/docs/devel/api-conventions.md#strategic-merge-patch for strategic-merge-patch to partially update the JSON objects using PATCH REST API. The document says that it can add or delete the object, but I have tried, whenever I add new object to existing JSON it just replaces that instead of adding new. I am trying this to modify pod definition in OpenShift 3.2. can anyone please help me how it works, probably with example. I need to use delete operation also , where I can delete the value by name.
As documented it depends on annotations of the types. AFAIS the strategic merge only works if patchStrategy and patchMergeKey are given. For example, this is the case in pod.spec.containers and pod.spec.volumes.
For an example you need to provide more information about the type you want to merge.

How do I get Events associated with a Pod via the API?

When I do a kubectl describe <pod>, the bottom section has an "Events" section, displaying Events related to that pod. For example, an event with Reason "failedScheduling", with the message "Failed for reason PodFitsResources and possibly others"
How can I query the API to return that list of events?
If I call /api/v1/namespaces/<ns>/pods/<pod_name>, it doesn't return any Events. If I try the /api/v1/events endpoint, I can specify a labelSelector parameter, but the name of the pod isn't a label of the Event, though it is in the object.involvedObject.name field.
I could request the entire Event stream and filter out the few Events that interest me client-side, but that seems like overkill. kubectl is able to do it, so I figure there must be some way that I'm missing.
Thanks.
I think events support a fieldSelector for the involved object kind and name
You can also turn the verbosity level on kubectl up to 8 to see network traces to see what it is doing
If you are still wondering how kubectl gets the events along with the describe command, then have a look at the following:
https://github.com/kubernetes/kubernetes/blob/b6a0718858876bbf8cedaeeb47e6de7e650a6c5b/pkg/kubectl/describe/versioned/describe.go#L242
If you see what's happening is that they first get the details of the resource requested (see https://github.com/kubernetes/kubernetes/blob/b6a0718858876bbf8cedaeeb47e6de7e650a6c5b/pkg/kubectl/describe/versioned/describe.go#L235 ) and then they get all the events from that namespace and filter out the events for the requested resource. See Line 242 in the same link.
So they are not using some other undocumented API or other ways, What you thought as overkill is what they are doing.