I am trying to get a list of all non-READY containers in all pods to debug a networking issue in my cluster.
Is it possible to use kubectl to get a clean list of all containers in all pods with their status (READY/..)?
I am currently using
$ kubectl get pods
However, the output can be huge and it can be difficult to know which containers are READY and which ones have issues.
Thanks.
kubectl get pods -o=jsonpath='{range .items[*]}{"\n"}{.metadata.name}{":\t"}{range .status.containerStatuses[*]}{.ready}{", "}{end}{end}'
Adapted from this doc: https://kubernetes.io/docs/tasks/access-application-cluster/list-all-running-container-images/#list-containers-by-pod
Edit to describe what the jsonpath is doing:
From what I understand with the jsonpath, range iterates all of the .items[*] returned by getting the pods. \n is added to split the result to one per line, otherwise the result would come to one line. To see how the rest work, you should choose one of your pods and run:
kubectl get pod podname -o yaml
.metadata.name corresponds to
apiVersion: v1
kind: Pod
metadata:
name: podname
Similarly, .status.containerStatuses[*] corresponds to the list of container statuses that should be towards the bottom.
I've adapted #joshua-oliphant's answer to include container-names:
kubectl get pods -o=jsonpath='{range .items[*]}{"\n"}{.metadata.name}{":\t"}{range .status.containerStatuses[*]}{.name}{": "}{.ready}{", "}{end}{end}'
This will display all pods including all containers in the current namespace with their ready-state such as:
pod-name: container-name-a: true, container-name-b: false
Using jq, we can list all pods and their containers' statuses:
kubectl get pods --output=json | jq --raw-output '.items | map([.metadata.name, (.status.containerStatuses | map(.name + ": " + (.ready | tostring)))[]]) | .[] | join("\n ")'
This displays something like this:
pod-1234-auiend
container1: true
container2: false
another-pod-2454-123123:
container1: true
(...)
Related
We have cluster with Istio and also Jenkins job to get "stable" pods, which uses this kubectl query:
kubectl get po -o=jsonpath="{range .items[?(#.status.containerStatuses[-1].ready==true)]}{.spec.containers[0].image}{'\\n'}{end}"
registry/my-proj/admin:2.0.0.000123
registry/my-proj/foo:2.0.0.000123
registry/my-proj/bar:2.0.0.000123
This query fetches pods where last container (application) is ready, because we also have Istio sidecar containers. But here is tricky thing, it looks like array is built using alphabet, so if Istio container will be last - it fetches it as ready pod, because last container is ready.
I've tried to use go-template also, but the best thing I've managed to do
kubectl get po -o go-template='{{range .items}}{{range .status.containerStatuses}}{{if eq .ready true }}{{end}}{{end}}{{.metadata.name}}{{println}}{{end}}
registry/my-proj/admin:2.0.0.000123
registry/my-proj/admin:2.0.0.000123
registry/my-proj/foo:2.0.0.000123
registry/my-proj/foo:2.0.0.000123
registry/my-proj/bar:2.0.0.000123
It fetches 2 times pods where 2 containers are ready and only 1 if 1 container is ready.
TL;DR;
I am looking for ultimate query which can fetch pods where all containers are ready, thanks
What about something like this?
kubectl get po -o go-template='{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}{{range .items}}{{$pod := .}}{{range .status.containerStatuses}}{{if eq .ready false}}{{$pod.metadata.name}}{{"\n"}}{{end}}{{end}}{{end}}' | sort | uniq -u
What's happening here:
We are getting all existing pod names, delimited by newline
Appending all pod names, which have at least one not ready container, delimited by newline
Sorting output alphabetically
Getting unique lines, while excluding duplicate ones.
The trick is that -u key excludes all duplicate entries, so all that is left is running pods.
{{ $pod := .}} is used to save outer scope to print pod name inside inner loop. "Get all pods" is coming after "get not ready pods" to reduce risk of possible race condition, when some pods may have become ready by the time we did a "get all pods" query.
I do believe that something like this can easily be achieved with jsonpath too, but I don't think that you'll be able to do it with kubectl only, without the usage of sort and uniq.
If you are ok with grep, you can use the following command:
kubectl get pod |grep -Po '^([^ ]+)(?=\s+((\d+)\/\3))'
Example:
kubectl get pod
NAME READY STATUS RESTARTS AGE
bar 2/2 Running 0 5m12s
foo 1/3 NotReady 6 6m9s
mypod 1/1 Running 2 (9m58s ago) 21h
kubectl get pod |grep -Po '^([^ ]+)(?=\s+((\d+)\/\3))'
bar
mypod
ps#controller:~$
Get all ready pods:
kubectl get po -o go-template='{{ $readyFlag := true}}{{range .items}}{{range .status.containerStatuses}}{{ if not .ready}}{{ $readyFlag = false}}{{end}}{{end}}{{if $readyFlag }}{{.metadata.name}}{{"\n"}}{{end}}{{end}}'
Get all not ready pods:
kubectl get po -o go-template='{{ $readyFlag := true}}{{range .items}}{{range .status.containerStatuses}}{{ if not .ready}}{{ $readyFlag = false}}{{end}}{{end}}{{if not $readyFlag }}{{.metadata.name}}{{"\n"}}{{end}}{{end}}'
Implementation details:
We define variable $readyFlag with initial value true
We loop over all containers statuses and if its field ".ready" is not true - update our flag value to false
In the end we just check if $readyFlag has value false - then at least one of checked containers had status not ready. If value true - then all containers was ready
We have a k8s cluster with 10 workers. we run hundreds of pods in the cluster. we want to avoid running pods with default service account.
Need to find out the pods that are running with default service account. am able to find the number of pods using default service account with grep command but also need the pod name and the image it is using. Let us know your thoughts
In Case if you want to use just kubectl without jq :
needed to print both namespace and the pod name
kubectl get pods --all-namespaces -o jsonpath='{range .items[?(#.spec.serviceAccountName == "default")]}{.metadata.namespace} {.metadata.name}{"\n"}{end}' 2>/dev/null
i have added 2>/dev/null to avoid printing whole json template in case if no field was found
I used the below command to identify the pods from each namespace that is using default service account
kubectl get pods --all-namespaces -o json | jq '.items[] | select(.spec.serviceAccountName?=="default") | "\(.metadata.namespace) \(.metadata.name)"' | cut -d'"' -f2 | sort
if you are using k9s you can also :pod then e the pod to see which service account it is associated with
I have 3 nodes, running all kinds of pods. I would like to have a list of nodes and pods, for an example:
NODE1 POD1
NODE1 POD2
NODE2 POD3
NODE3 POD4
How can this please be achieved?
Thanks.
You can do that with custom columns:
kubectl get pod -o=custom-columns=NAME:.metadata.name,STATUS:.status.phase,NODE:.spec.nodeName --all-namespaces
or just:
kubectl get pod -o=custom-columns=NODE:.spec.nodeName,NAME:.metadata.name --all-namespaces
kubectl has a simple yet useful extended output format that you can use like
kubectl get pod -o wide
so while custom formats provided in other answers are good, this might be a handy shortcut.
You can use kubectl get pods --all-namespaces to list all the pods from all namespaces and kubectl get nodes for listing all nodes.
The following command does more or less what you wanted. However, it's more of a jq trick than kubectl trick:
kubectl get pod --all-namespaces -o json | jq '.items[] | .spec.nodeName + " " + .status.podIP'
Not exactly as you wanted cause it describe much more, but you can use
kubectl describe nodes
it will expose each pod per node in the cluster with the following info
Namespace | Name | CPU Requests | CPU Limits | Memory Requests |
Memory Limits
This gets you: "nodeName namespace pod" across the cluster:
kubectl get pods --all-namespaces --output 'jsonpath={range .items[*]}{.spec.nodeName}{" "}{.metadata.namespace}{" "}{.metadata.name}{"\n"}{end}'
Maybe the answers are a little bit old, now you can simply launch this:
kubectl get pods -o wide
I am unable to add a label to my kubernetes pod. Why is this not working?
$ kubectl describe pods secure-monolith | grep Label
Labels: app=monolith
$ kubectl label pods secure-monolith "secure=enabled"
pod "secure-monolith" labeled
$ kubectl describe pods secure-monolith | grep Label
Labels: app=monolith
$ kubectl label pods secure-monolith "secure=enabled"
'secure' already has a value (enabled), and --overwrite is false
As you can see, it says the label was successfully added, however the label does not appear when "describing" the pod; and it can also not be added again.
You are grepping through the describe output, but only the first line of labels description contains Label string.
Labels output for two labels looks as follows:
Labels: a=b
c=d
So secure=enabled is there, you just filtered it out.
kubectl get pod POD_NAME --show-labels
This command shows all the labels added to the pod
I am looking to list all the containers in a pod in a script that gather's logs after running a test. kubectl describe pods -l k8s-app=kube-dns returns a lot of info, but I am just looking for a return like:
etcd
kube2sky
skydns
I don't see a simple way to format the describe output. Is there another command? (and I guess worst case there is always parsing the output of describe).
Answer
kubectl get pods POD_NAME_HERE -o jsonpath='{.spec.containers[*].name}'
Explanation
This gets the JSON object representing the pod. It then uses kubectl's JSONpath to extract the name of each container from the pod.
You can use get and choose one of the supported output template with the --output (-o) flag.
Take jsonpath for example,
kubectl get pods -l k8s-app=kube-dns -o jsonpath={.items[*].spec.containers[*].name} gives you etcd kube2sky skydns.
Other supported output output templates are go-template, go-template-file, jsonpath-file. See http://kubernetes.io/docs/user-guide/jsonpath/ for how to use jsonpath template. See https://golang.org/pkg/text/template/#pkg-overview for how to use go template.
Update: Check this doc for other example commands to list container images: https://kubernetes.io/docs/tasks/access-application-cluster/list-all-running-container-images/
Quick hack to avoid constructing the JSONpath query for a single pod:
$ kubectl logs mypod-123
a container name must be specified for pod mypod-123, choose one of: [etcd kubesky skydns]
I put some ideas together into the following:
Simple line:
kubectl get po -o jsonpath='{range .items[*]}{"pod: "}{.metadata.name}{"\n"}{range .spec.containers[*]}{"\tname: "}{.name}{"\n\timage: "}{.image}{"\n"}{end}'
Split (for readability):
kubectl get po -o jsonpath='
{range .items[*]}
{"pod: "}
{.metadata.name}
{"\n"}{range .spec.containers[*]}
{"\tname: "}
{.name}
{"\n\timage: "}
{.image}
{"\n"}
{end}'
How to list BOTH init and non-init containers for all pods
kubectl get pod -o="custom-columns=NAME:.metadata.name,INIT-CONTAINERS:.spec.initContainers[*].name,CONTAINERS:.spec.containers[*].name"
Output looks like this:
NAME INIT-CONTAINERS CONTAINERS
helm-install-traefik-sjts9 <none> helm
metrics-server-86cbb8457f-dkpqm <none> metrics-server
local-path-provisioner-5ff76fc89d-vjs6l <none> local-path-provisioner
coredns-6488c6fcc6-zp9gv <none> coredns
svclb-traefik-f5wwh <none> lb-port-80,lb-port-443
traefik-6f9cbd9bd4-pcbmz <none> traefik
dc-postgresql-0 init-chmod-data dc-postgresql
backend-5c4bf48d6f-7c8c6 wait-for-db backend
if you want a clear output of which containers are from each Pod
kubectl get po -l k8s-app=kube-dns \
-o=custom-columns=NAME:.metadata.name,CONTAINERS:.spec.containers[*].name
To get the output in the separate lines:
kubectl get pods POD_NAME_HERE -o jsonpath='{range .spec.containers[*]}{.name}{"\n"}{end}'
Output:
base-container
sidecar-0
sidecar-1
sidecar-2
If you use json as output format of kubectl get you get plenty details of a pod. With json processors like jq it is easy to select or filter for certain parts you are interested in.
To list the containers of a pod the jq query looks like this:
kubectl get --all-namespaces --selector k8s-app=kube-dns --output json pods \
| jq --raw-output '.items[].spec.containers[].name'
If you want to see all details regarding one specific container try something like this:
kubectl get --all-namespaces --selector k8s-app=kube-dns --output json pods \
| jq '.items[].spec.containers[] | select(.name=="etcd")'
Use below command:
kubectl get pods -o=custom-columns=PodName:.metadata.name,Containers:.spec.containers[*].name,Image:.spec.containers[*].image
To see verbose information along with configmaps of all containers in a particular pod, use this command:
kubectl describe pod/<pod name> -n <namespace name>
Use below command to see all the information of a particular pod
kubectl get pod <pod name> -n <namespace name> -o yaml
For overall details about the pod try following command to get the container details as well
kubectl describe pod <podname>
I use this to display image versions on the pods.
kubectl get pods -o=jsonpath='{range .items[*]}{"\n"}{.metadata.name}{":\t"}{range .spec.containers[*]}{.image}{end}{end}' && printf '\n'
It's just a small modification of script from here, with adding new line to start next console command on the new line, removed commas at the end of each line and listing only my pods, without service pods (e.g. --all-namespaces option is removed).
There are enough answers here but sometimes you want to see a deployment object pods' containers and initContainers. To do that;
1- Retrieve the deployment name
kubectl get deployment
2- Retrieve containers' names
kubectl get deployment <deployment-name> -o jsonpath='{.spec.template.spec.containers[*].name}'
3- Retrieve initContainers' names
kubectl get deployment <deployment-name> -o jsonpath='{.spec.template.spec.initContainers[*].name}'
Easiest way to know the containers in a pod:
kubectl logs -c -n