Подождите, пока задание kubernetes завершится в случае неудачи или успеха с помощью командной строки
Как лучше всего дождаться завершения работы kubernetes? Я заметил много предложений по использованию:
kubectl wait --for=condition=complete job/myjob
но я думаю, что это работает, только если работа успешна. если это не удается, я должен сделать что-то вроде:
kubectl wait --for=condition=failure job/myjob
есть ли способ ожидания обоих условий с помощью wait? если нет, то как лучше всего дождаться, пока работа будет успешной или неудачной?
5 ответов
kubectl wait --for=condition=<condition name
ждет определенного условия, поэтому в afaik он не может указать несколько условий в данный момент.
Мой обходной путь использует oc get --wait
, --wait
закрывается команда, если целевой ресурс обновлен. Я буду следить status
раздел работы с использованием oc get --wait
до тех пор status
обновляется. Обновление status
раздел означает, что задание завершено с некоторыми условиями статуса.
Если работа выполнена успешно, то status.conditions.type
обновляется сразу как Complete
, Но если работа не удалась, модуль будет автоматически перезапущен независимо от того, restartPolicy
является OnFailure
или же Never
, Но мы можем считать, что работа Failed
статус, если не обновлен как Complete
после первого обновления.
Посмотрите мои тестовые данные следующим образом.
- Задание yaml для успешного тестирования завершено
# vim job.yml apiVersion: партия /v1 вид: работа метаданные: имя: пи спецификация: параллелизм: 1 доработок: 1 шаблон: метаданные: имя: пи спецификация: контейнеры: - имя: пи изображение: perl команда: ["perl", "-wle", "exit 0"] restartPolicy: никогда
- Это покажет вам
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 'не удалось | завершить' || эхо "Failed" job.batch/pi создан карта [время начала:2019-03-09T12:30:16Z активна:1] Завершено
- Задание yaml для тестирования не выполнено
# vim job.yml apiVersion: партия /v1 вид: работа метаданные: имя: пи спецификация: параллелизм: 1 доработок: 1 шаблон: метаданные: имя: пи спецификация: контейнеры: - имя: пи изображение: perl команда: ["perl", "-wle", "exit 1"] restartPolicy: никогда
- Это покажет вам
Failed
если первое обновление вакансии неComplete
, Проверьте, если после удаления существующего ресурса задания.
# oc удалить задание pi job.batch "пи" удален # 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 'не удалось | завершить' || эхо "Failed" job.batch/pi создан map[active:1 startTime:2019-03-09T12:31:05Z] Не удалось
Я надеюсь, что это поможет вам.:)
Выполните первое условие ожидания как подпроцесс и запишите его 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
В
wait -n
подход не работает для меня, так как он мне нужен для работы как на Linux, так и на Mac.
Я немного улучшил ответ Клейтона, потому что его сценарий не работал с
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 logs --follow
:
kubectl wait --for=condition=ready pod --selector=job-name=YOUR_JOB_NAME --timeout=-1s
kubectl logs --follow job/YOUR_JOB_NAME
Он завершится, когда ваша работа завершится, с любым статусом.