일시적 실패 후 배치 완료하기

KubernetesBeginner
지금 연습하기

소개

Field Notes에는 일부만 준비된 갤러리가 있습니다. 한 그룹은 원본에서 일시적인 HTTP 503 응답을 받았고, 나머지 그룹은 완료되었습니다. 실패 증거를 보존하고, 적은 횟수의 재시도를 허용하는 새 Job을 실행한 뒤, 이미 올바른 JPEG를 다시 쓰지 않고 전체 모음을 전달합니다.

이 독립 VM에는 자체적인 원본 사진 스무 장, 공유 스토리지, 웹사이트, 실패한 Job, 부분 출력이 포함되어 있습니다. 이전 VM의 파일은 필요하지 않습니다. 먼저 배치로 갤러리 만들기를 완료하거나, 그 실습의 Indexed Job, YAML 복사/편집, Pod 조사, 다운로드 작업 흐름에 익숙해야 합니다. 40분은 저자의 예상 시간입니다.

명령은 Workspace에서 실행하고 웹사이트는 Gallery에서 확인합니다. 제공된 파일, 원본 및 참조 이미지, 처리기, 계획, 서비스, PVC, 원래의 first-try Job, 해당 Pod와 로그를 보존하세요.

실패한 사진 그룹 복구하기

이 단계에서는 복구 정책을 선택하기 전에 불완전한 갤러리를 Kubernetes에서 실패한 인덱스와 연결합니다.

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

0부터 번호를 매긴 그룹 네 개가 있습니다. 인덱스 1에는 photo-07부터 photo-12까지 포함됩니다. 보존된 시도를 조사하세요.

kubectl describe job first-try -n photo-workshop

Completion Mode: Indexed, Completed Indexes: 0,2,3, Pods Statuses의 실패한 Pod 하나, Events 아래의 FailedIndexes 경고를 찾으세요. 완료된 인덱스와 아래의 Pod 표로 누락된 그룹을 식별할 수 있습니다. 제공된 소스에서 정책을 읽으세요.

cat starter/first-try.yaml

backoffLimitPerIndex: 0은 해당 인덱스에서 실패한 뒤 대체 Pod를 허용하지 않습니다. backoffLimit: 6은 별도의 전역 실패 예산입니다. 인덱스별 허용 횟수가 0인 설정을 무시하지 않습니다. 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

모든 Pod의 로그를 읽으세요.

kubectl logs -n photo-workshop job/first-try --all-pods=true --prefix=true

인덱스 1의 Pod는 Source returned HTTP 503을 보고하고 종료합니다. 나머지 그룹은 완료한 사진을 보고합니다. HTTP 503은 원본이 응답했지만 일시적으로 이용할 수 없었다는 뜻입니다. 이는 Pod 누락, 연결 실패, 읽을 수 없는 JPEG와는 다릅니다.

표에서 인덱스 1의 전체 Pod 이름을 복사하여 다음 명령에 넣으세요. POD_NAME이라는 자리표시자를 그대로 입력하지 말고 교체하세요.

kubectl describe pod POD_NAME -n photo-workshop

종료된 컨테이너에는 Exit Code: 42가 표시됩니다. 이는 제공된 워커가 원본 HTTP 오류에 의도적으로 반환하는 응답이며, 일반적인 Kubernetes HTTP 오류 코드가 아닙니다. 이 시나리오는 각 새 Job의 인덱스 1에서 첫 요청에 실제 503을 한 번 발생시킵니다. 같은 인덱스의 다음 대체 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 식별 정보를 갖습니다. 이전에 성공한 그룹도 처리할 수 있습니다. 제공된 워커는 이러한 반복 실행에서 일치하는 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 명령이 이미 Kubernetes 고유의 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에서의 성공적인 처리가 순서대로 보여야 합니다. 다른 그룹은 이미 일치했던 JPEG에 대해 Kept를 보고합니다. 대기 시간이 초과되면 새 Job과 Pod 로그를 조사하세요. 이전 실패를 지우거나, setup을 초기화하거나, 재시도 한도를 무작정 늘리지 마세요. 요청된 병렬도는 원하는 동시 실행 설정이며, 교체 중의 절대적인 프로세스 수를 보장하지는 않습니다.

복구된 모음 전달하기

이 단계에서는 재시도로 사용 가능한 전체 갤러리가 만들어졌음을 확인하고 현재 다운로드를 저장합니다.

Gallery로 전환하여 페이지 탐색 메뉴의 Gallery를 선택하고 새로고침하세요. 20 of 20 images available을 확인하세요. 복구된 그룹의 첫 사진인 Black-and-white blossoms (photo-07)를 열고 해당 사진의 원본과 비교하세요. Download thumbnail과 Back to gallery를 선택하세요. 사진이 적은 마지막 그룹의 Blue and yellow flowers (photo-20)도 여세요.

복구된 Field Notes 모음

복구된 모음에는 이제 누락되었던 사진 여섯 장과 사진이 적은 마지막 그룹이 포함됩니다. 페이지는 여전히 변경되지 않은 참조 예제와 라이선스가 확보된 원본으로 연결됩니다.

갤러리로 돌아와 Download source index CSV와 Download gallery ZIP을 사용하세요. Reference를 선택하여 제공된 예제가 온전히 유지되는지 확인하고, Credits에서 원본 출처 표시를 확인하세요. 사이트는 워커가 실제로 출력한 읽을 수 있는 결과만 표시하며, 원본 모음에서 누락된 이미지를 채워 넣지 않습니다.

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와, 복구된 그룹 및 photos/photo-20.jpg를 포함한 실제 JPEG 스무 장이 들어 있습니다. 원본 및 썸네일 해시는 각 사진을 해당 결과와 연결합니다. 파일 이름만으로는 충분하지 않습니다.

마지막으로 두 시도를 계속 확인할 수 있는지 점검하세요.

kubectl get jobs -n photo-workshop

원래의 first-try는 실패 상태이고 새 gallery-retry는 완료 상태입니다. 이것이 의도한 최종 상태입니다. 저장된 매니페스트, 다운로드, 성공 및 실패한 Pod, 원래 JPEG 열네 장, 원본, 참조 예제를 사용할 수 있도록 남겨 두세요. 다운로드가 실패하거나 불완전하면 워크로드나 서비스를 수정한 뒤 다시 다운로드하세요. 수신한 파일을 직접 수정하지 마세요.

요약

Indexed Job의 부분 실패를 진단하고 Kubernetes 고유의 증거를 보존한 뒤, 인덱스별 재시도가 유한한 새 Job으로 실제 모음을 완성했습니다. 원본에서 생성된 파일, 원래의 성공한 JPEG, 실행 중인 갤러리, 저장된 매니페스트, 전달 파일이 이제 일치합니다.