잡에는 [`.spec` 섹션](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status)도 필요하다.
### 파드 템플릿
`.spec.template` 은 `.spec` 의 유일한 필수 필드이다.
`.spec.template` 은 [파드 템플릿](/ko/docs/concepts/workloads/pods/pod-overview/#파드-템플릿)이다. 이것은 `apiVersion` 또는 `kind` 가 없다는 것을 제외한다면 [파드](/ko/docs/concepts/workloads/pods/pod/)와 정확하게 같은 스키마를 가지고 있다.
추가로 파드의 필수 필드 외에도 잡의 파드 템플릿은 적절한
레이블([파드 셀렉터](#파드-셀렉터)를 본다)과 적절한 재시작 정책을 명시해야 한다.
`Never` 또는 `OnFailure` 와 같은 [`RestartPolicy`](/ko/docs/concepts/workloads/pods/pod-lifecycle/#재시작-정책)만 허용된다.
### 파드 셀렉터
`.spec.selector` 필드는 선택 사항이다. 대부분의 케이스에서 지정해서는 안된다.
[자신의 파드 셀렉터를 지정하기](#자신의-파드-셀렉터를-지정하기) 섹션을 참고한다.
### 병렬 잡
잡으로 실행하기에 적합한 작업 유형은 크게 세 가지가 있다.
1. 비-병렬(Non-parallel) 잡:
- 일반적으로, 파드가 실패하지 않은 한, 하나의 파드만 시작된다.
- 파드가 성공적으로 종료하자마자 즉시 잡이 완료된다.
1.*고정적(fixed)인 완료 횟수* 를 가진 병렬 잡:
-`.spec.completions` 에 0이 아닌 양수 값을 지정한다.
- 잡은 전체 작업을 나타내며 1에서 `.spec.completions` 까지의 범위의 각 값에 대해 한 개씩 성공한 파드가 있으면 완료된다.
- **아직 구현되지 않음:** 각 파드에게는 1부터 `.spec.completions` 까지의 범위 내의 서로 다른 인덱스가 전달된다.
1.*작업 큐(queue)* 가 있는 병렬 잡:
-`.spec.completions` 를 지정하지 않고, `.spec.parallelism` 를 기본으로 한다.
- 파드는 각자 또는 외부 서비스 간에 조정을 통해 각각의 작업을 결정해야 한다. 예를 들어 파드는 작업 큐에서 최대 N 개의 항목을 일괄로 가져올(fetch) 수 있다.
- 각 파드는 모든 피어들의 작업이 완료되었는지 여부를 독립적으로 판단할 수 있으며, 결과적으로 전체 잡이 완료되게 한다.
- 잡의 _모든_ 파드가 성공적으로 종료되면, 새로운 파드는 생성되지 않는다.
- 하나 이상의 파드가 성공적으로 종료되고, 모든 파드가 종료되면 잡은 성공적으로 완료된다.
- 성공적으로 종료된 파드가 하나라도 생긴 경우, 다른 파드들은 해당 작업을 지속하지 않아야 하며 어떠한 출력도 작성하면 안 된다. 파드들은 모두 종료되는 과정에 있어야 한다.
_비-병렬_ 잡은 `.spec.completions` 와 `.spec.parallelism` 모두를 설정하지 않은 채로 둘 수 있다. 이때 둘 다
설정하지 않은 경우 1이 기본으로 설정된다.
_고정적인 완료 횟수_ 잡은 `.spec.completions` 을 필요한 완료 횟수로 설정해야 한다.
`.spec.parallelism` 을 설정할 수 있고, 설정하지 않으면 1이 기본으로 설정된다.
_작업 큐_ 잡은 `.spec.completions` 를 설정하지 않은 상태로 두고, `.spec.parallelism` 을
음수가 아닌 정수로 설정해야 한다.
다른 유형의 잡을 사용하는 방법에 대한 더 자세한 정보는 [잡 패턴](#잡-패턴) 섹션을 본다.
#### 병렬 처리 제어하기
요청된 병렬 처리(`.spec.parallelism`)는 음수가 아닌 값으로 설정할 수 있다.
만약 지정되지 않은 경우에는 1이 기본이 된다.
만약 0으로 지정되면 병렬 처리가 증가할 때까지 사실상 일시 중지된다.
실제 병렬 처리(모든 인스턴스에서 실행되는 파드의 수)는 여러가지 이유로 요청된
병렬 처리보다 많거나 적을 수 있다.
- _고정적인 완료 횟수(fixed completion count)_ 잡의 경우, 병렬로 실행 중인 파드의 수는 남은 완료 수를
초과하지 않는다. `.spec.parallelism` 의 더 큰 값은 사실상 무시된다.
- _작업 큐_ 잡은 파드가 성공한 이후에 새로운 파드가 시작되지 않는다. 그러나 나머지 파드는 완료될 수 있다.
- 만약 잡 {{<glossary_tooltipterm_id="controller">}} 가 반응할 시간이 없는 경우
- 만약 잡 컨트롤러가 어떤 이유(`리소스 쿼터` 의 부족, 권한 부족 등)로든 파드 생성에 실패한 경우,
요청한 것보다 적은 수의 파드가 있을 수 있다.
- 잡 컨트롤러는 동일한 잡에서 과도하게 실패한 이전 파드들로 인해 새로운 파드의 생성을 조절할 수 있다.
- 파드가 정상적으로(gracefully) 종료되면, 중지하는데 시간이 소요된다.
## 파드와 컨테이너 장애 처리하기
파드내 컨테이너의 프로세스가 0이 아닌 종료 코드로 종료되었거나 컨테이너 메모리 제한을
초과해서 죽는 등의 여러가지 이유로 실패할 수 있다. 만약 이런 일이
발생하고 `.spec.template.spec.restartPolicy = "OnFailure"` 라면 파드는
노드에 그대로 유지되지만, 컨테이너는 다시 실행된다. 따라서 프로그램은 로컬에서 재시작될 때의
케이스를 다루거나 `.spec.template.spec.restartPolicy = "Never"` 로 지정해야 한다.
더 자세한 정보는 [파드 라이프사이클](/ko/docs/concepts/workloads/pods/pod-lifecycle/#상태-예제)의 `restartPolicy` 를 본다.
파드가 노드에서 내보내지는 경우(노드 업그레이드, 재부팅, 삭제 등) 또는 파드의 컨테이너가 실패
되고 `.spec.template.spec.restartPolicy = "Never"` 로 설정됨과 같은 여러 이유로
전체 파드가 실패할 수 있다. 파드가 실패하면 잡 컨트롤러는
새 파드를 시작한다. 이 의미는 애플리케이션이 새 파드에서 재시작될 때 이 케이스를 처리해야
한다는 점이다. 특히, 이전 실행으로 인한 임시파일, 잠금, 불완전한 출력 그리고 이와 유사한
것들을 처리해야 한다.
`.spec.parallelism = 1`, `.spec.completions = 1` 그리고
`.spec.template.spec.restartPolicy = "Never"` 를 지정하더라도 같은 프로그램을
두 번 시작하는 경우가 있다는 점을 참고한다.
`.spec.parallelism` 그리고 `.spec.completions` 를 모두 1보다 크게 지정한다면 한번에
여러개의 파드가 실행될 수 있다. 따라서 파드는 동시성에 대해서도 관대(tolerant)해야 한다.
### 파드 백오프(backoff) 실패 정책
구성 등의 논리적 오류로 인해 약간의 재시도 이후에
잡을 실패하게 만들려는 경우가 있다.
이렇게 하려면 `.spec.backoffLimit` 에 잡을 실패로 간주하기 이전에
재시도할 횟수를 설정한다. 백오프 제한은 기본적으로 6으로 설정되어 있다. 잡과
관련한 실패한 파드는 최대 6분안에서 기하급수적으로 증가하는 백-오프 지연 (10초, 20초, 40초 ...)
한도가 되어 잡 컨트롤러에 의해 재생성 된다. 잡의 다음 상태
확인 이전에 새로 실패한 파드가 표시되지 않으면 백 오프
카운트가 재설정 된다.
{{<note>}}
1.12 이전 버전의 쿠버네티스 버전에 대해 여전히 [#54870](https://github.com/kubernetes/kubernetes/issues/54870) 이슈가 있다.
{{</note>}}
{{<note>}}
만약 잡에 `restartPolicy = "OnFailure"` 가 있는 경우 잡 백오프 한계에
도달하면 잡을 실행 중인 컨테이너가 종료된다. 이로 인해 잡 실행 파일의 디버깅이
더 어려워질 수 있다. 디버깅하거나 로깅 시스템을 사용해서 실패한 작업의 결과를 실수로 손실되지 않도록
하려면 `restartPolicy = "Never"` 로 설정하는 것을 권장한다.
{{</note>}}
## 잡의 종료와 정리
잡이 완료되면 파드가 더 이상 생성되지도 않지만, 삭제되지도 않는다. 이를 유지하면
완료된 파드의 로그를 계속 보며 에러, 경고 또는 다른 기타 진단 출력을 확인할 수 있다.
잡 오브젝트는 완료된 후에도 상태를 볼 수 있도록 남아 있다. 상태를 확인한 후 이전 잡을 삭제하는 것은 사용자의 몫이다.
`kubectl` 로 잡을 삭제할 수 있다 (예: `kubectl delete jobs/pi` 또는 `kubectl delete -f ./job.yaml`). `kubectl` 을 사용해서 잡을 삭제하면 생성된 모든 파드도 함께 삭제된다.
기본적으로 파드의 실패(`restartPolicy=Never`) 또는 컨테이너가 오류(`restartPolicy=OnFailure`)로 종료되지 않는 한, 잡은 중단되지 않고 실행되고
이때 위에서 설명했던 `.spec.backoffLimit` 까지 연기된다. `.spec.backoffLimit` 에 도달하면 잡은 실패로 표기되고 실행 중인 모든 파드는 종료된다.
잡을 종료하는 또 다른 방법은 유효 데드라인을 설정하는 것이다.
잡의 `.spec.activeDeadlineSeconds` 필드를 초 단위로 설정하면 된다.
`activeDeadlineSeconds` 는 생성된 파드의 수에 관계 없이 잡의 기간에 적용된다.
잡이 `activeDeadlineSeconds` 에 도달하면, 실행 중인 모든 파드가 종료되고 잡의 상태는 `reason: DeadlineExceeded` 와 함께 `type: Failed` 가 된다.
잡의 `.spec.activeDeadlineSeconds` 는 `.spec.backoffLimit` 보다 우선한다는 점을 참고한다. 따라서 하나 이상 실패한 파드를 재시도하는 잡은 `backoffLimit` 에 도달하지 않은 경우에도 `activeDeadlineSeconds` 에 지정된 시간 제한에 도달하면 추가 파드를 배포하지 않는다.