[IT-방법] 잡 실전 예제 따라하기 – 배포부터 동작 검증까지 단계별 실습

잡 관련 쿠버네티스 구조를 설명하는 대표 이미지

왜 쿠버네티스 잡(Job)을 제대로 다뤄야 할까요

어느 날 새벽, 데이터베이스 마이그레이션 작업이 실패했다는 알람을 받고 급하게 클러스터에 접속한 적이 있나요? 로그를 확인하려 했지만 이미 Pod는 사라져 있고, 작업이 성공했는지 실패했는지조차 알 수 없는 막막한 상황을 마주해 본 SRE라면 잡(Job)의 관리 능력이 얼마나 중요한지 뼈저리게 느끼실 거예요.

단순히 웹 서비스를 띄우는 Deployment와 달리, 잡은 특정 작업을 완수하고 스스로 종료되는 특성을 가져요. 하지만 이 ‘종료’라는 특성 때문에 관리가 까다로워지기도 하죠. 작업이 끝난 뒤에 리소스를 어떻게 남길지, 실패했을 때 몇 번이나 다시 시도할지, 그리고 무엇보다 작업의 흔적을 어떻게 추적할지에 대한 전략이 없으면 운영 환경은 금방 혼란에 빠지게 돼요.

대규모 트래픽을 처리하는 환경에서는 배치 작업 하나가 전체 시스템의 안정성을 좌우해요. 배치 작업이 리소스를 독점하거나, 반대로 실패한 작업이 좀비처럼 남아 리소스를 낭비하는 일은 절대 있어서는 안 되는 일이죠. 이번 실습에서는 단순한 개념 설명을 넘어, 실무에서 바로 쓸 수 있는 수준의 잡 실전 예제를 통해 배치 작업의 생명 주기를 완벽하게 통제하는 법을 배워볼 거예요.

이 글을 끝까지 읽고 나면 다음과 같은 능력을 갖추게 돼요.

  • 실무에서 사용하는 수준의 잡 매니페스트를 직접 작성할 수 있어요.
  • 작업의 성공과 실패를 판단하는 명확한 기준을 세울 수 있어요.
  • 문제가 발생했을 때 로그를 추적하고 원인을 파악하는 절차를 익혀요.
  • 클러스터 리소스를 깨끗하게 유지하며 자동화된 정리 전략을 세울 수 있어요.

실습 전 반드시 체크해야 할 준비물과 개념

본격적으로 잡 실습에 들어가기 전에, 현재 여러분의 환경이 준비되었는지 확인해야 해요. 잡은 독립적인 실행 단위이기 때문에, 이를 실행할 수 있는 인프라와 제어 도구가 갖춰져 있어야 원활한 진행이 가능해요.

필수 준비 사항

가장 먼저 준비해야 할 것은 당연히 쿠버네티스 클러스터예요. 운영 환경이라면 검증된 클러스터가 있겠지만, 개인적인 학습이나 테스트 목적이라면 MinikubeKind를 활용해 로컬 환경을 구성하는 것을 추천해요. 또한, 클러스터를 조작할 수 있는 kubectl 명령줄 도구가 설치되어 있어야 하며, 실행할 컨테이너 이미지가 필요해요. 이번 예제에서는 별도의 이미지 없이도 테스트할 수 있도록 널리 쓰이는 알파인 리눅스(Alpine Linux) 기반의 이미지를 활용할게요.

워크로드 유형 비교하기

잡을 배우기 전, 우리가 흔히 사용하는 다른 컨트롤러와 무엇이 다른지 명확히 구분하는 것이 중요해요. 아래 표를 통해 상황에 맞는 적절한 워크로드 선택 기준을 확인해 보세요.

워크로드 유형 주요 목적 종료 방식 권장 사용 사례
Deployment 서비스 상시 유지 영구적 실행 웹 서버, API 서버
Job 일회성 작업 완수 성공 시 종료 데이터 백업, 배치 처리
CronJob 정기적 스케줄 작업 주기적 재시작 매일 자정 리포트 생성
💡 알아두기
잡(Job)은 Pod가 성공적으로 종료될 때까지 실행을 보장해요. 만약 Pod가 에러를 내며 종료되면 설정된 횟수만큼 재시도(Retry)를 수행하며, 이 과정에서 restartPolicy 설정을 정확히 이해하는 것이 매우 중요해요.

실무형 잡(Job) 배포 및 동작 검증 5단계

이제 본격적인 쿠버네티스 실습 예제를 시작해 볼게요. 이번 시나리오는 ‘특정 디렉토리에 파일을 생성하고, 10초간 대기한 뒤 성공 메시지를 출력하는 배치 작업’이에요. 이 과정을 통해 잡의 생성부터 소멸까지 모든 흐름을 직접 경험해 보게 될 거예요.

STEP 1. 잡 매니페스트 작성하기

먼저 작업을 정의할 YAML 파일을 만들어야 해요. 잡은 일반적인 Pod와 달리 backoffLimitactiveDeadlineSeconds 같은 중요한 옵션들을 가질 수 있어요. 아래 내용을 `my-job.yaml`이라는 이름으로 저장해 주세요.

