Waiting for K8S Job to finish [duplicate] Waiting for K8S Job to finish [duplicate] kubernetes kubernetes

Waiting for K8S Job to finish [duplicate]


We can check Pod status using K8S Rest API.

In order to connect to API, we need to get a token:https://kubernetes.io/docs/tasks/administer-cluster/access-cluster-api/#without-kubectl-proxy

# Check all possible clusters, as you .KUBECONFIG may have multiple contexts:kubectl config view -o jsonpath='{"Cluster name\tServer\n"}{range .clusters[*]}{.name}{"\t"}{.cluster.server}{"\n"}{end}'# Select name of cluster you want to interact with from above output:export CLUSTER_NAME="some_server_name"# Point to the API server refering the cluster nameAPISERVER=$(kubectl config view -o jsonpath="{.clusters[?(@.name==\"$CLUSTER_NAME\")].cluster.server}")# Gets the token valueTOKEN=$(kubectl get secrets -o jsonpath="{.items[?(@.metadata.annotations['kubernetes\.io/service-account\.name']=='default')].data.token}"|base64 -d)

From above code we have acquired TOKEN and APISERVER address.

On Azure DevOps, on your target Release, on Agent Job, we can add Bash task:

#name of K8S Job object we are waiting to finishJOB_NAME=name-of-db-jobAPISERVER=set-api-server-from-previous-codeTOKEN=set-token-from-previous-code#log APISERVER and JOB_NAME for troubleshootingecho API Server: $APISERVERecho JOB NAME: $JOB_NAME#keep calling API until you get status Succeeded or Failed.while true; do  #read all pods and query for pod containing JOB_NAME using jq.  #note that you should not have similar pod names with job name otherwise you will get mutiple results. This script is not expecting multiple results.  res=$(curl -X GET $APISERVER/api/v1/namespaces/default/pods/ --header "Authorization: Bearer $TOKEN" --insecure | jq --arg JOB_NAME "$JOB_NAME" '.items[] | select(.metadata.name | contains($JOB_NAME))' | jq '.status.phase')  if (res=="Succeeded"); then   echo Succeeded   exit 0  elif (res=="Failed"); then    echo Failed    exit 1  else        echo $res  fi  sleep 2done

If Failed, script will exit with code 1 and CD will stop (if configured that way).
If Succeeded, exist with code 0 and CD will continue.

In final setup:- Script is part of artifact and I'm using it inside Bash task in Agent Job.- I have placed JOB_NAME into Task Env. Vars so it can be used for multiple DB migrations.- Token and API Server address are in Variable group on global level.

TODO:

  • curl is not existing with code 0 if URL is invalid. It needs --fail flag, but still above line exists 0.
  • "Unknown" Pod status should be handled as well


I think the best approach is to use the kubectl wait command:

Wait for a specific condition on one or many resources.

The command takes multiple resources and waits until the specified condition is seen in the Status field of every given resource.

It will only return when the Job is completed (or the timeout is reached):

kubectl wait --for=condition=complete job/myjob --timeout=60s

If you don't set a --timeout, the default wait is 30 seconds.


Note: kubectl wait was introduced on Kubernetes v1.11.0. If you are using older versions, you can create some logic using kubectl get with --field-selector:

kubectl get pod --field-selector=status.phase=Succeeded