kubectl command to find a particular pod status as ready - kubernetes

I wanted to hit a command which searches pod with the service name and identify its pod's status as "Ready"
I tried some of the commands but it does not work and it does not search with service-name.
kubectl get svc | grep my-service | --output="jsonpath={.status.containerStatuses[*].ready}" | cut -d' ' -f2
I tried to use the loop also, but the script does not give the desired output.
Can you please help me figure out the exact command?

If I understood you correctly, you want to find if specific Pod connected to specific Endpoint - is in "Ready" status .
Using JSON PATH you can display all Pods in specific namespace with their status:
$ kubectl get pod -o=jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.phase}{"\n"}{end}'
If you are looking for status for Pods connected to specific Endpoint, you can use below script:
#!/bin/bash
endpointName="web-1"
for podName in $(kubectl get endpoints $endpointName -o=jsonpath={.subsets[*].addresses[*].targetRef.name}); do
if [ ! -z $podName ]; then
kubectl get pod -o=jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.phase}{"\n"}{end}' | grep $podName
fi
done
for podName in $(kubectl get endpoints $endpointName -o=jsonpath={.subsets[*].notReadyAddresses[*].targetRef.name}); do
if [ ! -z $podName ]; then
kubectl get pod -o=jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.phase}{"\n"}{end}' | grep $podName
fi
done
Please note that you need to change Endpoint name to your needs, in above example I use web-1 name.
If this response doesn't answer your question, please specify your exact purpose.

every service create a endpoints which contain the podIp and other info for service. you can just use that endpoints to get you pods. . it will show you the ready pod for your my-service.
use this command:
kubectl get endpoints -n <Name_space> <service_name> -o json | jq -r 'select(.subsets != null) | select(.subsets[].addresses != null) | .subsets[].addresses[].targetRef.name'
for you the command will be:
kubectl get endpoints my-service -o json | jq -r 'select(.subsets != null) | select(.subsets[].addresses != null) | .subsets[].addresses[].targetRef.name'
you can run the script for getting the pod status
#!/usr/bin/env bash
for podname in $(kubectl get endpoints my-service -o json | jq -r 'select(.subsets != null) | .subsets[].addresses[].targetRef.name')
do
kubectl get pods -n demo $podname -o json | jq -r ' select(.status.conditions[].type == "Ready") | .status.conditions[].type ' | grep -x Ready
done

Very easy and native command:
kubectl get pods --field-selector status.phase=Running

Related

Delete Kubernetes namespace only if it's empty?

