What command can I run to get the oldest pod's name? - kubernetes

I want to get the name of the oldest pod as part of a script. It seems like I should be able to run kubectl get po --no-headers=true, sort-by AGE, and then just pipe to head -n1|awk '{print $1}', but I can't seem to get sort-by working. I'm running kubectl 1.7.9.

The AGE times are in an irregular format (23m, 2d) that’s hard to sort on, but you can ask kubectl to write out the time a pod started instead. The times will come out in the very sortable ISO 8601 format. This recipe to get the single oldest pod might work for you:
kubectl get pods \
--no-headers \
--output=custom-columns=START:.status.startTime,NAME:.metadata.name \
| sort \
| head -1 \
| awk '{print $2}'
The kubectl command asks to only print out the start time and name, in that order, for each pod.
Also consider kubectl get pods -o json, which will give you a very large very detailed JSON record. If you have a preferred full-featured scripting language you can pick that apart there, or use a command-line tool like jq to try digesting it further. Any field path can also be inserted into the custom-columns output spec.

This can be accomplished with:
kubectl get pods --sort-by=.metadata.creationTimestamp -o=name | head -1
I'm not sure what version this started work in, but I'm using it in kubectl 1.12.

Related

How to get the list of pods with container name for pods that have restarted

Using this command, I am able to get the container name that have restarted.
kubectl get pods -o jsonpath='{.items[*].status.containerStatuses[?(#.restartCount>0)].name}'
Is there a way to get the pod name as well in the same command?
It's much easier to get json with kubectl and then process it with jq :
#!/usr/bin/env bash
kubectl get pods -o=json |
jq -r '.items[] |
"\(.metadata.name) \(.status.containerStatuses[]|select(.restartCount>0).name)"'
I've not tried this.
If (!) it works, it's not quite what you want as it should give you every Pod name and then a list of Container names that match the predicate.
I think you can't use kubectl --output=jsonpath alone to filter only the Pod names that have a Container with restarts.
FILTER='
{range .items[*]}
{.metadata.name}
{"\t"}
[
{.status.containerStatuses[?(#.restartCount>0)].name}
]
{"\n"}
{end}
'
kubectl get pods \
--output=jsonpath="${FILTER}"

Retrieve pod description(kubectl describe) from the output of other expression

In kubectl, describe and get -o can be used to get the details of a resource, can we get a describe of only a list of selected pods (different labels), my case is to details of selected pod names for analysis. I'm using describe but unable to get details of specific pods, there are quite a few to do it manually.
If it was events/ specific labels, i could do the below but need more specific details of certain pods out of 100 of them
kubectl get describe po -l app2=test > desc.txt
Kubectl get events -n test|grep -E 'app2|app3|hello1' > events.txt
Tried the below it returns the events of all pods in the namespace (doesnt help), any simpler way or may be this cannot be done or write a script to loop through the o/p?
kubectl get po -n test |grep -E 'app2|app3|hello1' |awk '{print $1}'|k describe po -n test > desc.txt
Thanks for the help!
Are you saying you can't use labels?
Not sure I understand correctly but if you need to choose pods by name - this will work:
kubectl get pod -oname | grep -E 'app2|app3|hello' | xargs kubectl describe

How to replace JSON value in kubectl output using go-template?

I have a configMap and I want to create a backup configMap by using the last applied configuration from that.
I use the following command to get the last applied configuration:
kubectl get cm app-map -n app-space \
-o go-template \
--template='{{index .metadata "annotations" "kubectl.kubernetes.io/last-applied-configuration"}}' > backup.json
It returns something like this [the content of backup.json]:
{"kind":"ConfigMap","apiVersion":"v1","metadata":{"name":"app-map","creationTimestamp":null},"data":{"app.yml":"xxxxxxxxx","config.yml":"yyyyyyyyy"}}
Now, I want my backup configMap to have a different name. So, I want to change the .metadata.name from app-map to app-map-backup.
Is there a way I can achieve that with kubectl and -o go-template? I want to have the name changed before I write it to the backup.json file.
I know I can do that using jq but I do not have permission to install jq on the server where I am using kubectl.
you could use kubectl bulk plugin. The below command will replicate your config map
# get resource(s) and create with field(name) change
kubectl bulk configmap app-map -n app-space create name app-mapp-backup
Kubectl bulk is very powerful to use, I suggest to check samples.
You cannot do this just using kubectl. But there are other ways.
You can download statically linked jq binary from official jq website:
wget https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64
chmod +x jq-linux64
and then you can use this binary like following:
kubectl -o go-template [...] | ./jq-linux64 ...
or you can use sed:
kubectl -o go-template [...] | sed 's/"name":"app-map"/"name":"app-map-backup"/'

Get count of Kubernetes pods that aren't running

I've this command to list the Kubernetes pods that are not running:
sudo kubectl get pods -n my-name-space | grep -v Running
Is there a command that will return a count of pods that are not running?
If you add ... | wc -l to the end of that command, it will print the number of lines that the grep command outputs. This will probably include the title line, but you can suppress that.
kubectl get pods -n my-name-space --no-headers \
| grep -v Running \
| wc -l
If you have a JSON-processing tool like jq available, you can get more reliable output (the grep invocation will get an incorrect answer if an Evicted pod happens to have the string Running in its name). You should be able to do something like (untested)
kubectl get pods -n my-namespace -o json \
| jq '.items | map(select(.status.phase != "Running")) | length'
If you'll be doing a lot of this, writing a non-shell program using the Kubernetes API will be more robust; you will generally be able to do an operation like "get pods" using an SDK call and get back a list of pod objects that you can filter.
You can do it without any external tool:
kubectl get po \
--field-selector=status.phase!=Running \
-o go-template='{{len .items}}'
the filtering is done with field-selectors
the counting is done with go-template: {{ len .items }}

How to apply a jq filter to kubectl output in watch mode?

I want to filter the output of a kubectl command running in --watch mode to keep an eye on changes to a certain k8s annotation. I'm using the following command:
kubectl get pod my-pod --watch -o json | jq '.metadata.annotations["my-annotation"]'
Problem is - nothing is printed until I stop the command. I'd like the jq to process the input and print it as the changes to my-pod happen.
I tried using the --unbuffered flag but it doesn't fix it.
So i've tested your command and it works perfectly. You are however missing a quote at the end of your command.
kubectl get pod nginx-5dfd5597bb-tp8h7 --watch -o json | jq '.metadata.name'
gives me
"nginx-5dfd5597bb-tp8h7"
if you can this command to work but not your own; it is probably related to the brackets and quotes or missing object keys.