How can i use kubectl labelselector with or contidion? - kubernetes

I want to get pod with label
app=vovo
component=db
When i get a pod with label app=vovo and component=db, i can get the result with below command.
kubectl get pod -l app=vovo,component=db
However, when i want to get the result
app=vovo or component=db
How can i get the result with one kubectl command?

OR operations for label selection is not supported as per the documentation
Caution: For both equality-based and set-based conditions there is no
logical OR (||) operator. Ensure your filter statements are structured
accordingly
Here is a close hack you could do:
kubectl get pod -l app=volvo && kubectl get pod -l component=db --no-headers
This will run two kubectl queries for two different labels.

Related

Is there a way to check multiple pods in one kubectl command

Is there a way to check multiple pods in one command, perhaps something like
kubectl logs pods/pod1 pods/pod2 [container-name]
?
The kubectl logs can't print logs from multiple pods specified by names.
Although, you can use the -l, --selector='' flag as a label query to filter on. e.g.:
# Return snapshot logs from all containers in pods defined by label app=nginx
kubectl logs -lapp=nginx --all-containers=true
If you need to print logs from multiple different pods, there are some projects that can help:
Kubetail: Bash script that enables you to aggregate (tail/follow) logs from multiple pods into one stream. This is the same as running kubectl logs -f but for multiple pods.
Kubelogs: It is a bash script that uses your current kubectl context to interactively select namespaces and multiple pods to download logs from. It basically runs kubectl logs in a loop for all containers, redirecting the logs to local files.

Querying pods by multiple labels

I need to retrieve a list of pods by selecting their corresponding labels.
When the pods have a simple label app=foo, k8s-app=bar, the selection is quite easy:
kubectl get po -l 'app in (foo), k8s-app in (bar)'
The complexity comes with labels that contain special characters, for example: app.kubernetes.io/name=foo
So when I query only this label, I don't have a problem, but if I try to add this label to the existing query, it will end by returning no resources were found.
kubectl get po -l app.kubernetes.io/name=foo,app=bar
kubectl get po -l 'app.kubernetes.io/name in (foo), app in (bar)'
Any idea how can I join the two labels in a single query?
Currently, Kubernetes does not support OR in label selectors. You can only OR different values of the same label (like kubectl get pods -l 'app in (foo,bar)').
See also How can the OR selector be used with labels in Kubernetes?
You can use below command for retrieving a list of pods by selecting their corresponding labels.
kubectl get pods --selector app=foo,k8s-app=bar

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 >

Get Ready status using kubectl -o=jsonpath

I was trying to get the Ready status of pods by using -o=jsonpath.
To be more clear of what I want, I would like to get the value 1/1 of the following example using -o=jsonpath.
NAME READY STATUS RESTARTS AGE
some_pod 1/1 Running 1 34d
I have managed to get some information such as the pod name or namespace.
kubectl get pods --all-namespaces -o=jsonpath='{range .items[*]}{"\n"}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{end}'
And I get somthing like:
some_namespace1 pod_name1
However, I don't know how to get the Ready status. What I would like to have is an aoutput similar to this:
some_namespace1 pod_name1 1/1
I know I can use bash commands like cut:
kubectl get pods --all-namespaces| tail -1 | cut -d' ' -f8
However, I would like to get it by using kubectl
You can get all the pods status using the following command:
kubectl get pods -o jsonpath={.items[*].status.phase}
Similar commands you can use for the name
kubectl get pods -o jsonpath={.items[*].metadata.name}
EDIT:
You need to compare the .status.replicas and .status.readyReplicas to get how many ready replicas are there.
I think this isn't directly reported in the Kubernetes API.
If you kubectl get pod ... -o yaml (or -o json) you'll get back an object matching a List (not included in the API docs) where each item is a Pod in the Kubernetes API, and -o jsonpath values follow that object structure. In particular a PodStatus has a list of ContainerStatus, each of which may or may not be ready, but the API itself doesn't return the counts as first-class fields.
There are a couple of different JSONPath implementations. I think Kubernetes only supports the syntax in the Kubernetes documentation, which doesn't include any sort of "length" function. (The original JavaScript implementation and a ready Googlable Java implementation both seem to, with slightly different syntax.)
The best I can come up with playing with this is to report all of the individual container "ready" statuses
kubectl get pods \
-o $'jsonpath={range .items[*]}{.metadata.name}\t{.status.containerStatuses[*].ready}\n{end}'
($'...' is bash/zsh syntax) but this still requires some post-processing to get back the original counts.

What is the jsonpath for Kubernetes POD status?

I couldn't find the status jsonpath when using kubectl. The pod json has a status field but it is an array.
kubectl get pods --column=Status:.status[*]
There are several elements in the array, how can I select the one for real pod status?
One must enable jsonpath output, via kubectl get pods --output="jsonpath={.status}", not via --column
The results were an array because as written kubectl is returning all Pods that are in the current namespace. To get a singular Pod status, qualify your request with:kubectl get pod $the_pod_name_here --output="jsonpath={.status}"if you really do want the status of all pods, then --output="jsonpath={.items[*].status}" is likely the syntax you were seeking