2

The problem is that after deploying new deployment like

kubectl apply -f deployment.yml

(let's say deployment with one replica)

Kubernetes will create second pod and shutdown the previous one - ok so far.

But immediately after kubectl apply I would like to detect in CI/CD if deployment was successful and in any case (no matter if rollout succeeded or failed) fetch log from one of newly deployed pod in order to provide as much as possible information in CI/CD log to determine what went wrong.

So I'm using

kubectl rollout status deployment deployment-name

which is waiting for deployment to rollout. Immediately after though you will end up with two pods, one in status "Running" and another "Terminating".

Now the problematic part: Normally I would use method like

kubectl get pods --selector=app=deployment-name --output=jsonpath='{.items[*].metadata.name}' --field-selector=status.phase=Running

but unfortunately it will return names of both pods ("Running" and "Terminating") separated with space.

Now I've tried also

kubectl get pods --selector=app=deployment-name --output=jsonpath='{.items[*].metadata.name}' --field-selector=status.phase=Running,status.phase!=Terminating

according to documentation:

but for some reason this will return exactly the same result, both pods running and terminating.

The quesiton is:

How to properly exclude TERMINATING pods from the result?

stopsopa
  • 408
  • 4
  • 20

2 Answers2

2

Known issue since 2018. Havent resolved yet.

Please refer to Kubectl returns pods in various states when only those in Running state are selected via --field-selector, or -o jsonpath for more details.

In short: There is NO normal, SHORT, adequate one-line command that would do what you want.

Reasons behind that:

This looks like not a bug. kubectl get pods output STATUS column not shows status.phase. kubectl get pods displays table format of PodList object and uses status.containerStatuses states to display STATUS column data.

Pod phase valid states are pending, running, succeeded, failed and unknown. From this document 'Running' state depends on 'restartPolicy'.

Jsonpath applies on 'PodList' object, not on kubectl output. status.containerStatuses gives whether pod containers running or not. Field selectors vary by Kubernetes resource types. status.containerStatuses not supported in pods field selectors.

Workarounds:

1. kubectl get pods | grep Running

2. kubectl get pods -o jsonpath='{.items[*].status.containerStatuses[*].state.running},{.items[*].metadata.name}' --field-selector=status.phase==Running | sed 's/ /\n/' | grep startedAt | awk -F',' '{print $2}'

3. (source) kubectl get pods --field-selector=status.phase=Running --template {{range .items}}{{ if not .metadata.deletionTimestamp }}{{.metadata.name}}{{"\n"}}{{end}}{{end}}

Vit
  • 7,740
  • 15
  • 40
  • Is it possible to `kubectl wait` for a pod with a given selector except those in terminating state? – guai Jan 25 '23 at 07:41
0

from the command line you can use commands like

grep

to catch what you like or you can do what I do and just look at all the pods with

watch 

command to see the changes and look at the errors from a separate terminal.

What I use for these kind of situations:

watch -n0.5 " kubectl get pods | grep -v 'Running' "

to catch pods with non Running status (Completed, OOMKilled, Pending, etc.) then from a separate terminal

kubectl logs podName && kubectl describe pods podName

I hope I was a little help.

Even for getting the latest revision number I use

kubectl rollout history deployment.v1.apps/deploymentName | tail -2 | head -1 | awk '{print $1}'

But maybe you can use

kubectl get pods  --sort-by=.metadata.creationTimestamp 

and then take the last one so finally maybe, you can use

kubectl logs -c [containerName] $(kubectl get pods  --sort-by=.metadata.creationTimestamp | tail -1 | awk '{print$1}') 

this can give me the latest created pod and its logs

Catastrophe
  • 322
  • 3
  • 12
  • It doesn't help at all. I said that I need to do this in CI/CD pipeline so using watch is not an option. Besides I know how generally use kubectl get pods to list all pods... I know also how to use kubectl logs when I know which pod to get informations from. What I need is to GET THE LIST OF NEWLY CREATED PODS EXCLUDING THE OLD PODS. That's all, But for some reason it seems like it can't be done with oneliner. I already have script using sorting, grep filtering and generally processing regular pods listing step by step, but I believe there should be way to do this in one-liner. – stopsopa Mar 18 '21 at 21:38
  • 1
    In that case I can not help you because there is no one-liner that I know of. Even for getting the latest revision number I use `kubectl rollout history deployment.v1.apps/deploymentName | tail -2 | head -1 | awk '{print $1}'`. But maybe you can use `kubectl get pods --sort-by=.metadata.creationTimestamp` and then take the last one so finally maybe, you can use `kubectl logs -c [containerName] $(kubectl get pods --sort-by=.metadata.creationTimestamp | tail -1 | awk '{print$1}')` this can give me the latest created pod and its logs. – Catastrophe Mar 19 '21 at 06:33
  • Ahh, that's actually good clue to try to list pods particular rollout. I didn't think about it and now it's seems obvious. For some reasons I've tried to list pods of deployment in general. – stopsopa Mar 20 '21 at 22:43
  • Glad I was able to help a little. Added to my answer for others to see. Wish best :) – Catastrophe Mar 21 '21 at 17:18