Введение
Галерея Field Notes подготовлена частично. Одна группа получила от источника временный HTTP 503, а остальные группы завершили обработку. Вы сохраните свидетельства этого сбоя, запустите новый Job с небольшим допустимым числом повторных попыток и передадите полную коллекцию без перезаписи уже правильных JPEG.
Эта независимая VM содержит собственные двадцать исходных фотографий, общее хранилище, сайт, завершившийся с ошибкой Job и частичные результаты. Файлы предыдущей VM не нужны. Сначала выполните Создайте галерею пакетной обработкой или уверенно владейте изученными там Indexed Job, копированием/редактированием YAML, осмотром Pod и порядком скачивания. Продолжительность в 40 минут — авторская оценка.
Используйте Workspace для команд и Gallery для сайта. Сохраните предоставленные файлы, исходные и эталонные изображения, обработчик, план, сервисы, PVC, исходный Job first-try, его Pod и логи.
Восстановите обработку группы фотографий после сбоя
На этом шаге вы свяжете неполную галерею со штатными данными о сбое индекса, прежде чем выбирать политику восстановления.
Откройте Gallery, выберите Open the gallery и убедитесь, что показано 14 of 20 images available. Первая, третья и четвёртая группы завершены; шесть фотографий группы 1 отсутствуют. Откройте Reference в навигации страницы, чтобы увидеть предоставленный обычный пример, затем переключитесь на Workspace.
Терминал запускается в /home/labex/project/photo-gallery. Подтвердите это с помощью pwd; при необходимости вернитесь командой cd /home/labex/project/photo-gallery. Прочитайте распределение групп и задание сотрудников:
cat inputs/groups.txt
cat inputs/brief.txt
Есть четыре группы с нумерацией от нуля. Индекс 1 содержит от photo-07 до photo-12. Изучите сохранённую попытку:
kubectl describe job first-try -n photo-workshop
Найдите Completion Mode: Indexed, Completed Indexes: 0,2,3, один завершившийся с ошибкой Pod в Pods Statuses и предупреждение FailedIndexes в Events. Завершённые индексы и приведённая ниже таблица Pod позволяют определить недостающую группу. Прочитайте политику Job в предоставленном исходном файле:
cat starter/first-try.yaml
backoffLimitPerIndex: 0 не разрешает замену после сбоя внутри индекса. backoffLimit: 6 — отдельный глобальный бюджет сбоев: он не отменяет нулевое число повторных попыток на индекс. activeDeadlineSeconds: 180 — ограничение активного времени жизни. Job остаётся завершившимся с ошибкой, хотя несколько индексов завершились успешно.
Выведите его фактические Pod и их метки индексов:
kubectl get pods -n photo-workshop -l batch.kubernetes.io/job-name=first-try -L batch.kubernetes.io/job-completion-index
Прочитайте все их логи:
kubectl logs -n photo-workshop job/first-try --all-pods=true --prefix=true
Pod индекса 1 сообщает Source returned HTTP 503 и завершает работу; остальные группы сообщают о своих обработанных фотографиях. HTTP 503 означает, что источник ответил, но был временно недоступен. Это отличается от отсутствующего Pod, сбоя соединения или нечитаемого JPEG.
Скопируйте полное имя Pod индекса 1 из таблицы в следующую команду, заменив POD_NAME, а не вводя этот заполнитель буквально:
kubectl describe pod POD_NAME -n photo-workshop
У его завершившегося контейнера показано Exit Code: 42. Это намеренная реакция предоставленного worker на ошибку HTTP источника, а не общий код ошибки HTTP Kubernetes. Сценарий выдаёт один настоящий 503 на первый запрос индекса 1 каждого нового Job. Следующий заменяющий Pod для того же индекса может успешно прочитать источник. Это управляемое упражнение с временным сбоем, а не утверждение, что любой производственный 503 можно безопасно повторять.
Сохраните завершившийся с ошибкой Job, его Pod и логи, а также четырнадцать существующих правильных JPEG. Обработчик записывает идентичный JPEG только при необходимости; уже совпадающие байты изображения и метаданные файла сохраняются. Записи обработки для каждого Pod и индексные записи изображений могут обновляться, чтобы указать новую успешную попытку.
Разрешите каждому индексу конечное число повторных попыток
Теперь создайте новый Job с одной разрешённой повторной попыткой на индекс. Не пытайтесь превратить уже завершившийся с ошибкой Job в новый запуск.
В Workspace, в /home/labex/project/photo-gallery, скопируйте предоставленный черновик восстановления:
cp starter/recovery-job.yaml gallery-job.yaml
Как и в предыдущей работе, cp оставляет источник нетронутым. Если источник не найден, проверьте pwd, вернитесь в рабочий каталог и повторите точное копирование. Прочитайте черновик:
cat gallery-job.yaml
Он уже запрашивает все четыре индекса с параллелизмом 2, но имеет черновое имя gallery-draft и не разрешает повторные попытки на индекс. С помощью sed -i замените каждое буквальное значение в своей копии; одинарные кавычки защищают выражения замены от интерпретации оболочкой:
sed -i 's/name: gallery-draft/name: gallery-retry/' gallery-job.yaml
sed -i 's/backoffLimitPerIndex: 0/backoffLimitPerIndex: 1/' gallery-job.yaml
Снова прочитайте файл:
cat gallery-job.yaml
Проверьте name: gallery-retry, completions: 4, parallelism: 2 и backoffLimitPerIndex: 1. Сохраните backoffLimit: 6, activeDeadlineSeconds: 180 и все предоставленные настройки обработчика, подключений томов, идентичности и ресурсов. Задание принимает одну или две повторные попытки на индекс, но небольшого конечного числа достаточно. Удаление срока или неограниченные повторные попытки скрыли бы постоянную проблему.
У нового Job новая идентичность в Kubernetes. Он может обрабатывать группы, которые уже завершились успешно; предоставленный worker поддерживает такое повторное выполнение без перезаписи совпадающих JPEG. Не делайте вывод об обработке ровно один раз из успешного завершения Job. Сохранение старого Job со сбоем также оставляет видимой причину восстановления. Если замена не нашла совпадение, снова скопируйте и исправьте черновик до применения. Если вы уже создали неподходящий итоговый Job, сохраните его свидетельства и подготовьте другое новое имя в сохранённом файле вместо изменения неизменяемого шаблона Pod или удаления first-try.
Примените сохранённый новый Job:
kubectl apply -n photo-workshop -f gallery-job.yaml
Дождитесь его успешного завершения:
kubectl wait -n photo-workshop --for=condition=Complete job/gallery-retry --timeout=180s
Изучите его индексы и политику:
kubectl describe job gallery-retry -n photo-workshop
Ожидается Completed Indexes: 0-3. Предыдущая команда wait уже подтвердила штатное условие Complete. Выведите фактические Pod:
kubectl get pods -n photo-workshop -l batch.kubernetes.io/job-name=gallery-retry -L batch.kubernetes.io/job-completion-index
Теперь у индекса 1 есть завершившийся с ошибкой Pod и другой успешно завершившийся заменяющий Pod для того же индекса. Неуспешный Pod — ожидаемое свидетельство этого управляемого теста. Прочитайте их вывод:
kubectl logs -n photo-workshop job/gallery-retry --all-pods=true --prefix=true
Вы должны увидеть настоящий HTTP 503, а затем успешную обработку в заменяющем Pod. Другие группы сообщают Kept для уже совпадающих JPEG. Если ожидание завершилось по тайм-ауту, изучите новый Job и логи Pod; не удаляйте старый сбой, не сбрасывайте подготовку и не увеличивайте лимиты повторных попыток вслепую. Запрошенный параллелизм — настройка желаемого числа одновременно работающих задач, а не абсолютная гарантия числа процессов во время замены.
Передайте восстановленную коллекцию
На этом шаге вы убедитесь, что повторная попытка дала полную пригодную к использованию галерею, и сохраните её текущие выгрузки.
Переключитесь на Gallery, выберите Gallery в навигации страницы и обновите её. Убедитесь, что показано 20 of 20 images available. Откройте Black-and-white blossoms (photo-07), первую фотографию восстановленной группы, и сравните её с собственным источником. Выберите Download thumbnail и Back to gallery. Также откройте Blue and yellow flowers (photo-20) из короткой последней группы.

