等待 kubernetes 作业完成的最佳方法是什么?我注意到很多使用建议:
kubectl wait --for=condition=complete job/myjob
但我认为只有在工作成功的情况下才有效。如果失败,我必须执行以下操作:
kubectl wait --for=condition=failure job/myjob
有没有办法使用等待来等待这两个条件?如果没有,等待工作成功或失败的最佳方法是什么?
等待 kubernetes 作业完成的最佳方法是什么?我注意到很多使用建议:
kubectl wait --for=condition=complete job/myjob
但我认为只有在工作成功的情况下才有效。如果失败,我必须执行以下操作:
kubectl wait --for=condition=failure job/myjob
有没有办法使用等待来等待这两个条件?如果没有,等待工作成功或失败的最佳方法是什么?
将第一个等待条件作为子进程运行并捕获其 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
orcondition=complete
为真时,执行将退出 while 循环(retval_complete
or retval_failed
will be 0
)。
接下来,您只需要检查并根据您想要的条件采取行动。就我而言,我想快速失败并在作业失败时停止执行。
该wait -n
方法对我不起作用,因为我需要它同时在 Linux 和 Mac 上工作。
我对 Clayton 提供的答案进行了一些改进,因为他的脚本无法set -e -E
启用。即使在这种情况下,以下内容也将起作用。
while true; do
if kubectl wait --for=condition=complete --timeout=0 job/name 2>/dev/null; then
job_result=0
break
fi
if kubectl wait --for=condition=failed --timeout=0 job/name 2>/dev/null; then
job_result=1
break
fi
sleep 3
done
if [[ $job_result -eq 1 ]]; then
echo "Job failed!"
exit 1
fi
echo "Job succeeded"
您可能需要添加超时以避免无限循环,具体取决于您的情况。
kubectl wait --for=condition=<condition name
正在等待特定条件,因此目前无法指定多个条件。
我的解决方法是使用oc get --wait
,--wait
如果目标资源已更新,则关闭该命令。我将status
使用oc get --wait
直到status
更新来监控工作的一部分。部分的更新status
意味着作业已完成并具有一些状态条件。
如果作业成功完成,则status.conditions.type
立即更新为Complete
. 但如果作业失败,则作业 pod 将自动重新启动,无论restartPolicy
是OnFailure
还是Never
。但是如果没有像第一次更新后那样更新,我们可以认为该工作是Failed
状态Complete
。
看我的测试证据如下。
# vim 工作.yml api版本:批处理/v1 种类:工作 元数据: 名称:pi 规格: 并行度:1 完成:1 模板: 元数据: 名称:pi 规格: 容器: - 名称:pi 图片:perl 命令:["perl", "-wle", "exit 0"] 重启策略:从不
Complete
它是否成功完成了工作。# oc create -f job.yml && oc get job/pi -o=jsonpath='{.status}' -w && oc get job/pi -o=jsonpath='{.status.conditions[*].type}' | grep -i -E '失败|完成' || 回显“失败” job.batch/pi 创建 map[startTime:2019-03-09T12:30:16Z active:1]完成
# vim 工作.yml api版本:批处理/v1 种类:工作 元数据: 名称:pi 规格: 并行度:1 完成:1 模板: 元数据: 名称:pi 规格: 容器: - 名称:pi 图片:perl 命令:["perl", "-wle", "exit 1"] 重启策略:从不
Failed
如果第一次工作更新不是,它将显示您Complete
。删除现有作业资源后测试是否。# oc 删除作业 pi job.batch "pi" 已删除 # oc create -f job.yml && oc get job/pi -o=jsonpath='{.status}' -w && oc get job/pi -o=jsonpath='{.status.conditions[*].type}' | grep -i -E '失败|完成' || 回显“失败” job.batch/pi 创建 地图[活动:1 开始时间:2019-03-09T12:31:05Z]失败
我希望它对你有帮助。:)