使用命令行等待kubernetes作业在失败/成功时完成
等待kubernetes作业完成的最佳方式是什么?我注意到有很多建议可以使用:使用命令行等待kubernetes作业在失败/成功时完成,kubernetes,wait,jobs,kubectl,kubernetes-jobs,Kubernetes,Wait,Jobs,Kubectl,Kubernetes Jobs,等待kubernetes作业完成的最佳方式是什么?我注意到有很多建议可以使用: kubectl wait --for=condition=complete job/myjob 但我认为只有在工作成功的情况下,这才有效。如果失败了,我必须做如下事情: kubectl wait --for=condition=failure job/myjob 是否有一种方法可以使用wait同时等待这两种情况?如果不是,等待工作成功或失败的最佳方式是什么 kubectl wait--for=condition=
kubectl wait --for=condition=complete job/myjob
但我认为只有在工作成功的情况下,这才有效。如果失败了,我必须做如下事情:
kubectl wait --for=condition=failure job/myjob
是否有一种方法可以使用wait同时等待这两种情况?如果不是,等待工作成功或失败的最佳方式是什么
kubectl wait--for=condition=将第一个等待条件作为子流程运行并捕获其PID。如果满足条件,此进程将退出,退出代码为0
kubectl wait --for=condition=complete job/myjob &
completion_pid=$!
对故障等待条件执行相同操作。这里的技巧是添加&&exit 1
,这样子流程在作业失败时返回一个非零的退出代码
kubectl wait --for=condition=failed job/myjob && exit 1 &
failure_pid=$!
然后使用Bash内置的wait-n$PID1$PID2
等待其中一个条件成功。该命令将捕获要退出的第一个进程的退出代码:
wait -n $completion_pid $failure_pid
最后,您可以检查wait-n
的实际退出代码,以查看作业是否失败:
exit_code=$?
if (( $exit_code == 0 )); then
echo "Job completed"
else
echo "Job failed with exit code ${exit_code}, exiting..."
fi
exit $exit_code
完整示例:
# wait for completion as background process - capture PID
kubectl wait --for=condition=complete job/myjob &
completion_pid=$!
# wait for failure as background process - capture PID
kubectl wait --for=condition=failed job/myjob && exit 1 &
failure_pid=$!
# capture exit code of the first subprocess to exit
wait -n $completion_pid $failure_pid
# store exit code in variable
exit_code=$?
if (( $exit_code == 0 )); then
echo "Job completed"
else
echo "Job failed with exit code ${exit_code}, exiting..."
fi
exit $exit_code
当
--timeout=0
时,可以利用该行为
在这种情况下,命令行立即返回结果代码0或1。下面是一个例子:
retval_complete=1
retval_failed=1
while [[ $retval_complete -ne 0 ]] && [[ $retval_failed -ne 0 ]]; do
sleep 5
output=$(kubectl wait --for=condition=failed job/job-name --timeout=0 2>&1)
retval_failed=$?
output=$(kubectl wait --for=condition=complete job/job-name --timeout=0 2>&1)
retval_complete=$?
done
if [ $retval_failed -eq 0 ]; then
echo "Job failed. Please check logs."
exit 1
fi
因此,当condition=failed
或condition=complete
为真时,执行将退出while循环(retval\u complete
或retval\u failed
将为0
)
接下来,你只需要检查并根据你想要的条件采取行动。在我的例子中,我希望在作业失败时快速失败并停止执行。等待-n方法不适合我,因为我需要它在Linux和Mac上都能工作
kubectl wait --for=condition=failed job/myjob && exit 1 &
failure_pid=$!
我对Clayton提供的答案做了一点改进,因为他的脚本无法在启用set-e-e
的情况下工作。即使在这种情况下,以下方法也会起作用
为true时;做
如果kubectl wait--for=condition=complete--timeout=0作业/name 2>/dev/null;然后
作业结果=0
打破
fi
如果kubectl wait--for=condition=failed--timeout=0作业/name 2>/dev/null;然后
作业结果=1
打破
fi
睡眠3
完成
如果[$job_result-等式1]];然后
echo“作业失败!”
出口1
fi
echo“作业成功”
您可能需要添加一个超时来避免无限循环,这取决于您的情况。我最后只是制作了一个简单的脚本来检查状态,如您所示:
直到[[$SECONDS-gt$end]].[$(kubectl get jobs$job_name-o jsonpath='{.status.conditions[?(@.type==“Failed”)].status}')==“True”].[$(kubectl get jobs$job_name-o jsonpath='{.status.conditions[?(@.type==“Complete”)].status}')==“True”];do
这很好,我很抱歉展示了openshift cli
示例。但是您可以赶上kubernetes cli
,这很好!实际上没有--wait和-w代表--watch您可以使用if wait…
而不是将退出代码存储在变量中。我认为--for=condition=failure
应该是--for=condition=failed
?@JamesMcLaughlin您是对的,可以在API参考中看到kubectl explain job.status.conditions.type
。我已经更新了代码:)@Exagone313您是对的-在原始脚本中我使用了陷阱,所以我在其他地方使用了退出代码。wait-n
在MacOS上不可用:(
exit_code=$?
if (( $exit_code == 0 )); then
echo "Job completed"
else
echo "Job failed with exit code ${exit_code}, exiting..."
fi
exit $exit_code
# wait for completion as background process - capture PID
kubectl wait --for=condition=complete job/myjob &
completion_pid=$!
# wait for failure as background process - capture PID
kubectl wait --for=condition=failed job/myjob && exit 1 &
failure_pid=$!
# capture exit code of the first subprocess to exit
wait -n $completion_pid $failure_pid
# store exit code in variable
exit_code=$?
if (( $exit_code == 0 )); then
echo "Job completed"
else
echo "Job failed with exit code ${exit_code}, exiting..."
fi
exit $exit_code
retval_complete=1
retval_failed=1
while [[ $retval_complete -ne 0 ]] && [[ $retval_failed -ne 0 ]]; do
sleep 5
output=$(kubectl wait --for=condition=failed job/job-name --timeout=0 2>&1)
retval_failed=$?
output=$(kubectl wait --for=condition=complete job/job-name --timeout=0 2>&1)
retval_complete=$?
done
if [ $retval_failed -eq 0 ]; then
echo "Job failed. Please check logs."
exit 1
fi