JSON path semantics different in kubectl and additional printer columns in custom resource definition - kubernetes

I use kubectl to list Kubernetes custom resources of a kind mykind with an additional table column LABEL that contains the value of a label a.b.c.com/key if present:
kubectl get mykind -o=custom-columns=LABEL:.metadata.labels.'a\.b\.c\.com/key'
This works, i.e., the label value is properly displayed.
Subsequently, I wanted to add a corresponding additional printer column to the custom resource definition of mykind:
- description: Label value
jsonPath: .metadata.labels.'a\.b\.c\.com/key'
name: LABEL
type: string
Although the additional column is added to kubectl get mykind, it is empty and no label value is shown (in contrast to above kubectl command). My only suspicion were problems with escaping of the special characters - but no variation helped.
Are you aware of any difference between the JSON path handling in kubectl and additional printer columns? I expected strongly that they are exactly the same.

mdaniel's comment works!
- description: Label value
jsonPath: '.metadata.labels.a\.b\.c\.com/key'
name: LABEL
type: string
You need to use \. instead of . and use single quotes ' '. It doesn't work with double quotes for the reasons I don't understand

Related

Host's pods panel in Grafana

I want to have a panel in Grafana which displays what pods are currently running in a host.
For the host variable I have the following query (the job variable is just label_values(node_uname_info, job).):
label_values(node_uname_info{job="$job"}, instance)
This gives me an array of sockets: host_ip:port
I can get the pod names from kube_pod_info{job="$job", host_ip="$host_ip"}, but in order to get the IP I need to remove the port part of the socket:
label_replace(node_uname_info{job="$job", instance="$node"}, "host_ip", "$1", "instance", "(.*):.*")
I haven't found how to use the new host_ip label in the pod query to eventually get all the pod label values of kube_pod_info. I don't want to put the label_replace in Prometheus to avoid data duplication - is there a way to use the new host_ip label in the pod query?
Edit:
I added the host_ip variable with the regex as shan1024 showed in his answer and changed the panel's query to:
sum by (pod) (kube_pod_info{job="$job", host_ip="$host_ip"})
Then I changed the panel's visualization to table and added column styles to Time and Value (chose type Hidden). This allows me to display the host's running pods in a list-like fashion.
This is actually quite easy to do in Grafana and no need to change labels in Prometheus. You just need to add a regex in the instance variable (when we add a regex with a capturing group, the value(s) of the 1st captured group will be the value(s) of the variable).
e.g.
Variable definition without Regex (you get host_ip:port)-
Variable definition with Regex (you only get host_ip)-
Then you can add a new variable with value kube_pod_info{ host_ip="$instance" } to get all pods in the selected host.

Terraform EKS specify node-role.kubernetes.io label on node group

In the terraform aws_eks_node_group resource I can't set :
labels = {
"node-role.kubernetes.io/others" = "other"
}
as AWS complains labels key should not contains kubernetes.io.
Error: error creating EKS Node Group (my-cluster:others): InvalidParameterException: Label cannot contain reserved labels kubernetes.io/
{
ClusterName: "my-cluster",
Message_: "Label cannot contain reserved labels kubernetes.io/",
NodegroupName: "others"
}
Also, EC2 instances spawned have no name and I have no clue on how to specify a Name for my instances based on their node group.
Any idea on how to achieve this ?
As per the documentation you can't use specific labels, regarding labels:
The kubernetes.io/ and k8s.io/ prefixes are reserved for Kubernetes core components. Valid label values must be 63 characters or less and must be empty or begin and end with an alphanumeric character ([a-z0-9A-Z]) with dashes (-), underscores (_), dots (.), and alphanumerics between.
Regarding your specific label. There are many issues since k8s 1.15 or 1.16 where some change in the core kubernetes don’t allow that label. one detailed issue
As for naming of EC2 instances created by EKS Node Group. Currently, there is no way to pass "Name" tag. This question is a duplicate of this where you can also find the answer how to name your instances for time being.
node-role.kubernetes.io and kubernetes.io - this is DIFFERENT prefixes