apiVersion: batch/v1
kind: Job
metadata:
  name: batch-worker-job
spec:
  backoffLimit: 4
  template:
    spec:
      containers:
      - name: worker
        image: alpine:latest
        command: ["/bin/sh", "-c", "echo '작업 시작...'; sleep 10; echo '작업 완료!';"]
      restartPolicy: OnFailure

여기서 주목해야 할 설정이 있어요. backoffLimit: 4는 작업이 실패했을 때 최대 4번까지 다시 시도하겠다는 뜻이에요. 만약 4번을 모두 실패하면 잡은 최종적으로 실패 상태가 돼요. 또한, restartPolicy: OnFailure는 컨테이너가 에러로 종료되었을 때만 다시 시작하도록 설정하는 것이 배치 작업의 정석이에요. 만약 성공했을 때 다시 시작하고 싶다면 이 설정을 절대 사용하면 안 돼요.

STEP 2. 클러스터에 배포하고 상태 확인하기

파일 작성이 끝났다면 이제 클러스터에 명령을 내릴 차례예요. 터미널에서 다음 명령어를 입력해 보세요.

kubectl apply -f my-job.yaml

명령어를 입력하면 API 서버가 요청을 수락하고, 잡 컨트롤러가 이를 인지하여 Pod를 생성하기 시작해요. 배포가 잘 되었는지 확인하려면 다음 명령어를 사용하세요.

kubectl get jobs

명령 결과에서 `COMPLETIONS` 항목을 확인해 보세요. `0/1`로 표시된다면 아직 작업이 진행 중이라는 뜻이고, `1/1`로 바뀌었다면 작업이 성공적으로 마무리된 상태예요. 이때 Pod의 상태도 함께 확인해 두는 것이 좋아요.

kubectl get pods

Pod의 상태가 Running에서 Completed로 바뀌는 과정을 지켜보는 것이 이번 실습의 핵심이에요.

STEP 3. 동작 로그를 통한 결과 검증

작업이 완료되었다고 해서 안심하기엔 일러요. 실제로 작업이 의도한 대로 수행되었는지 내부 로그를 반드시 확인해야 해요. Pod가 성공적으로 종료되었다면 아래 명령어로 로그를 불러올 수 있어요.

# Pod 이름을 확인한 뒤 로그 출력
kubectl logs [POD_NAME]

로그에 우리가 작성한 ‘작업 시작…’‘작업 완료!’라는 문구가 정확히 찍혀 있다면 완벽하게 성공한 거예요. 만약 로그가 비어 있거나 에러 메시지가 보인다면, 매니페스트의 command 부분을 다시 점검해야 해요.

STEP 4. 실패 시나리오 테스트하기 (의도적 에러 유도)

실무에서는 성공보다 실패를 관리하는 것이 훨씬 중요해요. 이번에는 의도적으로 에러를 내는 잡을 만들어 볼까요? `error-job.yaml` 파일을 만들고, command 부분을 존재하지 않는 명령어로 바꿔 보세요.

command: ["/bin/sh", "-c", "echo '에러 발생 중...'; exit 1;"]
restartPolicy: OnFailure

이 파일을 배포하면 잡은 즉시 실패하지 않고, 설정해둔 backoffLimit인 4회까지 재시도를 반복할 거예요. kubectl describe job error-job 명령어를 입력해 보면, 이벤트 로그에 재시도가 몇 번 일어났는지, 왜 실패했는지에 대한 상세한 히스토리가 기록되어 있는 것을 확인할 수 있어요.

STEP 5. 리소스 자동 정리 설정하기

잡이 끝나고 나서 Pod가 계속 남아 있으면 클러스터에 불필요한 데이터가 쌓이게 돼요. 이를 방지하기 위해 ttlSecondsAfterFinished 설정을 활용하는 것이 좋아요. 이 설정은 작업이 완료된 후 지정된 초(second)가 지나면 잡과 관련된 모든 리소스를 자동으로 삭제해 줘요.

💡 알아두기
실무에서는 이 설정을 통해 매일 수백 개씩 생성되는 배치 작업의 잔해를 자동으로 청소해요. 보통 작업 완료 후 3600초(1시간) 정도 여유를 두고 삭제하도록 설정하는 것이 일반적이에요.

자주 하는 실수와 해결법 및 FAQ

잡을 운영하다 보면 예상치 못한 변수로 인해 작업이 꼬이는 경우가 빈번해요. SRE라면 당황하지 않고 아래 사례들을 통해 문제 해결 능력을 키워야 해요.

