我正在寻找一种方法,等待Job部署完成后成功完成。
作业是通过CD在AWS的K8S上从Azure DevOps部署的。每次部署时,它都使用Fluent migrations运行一次增量数据库迁移。我需要阅读pod.status.phase
字段。
如果字段为“ Succeeded
”,则CD将继续。如果它是“ Failed
,则CD停止。
有人知道如何实现这一目标吗?
答案 0 :(得分:1)
我们可以使用K8S Rest API检查Pod的状态。
为了连接到API,我们需要获得一个令牌: 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 name
APISERVER=$(kubectl config view -o jsonpath="{.clusters[?(@.name==\"$CLUSTER_NAME\")].cluster.server}")
# Gets the token value
TOKEN=$(kubectl get secrets -o jsonpath="{.items[?(@.metadata.annotations['kubernetes\.io/service-account\.name']=='default')].data.token}"|base64 -d)
通过以上代码,我们获得了令牌和 APISERVER 地址。
在Azure DevOps上,在目标版本上,在“代理作业”上,我们可以添加Bash任务:
#name of K8S Job object we are waiting to finish
JOB_NAME=name-of-db-job
APISERVER=set-api-server-from-previous-code
TOKEN=set-token-from-previous-code
#log APISERVER and JOB_NAME for troubleshooting
echo API Server: $APISERVER
echo 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 2
done
如果Failed
,脚本将以代码1退出,并且CD将停止(如果以此方式配置)。
如果Succeeded
存在,代码为0,CD将继续。
在最终设置中: -脚本是工件的一部分,我正在Agent Job的Bash任务中使用它。 -我已将JOB_NAME放入Task Env。 Vars,因此可以用于多个数据库迁移。 -令牌和API服务器地址在全局级别的“变量”组中。
待办事项:
curl
不存在,代码为0。它需要--fail标志,但行上方仍存在0。答案 1 :(得分:1)
我认为最好的方法是使用 kubectl wait
命令:
等待一种或多种资源的特定条件。
该命令占用多个资源,并等待直到指定 每个给定资源的“状态”字段中都可以看到这种情况。
仅在作业完成(或达到超时)时返回:
kubectl wait --for=condition=complete job/myjob --timeout=60s
如果您未设置--timeout
,则默认等待时间为30秒。
注意::kubectl wait
是在Kubernetes v1.11.0上引入的。如果您使用的是旧版本,则可以使用kubectl get
和--field-selector
来创建一些逻辑:
kubectl get pod --field-selector=status.phase=Succeeded