A list type label in kubernetes

I was trying to add to a pod a list of values inside one key as a label, thing is it doesn't really work, when I try to do kubectl edit po/sektor -o yaml
(sektor is pod name) and then in labels section I edited the "abilities" label like this:
labels:
abilities:
- ability1: fire
- ability2: teleport
- ability3: rocekts
but when I try to save it shows me the following error:
Invalid value: "The edited file failed validation": ValidationError(Pod.metadata.labels.abilities): invalid type for io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta.labels: got "array", expected "string"
So I see that I need to change the type of that label somehow but I can't figure out how.
If it's possible, anyone knows how?
This is not possible because of the definition of Labels. According to the documentation Labels are key/value pairs. What you could do there tho, would be to have something like this:
labels:
ability-fire: true
ability-teleport: true
ability-rockets: true
With this way you can easily create Selectors for your other Resources like Services.

How can I filter the result of label_values(label) to get a list of labels that match a regex?

I have several metrics with the label "service". I want to get a list of all the "service" levels that begin with "abc" and end with "xyz". These will be the values of a grafana template variable.
This is that I have tried:
label_values(service) =~ "abc.*xyz"
However this produces a error Template variables could not be initialized: parse error at char 13: could not parse remaining input "(service_name) "...
Any ideas on how to filter the label values?
This should work (replacing up with the metric you mention):
label_values(up{service=~"abc.*xyz"}, service)
Or, in case you actually need to look across multiple metrics (assuming that for some reason some metrics have some service label values and other metrics have other values):
label_values({__name__=~"metric1|metric2|metric3", service=~"abc.*xyz"}, service)

OpenShift / Kubernetes explanation for each of the template fields

Sorry if this sounds like I'm lazy, but I've search around, around and around, but couldn't find it!
I'm looking for a reference that explains each of the fields that may exist in an OpenShift / Kubernetes template, e.g. what possible values there are.
The templates you get in OpenShift are OpenShift specific and not part of Kubernetes. If you mean the purpose of each of the possible fields you can specify for a parameter, you can run oc explain template. For example:
$ oc explain template.parameters
RESOURCE: parameters <[]Object>
DESCRIPTION:
parameters is an optional array of Parameters used during the Template to
Config transformation.
Parameter defines a name/value variable that is to be processed during the
Template to Config transformation.
FIELDS:
description <string>
Description of a parameter. Optional.
displayName <string>
Optional: The name that will show in UI instead of parameter 'Name'
from <string>
From is an input value for the generator. Optional.
generate <string>
generate specifies the generator to be used to generate random string from
an input value specified by From field. The result string is stored into
Value field. If empty, no generator is being used, leaving the result Value
untouched. Optional. The only supported generator is "expression", which
accepts a "from" value in the form of a simple regular expression
containing the range expression "[a-zA-Z0-9]", and the length expression
"a{length}". Examples: from | value -----------------------------
"test[0-9]{1}x" | "test7x" "[0-1]{8}" | "01001100" "0x[A-F0-9]{4}" |
"0xB3AF" "[a-zA-Z0-9]{8}" | "hW4yQU5i"
name <string> -required-
Name must be set and it can be referenced in Template Items using
${PARAMETER_NAME}. Required.
required <boolean>
Optional: Indicates the parameter must have a value. Defaults to false.
value <string>
Value holds the Parameter data. If specified, the generator will be
ignored. The value replaces all occurrences of the Parameter ${Name}
expression during the Template to Config transformation. Optional.
You can find more information in:
https://docs.openshift.org/latest/dev_guide/templates.html
If that isn't what you mean, you will need to be more specific as to what you mean. If you are talking about fields on any resource object (templates are specific type of resource object in OpenShift), you can use oc explain on any of them, pass the name of the resource type as argument, and then a dotted path as you traverse into fields. If using plain Kubernetes, you can use kubectl explain.