자주 하는 실수와 해결법

  • 실수: Pod가 종료되자마자 로그를 확인하려는데 Pod가 사라져 있음
    왜 발생하는가: 잡이 성공적으로 끝나면 기본 설정에 따라 Pod 리소스를 바로 정리하거나, 관리자가 수동으로 지웠기 때문이에요.
    ✅ 해결법: ttlSecondsAfterFinished 값을 충분히 크게 설정하거나, 작업이 끝난 직후 로그를 수집하는 별도의 로그링 시스템(EFK 스택 등)을 활용하세요.
  • 실수: restartPolicy를 Always로 설정함
    왜 발생하는가: Deployment와 습관이 같아서 잘못 설정하는 경우가 많아요.
    ✅ 해결법: 잡(Job)에서는 Always를 사용할 수 없어요. 반드시 OnFailureNever를 사용해야 해요.
  • 실수: backoffLimit을 너무 높게 설정함
    왜 발생하는가: 무조건 많이 시도하면 해결될 것이라고 착각하기 때문이에요.
    ✅ 해결법: 무한 재시도는 오히려 리소스 낭비와 비용 상승을 초래해요. 실패 원인이 코드 문제라면 재시도 횟수를 늘려도 해결되지 않으니, 적절한 횟수(보통 3~6회)를 정하는 것이 좋아요.
  • 실수: 작업 시간이 너무 길어지는데 제한을 두지 않음
    왜 발생하는가: 배치 작업이 무한 루프에 빠졌을 때를 대비하지 않았기 때문이에요.
    ✅ 해결법: activeDeadlineSeconds를 설정하여 작업이 특정 시간을 초과하면 강제로 종료되도록 제어하세요.
⚠️ 주의
잡이 실패했을 때 CrashLoopBackOff 상태가 지속된다면, 이는 단순한 일시적 에러가 아니라 설정이나 이미지 자체의 문제일 가능성이 매우 높아요. 즉시 로그를 확인하세요!

자주 묻는 질문

Q. 잡(Job)과 크론잡(CronJob)의 가장 큰 차이점은 무엇인가요?

잡은 특정 시점에 한 번 실행하고 끝나는 작업이고, 크론잡은 정해진 시간(예: 매일 새벽 2시)마다 자동으로 잡을 생성하여 실행하는 스케줄러 역할을 해요.

Q. 작업이 성공했는데 왜 Pod는 여전히 ‘Completed’ 상태로 남아 있나요?

잡이 성공했다는 것은 프로세스가 에러 없이 종료되었다는 뜻이에요. 쿠버네티스는 작업 결과를 확인하기 위해 Pod를 즉시 지우지 않고 ‘Completed’ 상태로 유지해요. 이를 정리하려면 앞서 설명한 TTL 설정을 사용해야 해요.

Q. 여러 개의 Pod가 동시에 실행되어야 하는 잡은 어떻게 만드나요?
매니페스트의 spec.parallelism 값을 조절하면 돼요. 예를를 들어 이 값을 2로 설정하면, 잡은 한 번에 두 개의 Pod를 동시에 띄워 작업을 분담하게 돼요.

Q. 작업이 실패했을 때 자동으로 알림을 받을 수 있나요?

쿠버네티스 자체 기능만으로는 어렵지만, Prometheus와 Alertmanager를 연동하여 잡의 실패 상태를 감시하거나, Kubernetes Event를 감지하여 Slack으로 메시지를 보내는 자동화 도구를 구성할 수 있어요.

성공적인 배치 운영을 위한 마무리

지금까지 잡 실전 예제를 통해 매니페스트 작성부터 검증, 그리고 트러블슈팅까지 전 과정을 살펴보았어요. 배치 작업은 눈에 잘 띄지 않지만, 시스템의 데이터 무결성을 지키는 핵심적인 요소라는 점을 꼭 기억해 주세요.

✅ 핵심 요약

  • restartPolicy는 반드시 OnFailure 또는 Never로 설정하세요.
  • backoffLimit을 통해 재시도 횟수를 관리하여 리소스 낭비를 막으세요.
  • activeDeadlineSeconds로 무한 루프 상황을 방지하세요.
  • ttlSecondsAfterFinished를 사용하여 클러스터를 청결하게 유지하세요.
  • 실패 시에는 반드시 kubectl describe와 로그를 통해 원인을 파악하세요.

오늘 배운 내용을 바탕으로 여러분의 클러스터에 직접 테스트용 잡을 배포해 보세요. 이론으로 읽을 때보다 직접 명령어를 입력하고 실패를 경험해 볼 때 진짜 실력이 늘어날 거예요. 실습 과정에서 예상치 못한 오류가 발생하거나 궁금한 점이 생기면 언제든 댓글로 질문을 남겨 주세요. 여러분의 고민이 다른 독자들에게도 큰 도움이 됩니다.

🚀 다음 단계로 나아가기:

  • 오늘 할 일: 작성한 YAML 파일로 클러스터에 잡 배포하기
  • 이번 주 할 일: 실패 시나리오를 만들어 backoffLimit 작동 확인하기
  • 실행 직전 할 일: 실무 환경에 적용하기 전 TTL 설정값 검토하기

함께 읽으면 좋은 글: 쿠버네티스 잡 기본 개념 정리, 쿠버네티스 클러스터 구축 입문 가이드

댓글 남기기