4

I am trying to create a shell script that will validate that certain pods are ready by checking the READY heading showing 1/1. I have tried two ways.

1.

ready=$(oc get pods | awk '{print $2}' | tail -n +2) # prints 1/1 or 0/1 for each pod
until [[ ${ready} == "1/1" ]]
do
  echo "Waiting for pods to be ready."
  sleep 3
done

Above script just keeps saying "Waiting for pods to be ready" even when the pods are ready and displaying 1/1 in the READY column.

2.

while true ; do
  for i in 1 2 3; do
  ready=`oc get pods | awk '{print $2}' | tail -n +2 | head -n $i` 

  if [[ "${ready}" == "1/1" ]]; then
    echo "pods are up and running"
  else
    echo "waiting for pods to be ready"
  sleep 10
  break
  fi
  done
done

Above script just continually prints waiting for pods to be ready and pods are up and running.

Any help would be appreciated, I am starting with Bash and not quite sure what to do.

Ren
  • 41
  • 1
  • 1
  • 2
  • 2
    why do you need the scripts? Are you using pod directly, or its sub resources of deployment? Using pod directly is not recommended. If you have a deployment, did you try `oc rollout status` ? – C Han May 20 '20 at 21:55
  • 1
    Take a look at https://stackoverflow.com/a/61446220/6758654. You really shouldn't be relying on `1/1`, there are more and better ways to determine exactly what pods are ready. – Will Gordon May 21 '20 at 01:23
  • @C Han, we use scripts to deploy our apps sort of like Helm as we don't yet have Helm. – Ren May 21 '20 at 12:16
  • I am trying another option to poll the readiness and here is what I did. `status=$(oc get pods -o jsonpath='{.items[*].status.containerStatuses[?(@.ready)].ready}') for stat in $(oc get pods -o jsonpath='{.items[*].status.containerStatuses[?(@.ready)].ready}'); do until [[ "${stat}" == "true" ]]; do echo "waiting for pods to be ready" sleep 10 done done echo "pods are ready"` – Ren May 21 '20 at 18:04

3 Answers3

10

I'm surprised no one so far has mentioned the experimental, yet official kubectl wait:
$ kubectl wait ([-f FILENAME] | resource.group/resource.name | resource.group [(-l label | --all)]) [--for=delete|--for condition=available]

nichoio
  • 6,289
  • 4
  • 26
  • 33
  • 5
    This answer should be way on top! `kubectl -n mynamespace wait pod --for=condition=Ready -l labelKey1=labelValue1,labelKey2=labelValue2` – wormhit Jun 22 '21 at 15:17
  • After my initial excitement on this response: this condition will wait ONLY if the pod exists (i.e. managed to be created). In my script, after `helm install` pod still needs some time to appear hence the command fails with `Error from server (NotFound): pods "proc-s1e2-0" not found` – Jarek Jul 29 '22 at 07:33
  • I suppose this was resolved by the time, but for anyone wondering there is a wait flag on helm install command. – Lucas Gras May 25 '23 at 15:44
6

Following solutions works for me

while [ "$(kubectl get pods -l=app='activemq' -o jsonpath='{.items[*].status.containerStatuses[0].ready}')" != "true" ]; do
   sleep 5
   echo "Waiting for Broker to be ready."
done
ImranRazaKhan
  • 1,955
  • 5
  • 33
  • 74
4

For pod status, the one and only answer (a pod can be Running but not yet ready!):

kubectl get pods -l <key=val> -o 'jsonpath={..status.conditions[?(@.type=="Ready")].status}'

For individual container statuses (need to be "true"):

kubectl get pod <pod_name> --output="jsonpath={.status.containerStatuses[*].ready}" | cut -d' ' -f2

If you want to check the status of several pods, you can use -l to filter and just prefix .items[*]:

kubectl get pods -l <key=val> --output="jsonpath={.items[*].status.conditions[*].status}"
seebi
  • 488
  • 5
  • 9