Восстановленная коллекция теперь включает шесть недостающих фотографий и короткую последнюю группу. Страница по-прежнему ссылается на неизменённый эталон и лицензированные источники.
Вернитесь в галерею и воспользуйтесь Download source index CSV и Download gallery ZIP. Выберите Reference, чтобы убедиться в сохранности предоставленного примера, и Credits, чтобы проверить указание источников. Сайт показывает только фактические читаемые результаты worker; он не заполняет недостающие изображения из исходной коллекции.
Переключитесь на Workspace, в /home/labex/project/photo-gallery. Сохраните текущие настоящие файлы передачи с теми же параметрами, которые вы изучили в первой работе:
curl --fail --silent --show-error http://127.0.0.1:8091/download/index.csv -o gallery-index.csv
curl --fail --silent --show-error http://127.0.0.1:8091/download/gallery.zip -o gallery.zip
Изучите заголовок CSV и первые строки:
head -n 3 gallery-index.csv
Безопасно выведите содержимое архива без распаковки:
python3 -m zipfile -l gallery.zip
Он содержит index.csv и двадцать настоящих JPEG, включая восстановленную группу и photos/photo-20.jpg. Хеши источника и миниатюры связывают каждую фотографию с её собственным результатом; одних имён файлов недостаточно.
Наконец, подтвердите доступность обеих попыток:
kubectl get jobs -n photo-workshop
Исходный first-try завершился с ошибкой, а новый gallery-retry — успешно. Это и есть предполагаемое конечное состояние. Оставьте доступными сохранённый манифест, выгрузки, успешные и неуспешные Pod, исходные четырнадцать JPEG, источники и эталон. Если скачивание не удалось или результат неполон, исправьте обработку или сервис и скачайте заново; не исправляйте полученные файлы вручную.
Резюме
Вы диагностировали частичный сбой Indexed Job, сохранили его штатные свидетельства и завершили настоящую коллекцию с помощью нового Job с конечным числом повторных попыток на индекс. Файлы, полученные из источников, исходные успешные JPEG, работающая галерея, сохранённый манифест и передаваемые материалы теперь согласованы.



