How to get the count of the jobs running using kubectl command? - kubernetes

I am able to get the jobs under the namespace using kubectl command:
kubectl get jobs --namespace xxx
This is giving me the jobs information
I would like to print the count of jobs using kubectl command. How to do that?

go-template way, no pipes or installation needed. Just good old kubectl:
kubectl get jobs --namespace xxx -o go-template='{{printf "%d\n" (len .items)}}'
len is an inbuild function in go-template to return the number of elements to its argument. Eg: items.

If you are want to get number of job that are running in namespace you can get it using like this also
kubectl get jobs -n dcs | grep -v NAME | wc -l

You can use the, wc or jq for this
kubectl get jobs --output name | wc -l
with jq :
kubectl get jobs --output json | jq -j '.items | length'

Related

I was to get a list of my Kubernetes namespace based on a particular label

I am writing a bash script and I need the kubectl command to get all the namespace in my cluster based on a particular label.
kubectl get ns -l=app=backend
When I run the command above I get:
no resources found
only the pods in the ns have that label. wondering if there's a way I can manipulate kubectl to output only the ns of the pods that have that label
You can combine a few commands to do something like:
kubectl get pods -A -l app=backend -o json |
jq -r '.items[]|.metadata.namespace' |
sort -u
This gets a list of all pods in all namespaces that match the label selector; uses jq to extract the namespace name from each pod, and then uses sort -u to produce a unique list.
You can actually do this without jq by using the go-template output format, but for me that always means visiting the go template documentation:
kubectl get pods -A -l app=backend \
-o go-template='{{range .items}}{{.metadata.namespace}}{{"\n"}}{{end}}' |
sort -u

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 values of deployed images helm/kubernetes

I'm looking for an easy way to find what version of my images I have deployed in my kubernetes environment.
The closest thing I can find to what I want is helm get values <namespace> -a
(but this gets values and dumps all (computed) values)
Is there an easier/clean way to get a list of images and versions deployed??
Thanks in advance
You can use kubectl to get all images form all pods running in the namespace/cluster. See List All Container Images Running in a Cluster.
For one namespace:
kubectl get pods -n <namespace> -o jsonpath="{..image}" | tr -s '[[:space:]]' '\n' | sort | uniq -c
For the whole cluster:
kubectl get pods --all-namespaces -o jsonpath="{..image}" | tr -s '[[:space:]]' '\n' | sort | uniq -c
I use something like this:
kubectl get po --all-namespaces -o yaml | grep image: | cut -d ":" -f2,3 | sort | uniq
this command shows all images used in your cluster and removes the duplicates.
You can use the helm plugin - helm images.
URL: https://github.com/nikhilsbhat/helm-images
Usage:
images get [RELEASE] [CHART] [flags]

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