I am using Helm to deploy multiple "components" of my application into a single namespace and using Jenkins to trigger create and destroy jobs. It doesn't seem that I can use Helm to delete the namespace thus I am looking to just use a Kubernetes command.
However, It seems that if I use kubectl delete namespace it will forcefully destroy the namespace and all its resources.
I'd like to destroy the namespace only if it is empty. Is there a command to do this?
I'd like destroy the namespace only if it is empty. Is there a command
to do this?
No there is not command to do that. This behavior is by design.
I would suggest a different approach. You should have all your deployment yamls in version control system for all of the components including namespace. When you want to create use kubectl create -f deployment.yaml and when you want to delete use kubectl delete -f deployment.yaml
See Remove Empty Namespaces Operator, it can do exactly what you want.
Why? Because it's not so easy to iterate over resources in the namespace to decide if it's empty or not. After all, there are "default resources" like default service account and probably other stuff from you tooling/operators.
So these resources should be excluded from iteration. Bash scripting becomes too complicated this way. And one day I decided to implement it with Python.
You can run kubectl get all --namespace YOUR_NAMESPACE and then depends on output call delete namespace
try this, better iterate over kube-api resources and this will give every resource list inside the namespace.
kubectl api-resources --verbs=list --namespaced -o name \
| xargs -n 1 kubectl get --show-kind --ignore-not-found -l <label>=<value> -n
<namespace>
or another approch
kubectl api-resources --verbs=list --namespaced -o name | `
%{ kubectl get $_ --show-kind --ignore-not-found -l <label>=<value> -n
<namespace> }
There's not a simple command to check a namespace before delete, it requires some kubectl scripting or a kube API client.
From the github issue discussing get alls limitations liggit provides an example and adding some jq processing you can get a (slow) command that errors unless it successfully finds all resource types are empty (no items):
set -o pipefail
kubectl api-resources --verbs=list --namespaced -o name \
| xargs -n 1 kubectl get --ignore-not-found -n YOUR_NAMESPACE -o json \
| jq '.items[] | .kind + "/" + .metadata.name | error'
just use folloing to delete all empty namespaces
kubectl get ns --no-headers -o custom-columns=":metadata.name" | xargs -I{} kubectl get all -n {} 2>&1 | grep "No" | cut -d " " -f 5 | xargs -I{} kubectl delete namespace {}
you can list empty namespaces by this
kubectl get ns --no-headers -o custom-columns=":metadata.name" | xargs -I{} kubectl get all -n {} 2>&1 | grep "No" | cut -d " " -f 5

Get an environment variable from kubernetes pods and store it in an array

The use case is to get the environment variable *COUNTRY from all the pods running in a namespace
kubectl get pods podname -n namespace -o 'jsonpath={.spec.containers[0].env[?(#.name~="^COUNTRY")].value}'
This does not seem to work. any lead?
You can retrieve this information using the following command:
kubectl get pods --all-namespaces -o jsonpath='{range .items[*]}{.spec.containers[*].env[*].name}{"\t"}{.spec.containers[*].env[*].value}{"\n"}{end}' | grep COUNTRY | cut -f 2
It will return the variables content as follows:
$ kubectl get pods --all-namespaces -o jsonpath='{range .items[*]}{.spec.containers[*].env[*].name}{"\t"}{.spec.containers[*].env[*].value}{"\n"}{end}' | grep VAR | cut -f 2
123456
7890123
kubectl get pods -o=jsonpath='{.items[*].spec.containers[*].env[?(#.name=="COUNTRY")].value}'
Hope this helps. I was just able to run it on mine and it worked the best.

How do I get a single pod name for kubernetes?

I'm looking for a command like "gcloud config get-value project" that retrieves a project's name, but for a pod (it can retrieve any pod name that is running). I know you can get multiple pods with "kubectl get pods", but I would just like one pod name as the result.
I'm having to do this all the time:
kubectl get pods # add one of the pod names in next line
kubectl logs -f some-pod-frontend-3931629792-g589c some-app
I'm thinking along the lines of "gcloud config get-value pod". Is there a command to do that correctly?
There are many ways, here are some examples of solutions:
kubectl get pods -o name --no-headers=true
kubectl get pods -o=name --all-namespaces | grep kube-proxy
kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}'
For additional reading, please take a look to these links:
kubernetes list all running pods name
Kubernetes list all container id
https://kubernetes.io/docs/tasks/access-application-cluster/list-all-running-container-images/
You can use the grep command to filter any output on stdout. So to get pods matching a specified pattern you can use a command like this:
> kubectl get pods --all-namespaces|grep grafana
Output:
monitoring kube-prometheus-grafana-57d5b4d79f-smkz6 2/2 Running 0 1h
To only output the pod name, you can use the awk command with a parameter of '{print $2}', which displays the second column of the previous output:
kubectl get pods --all-namespaces|grep grafana|awk '{print $2}'
To only display one line you can use the head command like so:
kubectl get pods --all-namespaces|grep grafana|awk '{print $2}'|head -n 1
This will output the last pod name :
kubectl get pods -o go-template --template ' {{range .items}}{{.metadata.name}}{{"\n"}}{{end}}' | awk '{print $1}' | tail -n 1
if you want to fetch logs for a pod:
kubectl logs -f kubectl get pods -o go-template --template ' {{range .items}}{{.metadata.name}}{{"\n"}}{{end}}' | awk '{print $1}' | tail -n 1
just run the command with a single quotes.
Links:
kubernetes list all running pods name
https://kubernetes.io/docs/tasks/access-application-cluster/list-all-running-container-images/
Hope this helps!!

How do I extract multiple values from kubectl with jsonpath

I've found jsonpath examples for testing multiple values but not extracting multiple values.
I want to get image and name from kubectl get pods.
this gets me name
kubectl get pods -o=jsonpath='{.items[*].spec.containers[*].name}' | xargs -n 1
this gets me image
kubectl get pods -o=jsonpath='{.items[*].spec.containers[*].image}' | xargs -n 1
but
kubectl get pods -o=jsonpath='{.items[*].spec.containers[*].[name,image}' | xargs -n 2
complains invalid array index image - is there a syntax for getting a list of node-adjacent values?
Use below command to get name and image:
kubectl get pods -Ao jsonpath='{range .items[*]}{#.metadata.name}{" "}{#.spec.template.spec.containers[].image}{"\n"}{end}'
It will give output like below:
name image
Useful command, I had to modify it a little to make it work (failed with -a flag). Also, I added a filter to app label and one more field to get: namespace, pod name, image
kubectl get pods --all-namespaces -o jsonpath='{range .items[*]}{#.metadata.namespace}{"\t"}{#.metadata.name}{"\t"}{#.spec.containers[*].image}{"\n"}{end}' -l app=nginx
Thanks! I had to change a little bit, but this worked for me:
#!/bin/bash
releases=$(kubectl get deployment -A --output=jsonpath='{range .items[*]}{#.metadata.namespace}{"|"}{#.metadata.name}{"\n"}{end}')
for release in $releases; do
namespace=$( echo $release | cut -d "|" -f 1)
deployment=$( echo $release | cut -d "|" -f 2)
kubectl rollout restart deployments -n "${namespace}" "${deployment}"
done

kubernetes list all running pods name

I looking for the option to list all pods name
How to do without awk (or cut). Now i'm using this command
kubectl get --no-headers=true pods -o name | awk -F "/" '{print $2}'
Personally I prefer this method because it relies only on kubectl, is not very verbose and we don't get the pod/ prefix in the output:
kubectl get pods --no-headers -o custom-columns=":metadata.name"
You can use the go templating option built into kubectl to format the output to just show the names for each pod:
kubectl get pods --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}'
Get Names of pods using -o=name Refer this cheatsheet for more.
kubectl get pods -o=name
Example output:
pod/kube-xyz-53kg5
pod/kube-xyz-jh7d2
pod/kube-xyz-subt9
To remove trailing pod/ you can use standard bash sed command
kubectl get pods -o=name | sed "s/^.\{4\}//"
Example output:
kube-xyz-53kg5
kube-pqr-jh7d2
kube-abc-s2bt9
To get podname with particular string, standard linux grep command
kubectl get pods -o=name | grep kube-pqr | sed "s/^.\{4\}//"
Example output:
kube-pqr-jh7d2
With this name, you can do things, like adding alias to get shell to running container:
alias bashkubepqr='kubectl exec -it $(kubectl get pods -o=name | grep kube-pqr | sed "s/^.\{4\}//") bash'
You can use custom-columns in output option to get the name and --no-headers option
kubectl get --no-headers=true pods -l app=external-dns -o custom-columns=:metadata.name
You can use -o=name to display only pod names. For example to list proxy pods you can use:
kubectl get pods -o=name --all-namespaces | grep kube-proxy
The result is:
pod/kube-proxy-95rlj
pod/kube-proxy-bm77b
pod/kube-proxy-clc25
There is also this solution:
kubectl get pods -o jsonpath={..metadata.name}
Here is another way to do it:
kubectl get pods -o=name --field-selector=status.phase=Running
The --field-selector=status.phase=Running is needed as the question mention all the running pod names. If the all in the question is for all the namespaces, just add the --all-namespaces option.
Note that this command is very convenient when one want a quick way to access something from the running pod(s), such as logs :
kubectl logs -f $(kubectl get pods -o=name --field-selector=status.phase=Running)
Get all running pods in the namespace
kubectl get pods --field-selector=status.phase=Running --no-headers -o custom-columns=":metadata.name"
From viewing, finding resources.
You could also specify namespace with -n <namespace name>.
jsonpath alternative
kubectl get po -o jsonpath="{range .items[*]}{#.metadata.name}{end}" -l app=nginx-ingress,component=controller
see also:
more examples of kubectl output options
If you want to extract specific container's pod name then
A simple command can do all the hard work
kubectl get pods --template '{{range .items}}{{.metadata.name}}{{end}}' --selector=app=<CONTAINER-NAME>
Just replace <CONTAINER-NAME> with your service container-name
Well, In our case we have kept pods inside different namespace, here to identify the specific pod or list of pods we ran following command-
Approach 1:
To get the list of namespaces
kubectl get ns -A
To get all the pods inside one namespaces kubectl get pods -n <namespace>
Approach 2:
Use this command-
kubectl get pods --all-namespaces
kubectl exec -it $(kubectl get pods | grep mess | awk '{print $1}') /bin/bash
kubectl get po --all-namespaces | awk '{if ($4 != "Running") system ("kubectl -n " $1 " delete pods " $2 " --grace-period=0 " " --force ")}'