Job

Job

Job은 하나 이상의 파드를 만들고, 지정된 수의 파드가 성공적으로 종료될 때까지 파드 실행을 계속 재시도해요. 파드가 성공적으로 완료되면 Job은 성공적인 완료 횟수를 추적해요. 지정된 수의 성공적인 완료 횟수에 도달하면 작업(즉, Job)이 완료돼요. Job을 삭제하면 그것이 만든 파드가 정리돼요. Job을 일시 중지(suspend)하면 다시 재개될 때까지 활성 파드가 삭제돼요.

간단한 경우는 하나의 파드를 완료까지 안정적으로 실행하기 위해 하나의 Job 객체를 만드는 것이에요. Job 객체는 첫 번째 파드가 실패하거나 삭제되면(예: 노드 하드웨어 장애나 노드 재부팅 때문에) 새 파드를 시작해요.

Job을 사용해 여러 파드를 병렬로 실행할 수도 있어요.

Job을(단일 작업이든 여러 병렬 작업이든) 스케줄에 따라 실행하려면 CronJob을 참조하세요.

출처: 문서

본문

예시 Job 실행하기

다음은 예시 Job 구성이에요. π를 2000자리까지 계산해 출력해요. 완료하는 데 약 10초가 걸려요.

apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  template:
    spec:
      containers:
      - name: pi
        image: perl:5.34.0
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never
  backoffLimit: 4

이 예시를 이 명령으로 실행할 수 있어요:

kubectl apply -f https://kubernetes.io/examples/controllers/job.yaml

출력은 다음과 비슷해요:

job.batch/pi created

kubectl로 Job의 상태를 확인해요:

kubectl describe job pi
kubectl get job pi -o yaml
Name:           pi
Namespace:      default
Selector:       batch.kubernetes.io/controller-uid=c9948307-e56d-4b5d-8302-ae2d7b7da67c
Labels:         batch.kubernetes.io/controller-uid=c9948307-e56d-4b5d-8302-ae2d7b7da67c
                batch.kubernetes.io/job-name=pi
                ...
Annotations:    batch.kubernetes.io/job-tracking: ""
Parallelism:    1
Completions:    1
Start Time:     Mon, 02 Dec 2019 15:20:11 +0200
Completed At:   Mon, 02 Dec 2019 15:21:16 +0200
Duration:       65s
Pods Statuses:  0 Running / 1 Succeeded / 0 Failed
Pod Template:
  Labels:  batch.kubernetes.io/controller-uid=c9948307-e56d-4b5d-8302-ae2d7b7da67c
           batch.kubernetes.io/job-name=pi
  Containers:
   pi:
    Image:      perl:5.34.0
    Port:       <none>
    Host Port:  <none>
    Command:
      perl
      -Mbignum=bpi
      -wle
      print bpi(2000)
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Events:
  Type    Reason            Age   From            Message
  ----    ------            ----  ----            -------
  Normal  SuccessfulCreate  21s   job-controller  Created pod: pi-xf9p4
  Normal  Completed         18s   job-controller  Job completed

Job의 완료된 파드를 보려면 kubectl get pods를 사용해요.

Job에 속한 모든 파드를 머신이 읽을 수 있는 형태로 나열하려면 다음과 같은 명령을 사용할 수 있어요:

pods=$(kubectl get pods --selector=batch.kubernetes.io/job-name=pi --output=jsonpath='{.items[*].metadata.name}')
echo $pods

출력은 다음과 비슷해요:

pi-5rwd7

여기서 셀렉터는 Job의 셀렉터와 같아요. --output=jsonpath 옵션은 반환된 목록의 각 파드에서 이름을 가진 표현식을 지정해요.

파드 중 하나의 표준 출력을 봐요:

kubectl logs $pods

Job의 로그를 보는 또 다른 방법:

kubectl logs jobs/pi

출력은 다음과 비슷해요(경우에 따라 π의 많은 자릿수):

3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316527120190914564856692346034861045432664821339360726024914127372458700660631558817488152092096282925409171536436789259036001133053054882046652138414695194151160943305727036575959195309218611738193261179310511854807446237996274956735188575272489122793818301194912983367336244065664308602139494639522473719070217986094370277053921717629317675238467481846766940513200056812714526356082778577134275778960917363717872146844090122495343014654958537105079227968925892354201995611212902196086403441815981362977477130996051870721134999999837297804995105973173281609631859502445945534690830264252230825334468503526193118817101000313783875288658753320838142061717766914730359825349042875546873115956286388235378759375195778185778053217122680661300192787661119590921642019893809525720106548586327886593615338182796823030195203530185296899577362259941389124972177528347913151557485724245415069595082953311686172785588907509838175463746493931925506040092770167113900984882401285836160356370766010471018194295559619894676783744944825537977472684710404753464620804668425906949129331367702898915210475216205696602405803815019351125338243003558764024749647326391419927260426992279678235478163600934172164121992458631503028618297455570674983850549458858692699569092721079750930295532116534498720275596023648066549911988183479775356636980742654252786255181841757467289097777279380008164706001614524919217321721477235014144197356854816136115735255213347574184946843852332390739414333454776241686251898356948556209921922218427255025425688767179049460165346680498862723279178608578438382796797668145410095388378636095068006422512520511739298489608412848862694560424196528502221066118630674427862203919494504712371378696095636437191728746776465757396241389086583264599581339047802...

Job spec 작성하기

다른 모든 쿠버네티스 구성과 마찬가지로 Job은 apiVersion, kind, metadata 필드가 필요해요.

제어 플레인이 Job에 대한 새 파드를 만들 때, Job의 .metadata.name은 그 파드들의 이름을 짓는 기준의 일부가 돼요. Job의 이름은 유효한 DNS 서브도메인 값이어야 하지만, 이것은 파드 호스트 이름에 예기치 않은 결과를 만들 수 있어요. 최상의 호환성을 위해 이름은 DNS 레이블의 더 제한적인 규칙을 따라야 해요. 이름이 DNS 서브도메인일 때도 이름은 63자를 넘을 수 없어요.

Job은 또한 .spec 섹션이 필요해요.

Job 레이블

Job 레이블은 job-namecontroller-uid에 대해 batch.kubernetes.io/ 접두사를 가질 거예요.

파드 템플릿

.spec.template.spec의 유일한 필수 필드예요.

.spec.template은 파드 템플릿(pod template)이에요. 파드와 정확히 같은 스키마를 가지지만, 중첩되어 있고 apiVersion이나 kind가 없다는 점이 달라요.

파드에 대한 필수 필드 외에도, Job의 파드 템플릿은 적절한 레이블(파드 셀렉터 참조)과 적절한 재시작 정책을 지정해야 해요.

RestartPolicyNever 또는 OnFailure와 같은 것만 허용돼요.

파드 셀렉터

.spec.selector 필드는 선택적이에요. 거의 모든 경우에 지정하지 않아야 해요. 자신의 파드 셀렉터 지정 섹션을 참조하세요.

Job의 병렬 실행

Job으로 실행하기에 적합한 작업 유형은 세 가지 주요 유형이 있어요:

  • 비병렬 Jobs: 보통 파드가 실패하지 않는 한 파드 하나만 시작돼요. 파드가 성공적으로 종료되는 즉시 Job이 완료돼요.
  • 고정 완료 횟수를 가진 병렬 Jobs: .spec.completions에 0이 아닌 양수 값을 지정해요. Job은 전체 작업을 나타내며 .spec.completions개의 성공적인 파드가 있을 때 완료돼요. .spec.completionMode="Indexed"를 사용할 때 각 파드는 0에서 .spec.completions-1 범위의 다른 인덱스를 받아요.
  • 작업 큐(work queue)를 가진 병렬 Jobs: .spec.completions를 지정하지 않고 .spec.parallelism으로 기본 설정돼요. 파드는 무엇을 작업해야 할지 결정하기 위해 서로 또는 외부 서비스와 조정해야 해요. 예를 들어 파드는 작업 큐에서 최대 N개의 항목을 가져올 수 있어요. 각 파드는 모든 동료가 완료되었는지, 따라서 전체 Job이 완료되었는지 독립적으로 판단할 수 있어요. Job의 어떤 파드가 성공으로 종료되면 새 파드는 생성되지 않아요. 적어도 하나의 파드가 성공으로 종료되고 모든 파드가 종료되면 Job은 성공으로 완료돼요. 어떤 파드가 성공으로 종료되면, 다른 파드는 이 작업을 위해 어떤 일도 하거나 어떤 출력도 쓰지 않아야 해요. 모두 종료되는 과정에 있어야 해요.

비병렬 Job의 경우 .spec.completions.spec.parallelism을 모두 설정하지 않고 둘 수 있어요. 둘 다 설정되지 않으면 둘 다 1로 기본 설정돼요.

고정 완료 횟수 Job의 경우 필요한 완료 횟수로 .spec.completions를 설정해야 해요. .spec.parallelism을 설정하거나 설정하지 않고 1로 기본 설정될 수 있어요.

작업 큐 Job의 경우 .spec.completions를 설정하지 않은 채 두고 .spec.parallelism을 음이 아닌 정수로 설정해야 해요.

다양한 유형의 Job을 활용하는 방법에 대한 자세한 내용은 job 패턴 섹션을 참조하세요.

병렬 처리 제어

요청된 병렬 처리(.spec.parallelism)는 음이 아닌 값으로 설정할 수 있어요. 지정되지 않으면 1로 기본 설정돼요. 0으로 지정하면 Job은 늘어날 때까지 효과적으로 일시 중지돼요.

실제 병렬 처리(어느 순간에든 실행되는 파드 수)는 다양한 이유로 요청된 병렬 처리보다 많거나 적을 수 있어요:

  • 고정 완료 횟수 Job의 경우 병렬로 실행되는 실제 파드 수는 남은 완료 횟수를 초과하지 않아요. 더 높은 .spec.parallelism 값은 효과적으로 무시돼요.
  • 작업 큐 Job의 경우 어떤 파드가 성공한 후 새 파드는 시작되지 않아요 — 그러나 남은 파드는 완료될 수 있어요.
  • Job 컨트롤러가 반응할 시간이 없으면.
  • Job 컨트롤러가 어떤 이유로든(ResourceQuota 부족, 권한 부족 등) 파드를 만들지 못하면 요청된 것보다 파드가 적을 수 있어요.
  • Job 컨트롤러는 같은 Job의 과도한 이전 파드 실패 때문에 새 파드 생성을 스로틀할 수 있어요.
  • 파드가 정상 종료될 때 중지하는 데 시간이 걸려요.

완료 모드 (Completion mode)

고정 완료 횟수를 가진 Job — 즉 .spec.completions가 null이 아닌 Job — 은 .spec.completionMode에 지정된 완료 모드를 가질 수 있어요:

  • NonIndexed(기본값): .spec.completions개의 성공적으로 완료된 파드가 있을 때 Job이 완료된 것으로 간주돼요. 즉 각 파드 완료는 서로 동형이에요. .spec.completions가 null인 Job은 암묵적으로 NonIndexed임을 유의하세요.
  • Indexed: Job의 파드는 0에서 .spec.completions-1까지의 연관된 완료 인덱스를 받아요. 이 인덱스는 네 가지 메커니즘을 통해 사용할 수 있어요: 파드 어노테이션 batch.kubernetes.io/job-completion-index. 파드 레이블 batch.kubernetes.io/job-completion-index(v1.28 이상; 이 레이블을 사용하려면 PodIndexLabel 기능 게이트를 활성화해야 하며 기본적으로 활성화됨). 파드 호스트 이름의 일부로, $(job-name)-$(index) 패턴을 따름. Indexed Job을 Service와 함께 사용하면 Job 내의 파드는 결정적 호스트 이름을 이용해 DNS를 통해 서로 주소를 지정할 수 있음. 컨테이너화된 작업에서 환경 변수 JOB_COMPLETION_INDEX로.

각 인덱스에 대해 성공적으로 완료된 파드가 하나 있으면 Job이 완료된 것으로 간주돼요. 이 모드 사용에 대한 자세한 내용은 정적 작업 할당이 있는 병렬 처리용 Indexed Job을 참조하세요.

워크로드 API와 통합하기

이 기능을 사용하려면 (또는) 클러스터 관리자가 클러스터의 모든 관련 컴포넌트에 대해 WorkloadWithJob 기능 게이트를 활성화해야 해요.

기능 게이트 활성화 또는 비활성화에 대한 자세한 내용은 기능 게이트 활성화/비활성화를 참조하세요.

WorkloadWithJob 기능 게이트가 활성화되면, Job 컨트롤러는 어떤 파드를 만들기 전에 Job의 .spec.scheduling 구성을 Workload 및 PodGroup 객체(scheduling.k8s.io/v1beta1)로 컴파일해요. 이를 통해 Job에 대한 명시적 스케줄링 의도, 예를 들어 방(scheduling, 모든 파드가 함께 스케줄링되거나 전혀 안 됨), 토폴로지 공동 배치, 중단 동작을 표현할 수 있어요.

.spec.scheduling을 생략하면 Job은 일반 Job의 표준 파드별 스케줄링 결과를 보존하는 Basic 스케줄링 정책으로 기본 설정돼요. 컨트롤러는 여전히 모든 적격 Job(Basic 포함)에 대해 Workload와 PodGroup을 만들므로, 정책과 관계없이 관찰 가능한 객체가 일관돼요.

스케줄링 구성

.spec.scheduling 필드는 다음 필드를 받아들여요:

  • schedulingPolicy: basic 또는 gang 중 정확히 하나를 지정해야 해요. gang을 사용하면 모든 파드가 어떤 것도 바인딩되기 전에 함께 스케줄링 가능해야 해요. 생략된 gang.minCount는 Job의 .spec.parallelism으로 기본 설정돼요. PodGroup 스케줄링 정책을 참조하세요.
  • schedulingConstraints: Job 파드에 대한 토폴로지 공동 배치 제약.
  • disruptionMode: 파드가 개별적으로(single) 또는 그룹으로(all) 중단되는지 여부. 중단과 우선순위를 참조하세요.
  • resourceClaims: Job 파드에 걸쳐 공유되는 동적 리소스 클레임.

모든 .spec.scheduling 필드는 Job이 생성된 후 불변이며, 탄력적으로 강을 확장하기 위해 변경할 수 있는 schedulingPolicy.gang.minCount를 제외해요.

강 스케줄링 (Gang scheduling)

다음 Job은 8개의 파드에 대해 강 스케줄링을 요청하며, 단일 존 내에 공동 배치되고 함께 중단돼요:

apiVersion: batch/v1
kind: Job
metadata:
  name: distributed-training
  namespace: training
spec:
  parallelism: 8
  completions: 8
  completionMode: Indexed
  scheduling:
    schedulingPolicy:
      gang: {} # minCount omitted -> defaults to parallelism (8)
    schedulingConstraints:
    - key: topology.kubernetes.io/zone
      level: topology.kubernetes.io/zone
    disruptionMode:
      all: {} # the entire group is disrupted together
  template:
    spec:
      restartPolicy: Never
      containers:
      - name: trainer
        image: training-image:latest
        resources:
          limits:
            nvidia.com/gpu: 1

Job 컨트롤러가 이 Job을 처리할 때:

  • 같은 네임스페이스에 Workload 객체를 만들고 .spec.scheduling에서 컴파일된 podGroupTemplate(여기서는 minCount: 8인 강 정책)을 포함해요.
  • 그 템플릿에서 PodGroup 객체를 만들어요. PodGroup은 런타임 스케줄링 단위이며 정책의 인라인 복사본을 담아요.
  • .spec.schedulingGroup.podGroupName이 PodGroup의 이름으로 설정된 파드를 만들어 각 파드를 그 스케줄링 그룹에 연결해요.

컨트롤러는 이러한 객체를 이름이 아닌 spec 참조(Workload.spec.controllerRefPodGroup.spec.workloadRef)로 발견해요. 컨트롤러가 만드는 객체는 Job을 가리키는 ownerReferences 항목을 가지므로, Job이 삭제될 때 가비지 컬렉션돼요.

기본 (Basic) 스케줄링

.spec.scheduling을 생략한 Job은 강 스케줄링의 암묵적 선택 해제로 작동하는 Basic으로 기본 설정돼요. 그 파드는 일반 Job처럼 스케줄링되는 반면, Basic Workload와 PodGroup은 여전히 만들어져요:

apiVersion: batch/v1
kind: Job
metadata:
  name: batch-processor
  namespace: batch
spec:
  parallelism: 10
  completions: 10
  # .spec.scheduling omitted -> defaults to Basic scheduling.
  template:
    spec:
      restartPolicy: Never
      containers:
      - name: processor
        image: processor-image:v1

상위 레벨 컨트롤러

독립 Job의 경우 Job 컨트롤러가 Workload와 PodGroup을 모두 소유해요. Job이 대신 Workload를 컴파일하는 상위 컨트롤러(예: JobSet)에 대한 ownerReference를 가질 때, Job 컨트롤러는 Workload 소유권을 그 상위로 위임해요. Job 컨트롤러가 여전히 런타임 PodGroup을 만드는지 여부는 상위가 위임하는 것에 따라 달라져요:

  • 상위가 Job에 scheduling.k8s.io/group-template-name 어노테이션을 설정하면, Job 컨트롤러는 명명된 PodGroupTemplate에 매핑된 PodGroup을 만들고 소유해요.
  • 그렇지 않으면 상위가 두 객체를 모두 소유하고 Job 컨트롤러는 어느 것도 만들지 않아요; 컨트롤러는 기존 객체를 발견하고 파드를 만들 때 사용해요.

Job의 파드 템플릿에 이미 .spec.template.spec.schedulingGroup이 설정되어 있으면, Job 컨트롤러는 어떤 객체도 만들지 않아 여러분(또는 상위 레벨 컨트롤러)이 Workload/PodGroup 수명 주기를 직접 관리하게 해요.

CronJob 동작

CronJob이 만든 Job은 독립적이에요; CronJob은 Workload 객체를 만들거나 관리하지 않아요. CronJob의 jobTemplate.spec.scheduling을 설정하면, Job 컨트롤러는 각 Job 인스턴스에 대해 그 Job의 .spec.scheduling에서 컴파일된(생략 시 Basic으로 기본 설정) 별도의 Workload와 PodGroup을 만들어요. 이러한 객체는 각 Job이 완료되거나 삭제될 때 가비지 컬렉션돼요.

알파 릴리스의 제한 사항

  • 각 Job은 정확히 하나의 PodGroup에 매핑돼요; Job의 모든 파드는 단일 스케줄링 정책을 공유해요.
  • schedulingPolicy.gang.minCount만 변경 가능하며, 다른 모든 .spec.scheduling 필드는 생성 후 불변이에요.
  • 일시 중지된 Job은 자신의 Workload와 PodGroup 객체를 유지해요; 일시 중지 시 삭제되거나 재개 시 재생성되지 않아요.

파드와 컨테이너 실패 처리

파드의 컨테이너는 여러 이유로 실패할 수 있어요. 예를 들어 그 안의 프로세스가 0이 아닌 종료 코드로 종료되었거나, 컨테이너가 메모리 한도를 초과해 종료되었을 수 있어요. 이런 일이 발생하고 .spec.template.spec.restartPolicy = "OnFailure"이면 파드는 노드에 남지만 컨테이너는 다시 실행돼요. 따라서 프로그램은 로컬에서 재시작되는 경우를 처리해야 하거나, .spec.template.spec.restartPolicy = "Never"를 지정해야 해요. restartPolicy에 대한 자세한 내용은 파드 수명 주기를 참조하세요.

전체 파드도 여러 이유로 실패할 수 있어요. 예를 들어 파드가 노드에서 쫓겨났거나(노드가 업그레이드, 재부팅, 삭제됨), 파드의 컨테이너가 실패하고 .spec.template.spec.restartPolicy = "Never"일 때. 파드가 실패하면 Job 컨트롤러가 새 파드를 시작해요. 이것은 애플리케이션이 새 파드에서 재시작되는 경우를 처리해야 함을 의미해요. 특히 이전 실행으로 인한 임시 파일, 잠금, 불완전한 출력 등을 처리해야 해요.

기본적으로 각 파드 실패는 .spec.backoffLimit 한도로 계산돼요(파드 백오프 실패 정책 참조). 그러나 Job의 파드 실패 정책을 설정해 파드 실패 처리를 사용자 지정할 수 있어요.

또한 .spec.backoffLimitPerIndex 필드를 설정해 Indexed Job의 각 인덱스에 대해 파드 실패를 독립적으로 계산하도록 선택할 수 있어요(인덱스별 백오프 한도 참조).

.spec.parallelism = 1.spec.completions = 1을 지정하고 .spec.template.spec.restartPolicy = "Never"를 지정하더라도 같은 프로그램이 때로 두 번 시작될 수 있다는 점을 유의하세요.

.spec.parallelism.spec.completions가 둘 다 1보다 크도록 지정하면 한 번에 여러 파드가 실행될 수 있어요. 따라서 파드는 동시성에도 관대해야 해요.

.spec.podFailurePolicy 필드를 지정하면, Job 컨트롤러는 종료 중인 파드(.metadata.deletionTimestamp 필드가 설정된 파드)가 종료될 때까지(.status.phaseFailed 또는 Succeeded일 때) 실패로 간주하지 않아요. 그러나 Job 컨트롤러는 종료가 명백해지는 즉시 교체 파드를 만들어요. 파드가 종료되면 Job 컨트롤러는 관련 Job에 대해 .backoffLimit.podFailurePolicy를 평가하며 이제 종료된 파드를 고려해요.

이 요구 사항 중 하나라도 충족되지 않으면, Job 컨트롤러는 종료 중인 파드를 즉각적인 실패로 계산해요. 파드가 나중에 phase: "Succeeded"로 종료되더라도 마찬가지예요.

파드 백오프 실패 정책

구성의 논리적 오류 때문에 일정 횟수의 재시도 후 Job을 실패시키고 싶은 상황이 있어요. 그렇게 하려면 .spec.backoffLimit을 설정해 Job을 실패로 간주하기 전의 재시도 횟수를 지정해요.

.spec.backoffLimit은 인덱스별 백오프 한도(Indexed Job만)가 지정되지 않으면 기본적으로 6으로 설정돼요. .spec.backoffLimitPerIndex가 지정되면 .spec.backoffLimit은 기본적으로 2147483647(MaxInt32)이 돼요.

Job과 연관된 실패한 파드는 Job 컨트롤러가 지수 백오프 지연(10s, 20s, 40s ...)으로 재생성하며 최대 6분으로 제한돼요.

재시도 횟수는 두 가지 방식으로 계산돼요:

  • .status.phase = "Failed"인 파드 수.
  • restartPolicy = "OnFailure"를 사용할 때 .status.phase가 Pending 또는 Running인 파드의 모든 컨테이너에서의 재시도 수.

두 계산 중 하나가 .spec.backoffLimit에 도달하면 Job이 실패한 것으로 간주돼요.

인덱스별 백오프 한도 (Backoff limit per index)

이것은 쿠버네티스의 안정적(stable) 기능이며 v1.33 버전부터 그렇게 되어 있어요. v1.28 릴리스에서 처음 사용 가능해졌어요. 더 이상 이 기능이나 동작을 비활성화하거나 선택 해제할 수 없어요(잠겨 있음); 관련 기능 게이트 JobBackoffLimitPerIndex에 값을 명시적으로 설정하면 쿠버네티스는 그것을 무시하지만 오류를 보고하지 않아요.

인덱스 Job을 실행할 때 각 인덱스에 대해 파드 실패에 대한 재시도를 독립적으로 처리하도록 선택할 수 있어요. 그러려면 .spec.backoffLimitPerIndex를 설정해 인덱스당 최대 파드 실패 수를 지정해요.

인덱스에 대한 인덱스별 백오프 한도가 초과되면 쿠버네티스는 그 인덱스를 실패한 것으로 간주하고 .status.failedIndexes 필드에 추가해요. 성공적인 파드가 있는 성공한 인덱스는 backoffLimitPerIndex 필드를 설정했는지와 관계없이 .status.completedIndexes 필드에 기록돼요.

실패한 인덱스가 다른 인덱스의 실행을 방해하지 않는다는 점을 유의하세요. 인덱스별 백오프 한도를 지정한 Job에 대해 모든 인덱스가 완료되면, 그 인덱스 중 적어도 하나가 실패했다면 Job 컨트롤러는 상태에서 Failed 조건을 설정해 전체 Job을 실패로 표시해요. 일부, 어쩌면 거의 대부분의 인덱스가 성공적으로 처리되었더라도 Job은 실패로 표시돼요.

.spec.maxFailedIndexes 필드를 설정해 실패로 표시된 최대 인덱스 수를 제한할 수도 있어요. 실패한 인덱스 수가 maxFailedIndexes 필드를 초과하면, Job 컨트롤러는 그 Job에 대해 실행 중인 모든 남은 파드의 종료를 트리거해요. 모든 파드가 종료되면 Job 컨트롤러는 Job 상태에 Failed 조건을 설정해 전체 Job을 실패로 표시해요.

다음은 backoffLimitPerIndex를 정의하는 Job의 예시 매니페스트예요:

apiVersion: batch/v1
kind: Job
metadata:
  name: job-backoff-limit-per-index-example
spec:
  completions: 10
  parallelism: 3
  completionMode: Indexed # required for the feature
  backoffLimitPerIndex: 1 # maximal number of failures per index
  maxFailedIndexes: 5 # maximal number of failed indexes before terminating the Job execution
  template:
    spec:
      restartPolicy: Never # required for the feature
      containers:
      - name: example
        image: python
        command:
        # The jobs fails as there is at least one failed index
        # (all even indexes fail in here), yet all indexes
        # are executed as maxFailedIndexes is not exceeded.
        - python3
        - -c
        - |
          import os, sys
          print("Hello world")
          if int(os.environ.get("JOB_COMPLETION_INDEX")) % 2 == 0:
            sys.exit(1)

위 예시에서 Job 컨트롤러는 각 인덱스마다 한 번의 재시작을 허용해요. 실패한 인덱스 총 수가 5를 초과하면 전체 Job이 종료돼요.

Job이 끝나면 Job 상태는 다음과 같아요:

kubectl get -o yaml job job-backoff-limit-per-index-example
  status:
    completedIndexes: 1,3,5,7,9
    failedIndexes: 0,2,4,6,8
    succeeded: 5 # 1 succeeded pod for each of 5 succeeded indexes
    failed: 10 # 2 failed pods (1 retry) for each of 5 failed indexes
    conditions:
    - message: Job has failed indexes
      reason: FailedIndexes
      status: "True"
      type: FailureTarget
    - message: Job has failed indexes
      reason: FailedIndexes
      status: "True"
      type: Failed

Job 컨트롤러는 Job 종료와 정리를 트리거하기 위해 FailureTarget Job 조건을 추가해요. 모든 Job 파드가 종료되면 Job 컨트롤러는 FailureTarget Job 조건과 같은 reason과 message 값으로 Failed 조건을 추가해요. 자세한 내용은 Job 파드 종료를 참조하세요.

또한 인덱스별 백오프를 파드 실패 정책과 함께 사용하고 싶을 수 있어요. 인덱스별 백오프를 사용할 때, 인덱스 내에서 불필요한 재시도를 피할 수 있게 해주는 새 FailIndex 동작이 있어요.

파드 실패 정책 (Pod failure policy)

이것은 쿠버네티스의 안정적(stable) 기능이며 1.31 릴리스부터 그렇게 되어 있어요. 더 이상 이 기능을 토글할 수 없어요(관련 기능 게이트가 제거됨).

.spec.podFailurePolicy 필드로 정의된 파드 실패 정책은 클러스터가 컨테이너 종료 코드와 파드 조건에 기반해 파드 실패를 처리할 수 있게 해줘요.

어떤 상황에서는 Job의 .spec.backoffLimit에 기반한 파드 백오프 실패 정책이 제공하는 제어보다 파드 실패를 처리할 때 더 나은 제어를 원할 수 있어요. 다음은 사용 사례의 몇 가지 예시예요:

  • 불필요한 파드 재시작을 피해 워크로드 실행 비용을 최적화하려면, 파드 중 하나가 소프트웨어 버그를 나타내는 종료 코드로 실패하는 즉시 Job을 종료할 수 있어요.
  • 중단이 있어도 Job이 끝나도록 보장하려면, 중단(선점, API 시작 퇴거, 테인트 기반 퇴거 같은)으로 인한 파드 실패를 무시해 재시도 .spec.backoffLimit 한도로 계산되지 않게 할 수 있어요.

.spec.podFailurePolicy 필드에 파드 실패 정책을 구성해 위의 사용 사례를 충족할 수 있어요. 이 정책은 컨테이너 종료 코드와 파드 조건에 기반해 파드 실패를 처리할 수 있어요.

다음은 podFailurePolicy를 정의하는 Job의 매니페스트예요:

apiVersion: batch/v1
kind: Job
metadata:
  name: job-pod-failure-policy-example
spec:
  completions: 12
  parallelism: 3
  template:
    spec:
      restartPolicy: Never
      containers:
      - name: main
        image: docker.io/library/bash:5
        command: ["bash"] # example command simulating a bug which triggers the FailJob action
        args:
        - -c
        - echo "Hello world!" && sleep 5 && exit 42
  backoffLimit: 6
  podFailurePolicy:
    rules:
    - action: FailJob
      onExitCodes:
        containerName: main     # optional
        operator: In            # one of: In, NotIn
        values: [42]
    - action: Ignore            # one of: Ignore, FailJob, Count
      onPodConditions:
      - type: DisruptionTarget  # indicates Pod disruption

위 예시에서 파드 실패 정책의 첫 번째 규칙은 main 컨테이너가 42 종료 코드로 실패하면 Job이 실패로 표시되어야 함을 지정해요. 다음은 main 컨테이너에 대한 규칙이에요:

  • 종료 코드 0은 컨테이너가 성공했음을 의미해요.
  • 종료 코드 42는 전체 Job이 실패했음을 의미해요.
  • 다른 종료 코드는 컨테이너가 실패했고 따라서 전체 파드가 실패했음을 의미해요. 재시작 총 수가 backoffLimit 아래이면 파드가 재생성돼요. backoffLimit에 도달하면 전체 Job이 실패해요.

참고:

DisruptionTarget 조건이 있는 실패한 파드에 대한 Ignore 동작을 지정하는 파드 실패 정책의 두 번째 규칙은 파드 중단이 재시도의 .spec.backoffLimit 한도로 계산되는 것을 제외해요.

참고:

다음은 API의 몇 가지 요구 사항과 의미예요:

  • Job에 .spec.podFailurePolicy 필드를 사용하려면 그 Job의 파드 템플릿을 .spec.restartPolicyNever로 설정되도록 정의해야 해요.
  • spec.podFailurePolicy.rules 아래에 지정하는 파드 실패 정책 규칙은 순서대로 평가돼요. 한 규칙이 파드 실패와 일치하면 나머지 규칙은 무시돼요. 어떤 규칙도 파드 실패와 일치하지 않으면 기본 처리가 적용돼요.
  • spec.podFailurePolicy.rules[*].onExitCodes.containerName에 이름을 지정해 규칙을 특정 컨테이너로 제한할 수 있어요. 지정하지 않으면 규칙이 모든 컨테이너에 적용돼요. 지정하면 파드 템플릿의 container 또는 initContainer 이름 중 하나와 일치해야 해요.
  • 파드 실패 정책이 일치할 때 취할 동작을 spec.podFailurePolicy.rules[*].action으로 지정할 수 있어요. 가능한 값은: FailJob: 파드의 job이 실패로 표시되고 모든 실행 중인 파드가 종료되어야 함을 나타내는 데 사용. Ignore: .spec.backoffLimit으로 향하는 카운터가 증가하지 않고 교체 파드가 생성되어야 함을 나타내는 데 사용. Count: 파드가 기본 방식으로 처리되어야 함을 나타내는 데 사용. .spec.backoffLimit으로 향하는 카운터가 증가해야 함. FailIndex: 실패한 파드의 인덱스 내에서 불필요한 재시도를 피하기 위해 인덱스별 백오프 한도와 함께 이 동작을 사용.

참고:

podFailurePolicy를 사용하고 Job이 FailJob 동작이 있는 규칙과 일치하는 파드 때문에 실패하면, Job 컨트롤러는 FailureTarget 조건을 추가해 Job 종료 과정을 트리거해요. 자세한 내용은 Job 종료와 정리를 참조하세요.

성공 정책 (Success policy)

Indexed Job을 만들 때 성공한 파드에 기반해 Job이 성공으로 선언될 수 있는 때를 .spec.successPolicy로 정의할 수 있어요.

기본적으로 Job은 성공한 파드 수가 .spec.completions와 같을 때 성공해요. Job이 성공으로 선언되는 것에 대한 추가 제어를 원할 수 있는 몇 가지 상황은 다음과 같아요:

  • 다른 파라미터로 시뮬레이션을 실행할 때 전체 Job이 성공하려면 모든 시뮬레이션이 성공할 필요가 없을 수 있어요.
  • 리더-워커 패턴을 따를 때 Job의 성공과 실패를 결정하는 것은 리더의 성공뿐이에요. 이에 대한 예시는 MPI와 PyTorch 같은 프레임워크예요.

.spec.successPolicy 필드에 성공 정책을 구성해 위의 사용 사례를 충족할 수 있어요. 이 정책은 성공한 파드에 기반해 Job 성공을 처리할 수 있어요. Job이 성공 정책을 충족하면 job 컨트롤러는 남아 있는 파드를 종료해요. 성공 정책은 규칙으로 정의돼요. 각 규칙은 다음 형식 중 하나를 취할 수 있어요:

  • succeededIndexes만 지정하면 succeededIndexes에 지정된 모든 인덱스가 성공하면 job 컨트롤러가 Job을 성공으로 표시해요. succeededIndexes는 0과 .spec.completions-1 사이의 간격 목록이어야 해요.
  • succeededCount만 지정하면 성공한 인덱스 수가 succeededCount에 도달하면 job 컨트롤러가 Job을 성공으로 표시해요.
  • succeededIndexessucceededCount를 모두 지정하면 succeededIndexes에 지정된 인덱스 부분 집합에서 성공한 인덱스 수가 succeededCount에 도달하면 job 컨트롤러가 Job을 성공으로 표시해요.

.spec.successPolicy.rules에 여러 규칙을 지정하면 job 컨트롤러는 규칙을 순서대로 평가한다는 점을 유의하세요. Job이 규칙을 충족하면 job 컨트롤러는 나머지 규칙을 무시해요.

다음은 successPolicy가 있는 Job의 매니페스트예요:

apiVersion: batch/v1
kind: Job
metadata:
  name: job-success
spec:
  parallelism: 10
  completions: 10
  completionMode: Indexed # Required for the success policy
  successPolicy:
    rules:
      - succeededIndexes: 0,2-3
        succeededCount: 1
  template:
    spec:
      containers:
      - name: main
        image: python
        command:
        # Provided that at least one of the Pods with 0, 2, and 3 indexes has succeeded,
        # the overall Job is a success.
        - python3
        - -c
        - |
          import os, sys
          if os.environ.get("JOB_COMPLETION_INDEX") == "2":
            sys.exit(0)
          else:
            sys.exit(1)
      restartPolicy: Never

위 예시에서 succeededIndexessucceededCount가 모두 지정되었어요. 따라서 지정된 인덱스 0, 2, 3 중 하나가 성공하면 job 컨트롤러는 Job을 성공으로 표시하고 남아 있는 파드를 종료해요. 성공 정책을 충족하는 Job은 SuccessPolicy reason을 가진 SuccessCriteriaMet 조건을 받아요. 남아 있는 파드의 제거가 발행된 후 Job은 Complete 조건을 받아요.

succeededIndexes는 하이픈으로 구분된 간격으로 표현된다는 점을 유의하세요. 숫자는 계열의 첫 번째와 마지막 요소로 표시되고 하이픈으로 구분돼요.

Job 종료와 정리

Job이 완료되면 더 이상 파드는 만들어지지 않지만, 파드는 보통 삭제되지도 않아요. 그것들을 남겨 두면 오류, 경고 또는 다른 진단 출력을 확인하기 위해 완료된 파드의 로그를 여전히 볼 수 있어요. job 객체도 완료 후에도 남아 있어 상태를 볼 수 있어요. 상태를 기록한 후 오래된 job을 삭제하는 것은 사용자의 몫이에요. kubectl로 job을 삭제하세요 (예: kubectl delete jobs/pi 또는 kubectl delete -f ./job.yaml). kubectl을 사용해 job을 삭제하면 그것이 만든 모든 파드도 삭제돼요.

기본적으로 Job은 파드가 실패하거나(restartPolicy=Never) 컨테이너가 오류로 종료되지 않는 한(restartPolicy=OnFailure) 중단 없이 실행되며, 그 시점에 Job은 위에서 설명한 .spec.backoffLimit으로 위임해요. .spec.backoffLimit에 도달하면 Job은 실패로 표시되고 실행 중인 파드가 종료돼요.

Job을 종료하는 또 다른 방법은 활성 데드라인(active deadline)을 설정하는 것이에요. Job의 .spec.activeDeadlineSeconds 필드를 몇 초로 설정해 이렇게 해요. activeDeadlineSeconds는 얼마나 많은 파드가 만들어지는지와 무관하게 Job의 기간에 적용돼요. Job이 activeDeadlineSeconds에 도달하면 실행 중인 모든 파드가 종료되고 Job 상태는 type: Failed with reason: DeadlineExceeded가 돼요.

Job의 .spec.activeDeadlineSeconds.spec.backoffLimit보다 우선한다는 점을 유의하세요. 따라서 하나 이상의 실패한 파드를 재시도하는 Job은 backoffLimit에 아직 도달하지 않았더라도 activeDeadlineSeconds에 지정된 시간 한도에 도달하면 추가 파드를 배포하지 않아요.

예시:

apiVersion: batch/v1
kind: Job
metadata:
  name: pi-with-timeout
spec:
  backoffLimit: 5
  activeDeadlineSeconds: 100
  template:
    spec:
      containers:
      - name: pi
        image: perl:5.34.0
        command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never

Job spec과 Job 내의 파드 템플릿 spec 모두 activeDeadlineSeconds 필드를 가진다는 점을 유의하세요. 이 필드를 적절한 레벨에 설정해야 합니다.

restartPolicy는 Job 자체가 아니라 파드에 적용된다는 점을 명심하세요: Job 상태가 type: Failed가 되면 자동 Job 재시작은 없어요. 즉 .spec.activeDeadlineSeconds.spec.backoffLimit으로 활성화된 Job 종료 메커니즘은 수동 개입이 필요한 영구적인 Job 실패를 초래해요.

종료 Job 조건 (Terminal Job conditions)

Job에는 두 가지 가능한 종료 상태가 있고, 각각 해당 Job 조건이 있어요:

  • Succeeded: Job 조건 Complete
  • Failed: Job 조건 Failed

Job이 실패하는 이유:

  • 파드 실패 수가 Job 스펙의 지정된 .spec.backoffLimit을 초과했을 때. 자세한 내용은 파드 백오프 실패 정책을 참조하세요.
  • Job 런타임이 지정된 .spec.activeDeadlineSeconds을 초과했을 때.
  • .spec.backoffLimitPerIndex를 사용한 Indexed Job에 실패한 인덱스가 있을 때. 자세한 내용은 인덱스별 백오프 한도를 참조하세요.
  • Job의 실패한 인덱스 수가 지정된 spec.maxFailedIndexes을 초과했을 때. 자세한 내용은 인덱스별 백오프 한도를 참조하세요.
  • 실패한 파드가 FailJob 동작이 있는 .spec.podFailurePolicy의 규칙과 일치할 때. 파드 실패 정책 규칙이 실패 평가에 어떻게 영향을 미칠 수 있는지에 대한 자세한 내용은 파드 실패 정책을 참조하세요.

Job이 성공하는 이유:

  • 성공한 파드 수가 지정된 .spec.completions에 도달했을 때.
  • .spec.successPolicy에 지정된 기준이 충족되었을 때. 자세한 내용은 성공 정책을 참조하세요.

쿠버네티스 v1.31 이상에서 Job 컨트롤러는 모든 Job 파드가 종료될 때까지 종료 조건인 Failed 또는 Complete의 추가를 지연해요.

쿠버네티스 v1.30 이하에서는 Job 컨트롤러가 Job 종료 과정이 트리거되고 모든 파드 파이널라이저가 제거되는 즉시 Complete 또는 Failed Job 종료 조건을 추가했어요. 그러나 일부 파드는 종료 조건이 추가된 순간에도 여전히 실행되거나 종료 중일 수 있었어요.

쿠버네티스 v1.31 이상에서 컨트롤러는 모든 파드가 종료된 후에만 Job 종료 조건을 추가해요. JobManagedByJobPodReplacementPolicy(둘 다 기본적으로 활성화) 기능 게이트를 사용해 이 동작을 제어할 수 있어요.

Job 파드 종료

Job 컨트롤러는 Job이 성공 또는 실패 기준을 충족한 후 파드 종료를 트리거하기 위해 FailureTarget 조건이나 SuccessCriteriaMet 조건을 Job에 추가해요.

terminationGracePeriodSeconds 같은 요인은 Job 컨트롤러가 FailureTarget 조건이나 SuccessCriteriaMet 조건을 추가한 순간부터 모든 Job 파드가 종료되고 Job 컨트롤러가 종료 조건(Failed 또는 Complete)을 추가하는 순간까지의 시간을 늘릴 수 있어요.

컨트롤러가 종료 조건을 추가할 때까지 기다리지 않고 Job이 실패했는지 성공했는지 평가하기 위해 FailureTarget 또는 SuccessCriteriaMet 조건을 사용할 수 있어요.

예를 들어 실패한 Job을 대체하는 교체 Job을 언제 만들지 결정하고 싶을 수 있어요. FailureTarget 조건이 나타날 때 실패한 Job을 교체하면 교체 Job이 더 빨리 실행되지만, 실패한 Job과 교체 Job의 파드가 동시에 실행되어 추가 컴퓨트 리소스를 사용할 수 있어요.

대안으로 클러스터의 리소스 용량이 제한적이라면 Job에 Failed 조건이 나타날 때까지 기다리기로 선택할 수 있는데, 이렇게 하면 모든 실패한 파드가 제거될 때까지 기다려 자원을 보존한다는 것을 보장하지만 교체 Job은 지연돼요.

완료된 Job 자동 정리

완료된 Job은 보통 시스템에서 더 이상 필요하지 않아요. 시스템에 남겨 두면 API 서버에 부담을 줘요. Job이 CronJob 같은 상위 레벨 컨트롤러에 의해 직접 관리되면, Job은 지정된 용량 기반 정리 정책에 따라 CronJob에 의해 정리될 수 있어요.

완료된 Job을 위한 TTL 메커니즘

완료된 Job(완료 또는 실패)을 자동으로 정리하는 또 다른 방법은 Job의 .spec.ttlSecondsAfterFinished 필드를 지정해 완료된 리소스용 TTL 컨트롤러가 제공하는 TTL 메커니즘을 사용하는 것이에요.

TTL 컨트롤러가 Job을 정리할 때, Job을 캐스케이딩 방식으로 삭제해요. 즉 파드 같은 의존 객체를 Job과 함께 삭제해요. Job이 삭제될 때 파이널라이저 같은 수명 주기 보장이 존중된다는 점을 유의하세요.

예를 들어:

apiVersion: batch/v1
kind: Job
metadata:
  name: pi-with-ttl
spec:
  ttlSecondsAfterFinished: 100
  template:
    spec:
      containers:
      - name: pi
        image: perl:5.34.0
        command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never

pi-with-ttl Job은 완료 100초 후 자동 삭제 대상이 돼요.

필드가 0으로 설정되면 Job은 완료 직후 자동 삭제 대상이 돼요. 필드가 설정되지 않으면 이 Job은 완료 후 TTL 컨트롤러에 의해 정리되지 않아요.

참고:

ttlSecondsAfterFinished 필드를 설정하는 것이 권장돼요. 관리되지 않는 Job(직접 만든, 그리고 CronJob 같은 다른 워크로드 API를 통해 간접적으로 만든 것이 아닌 Job)은 기본 삭제 정책이 orphanDependents이므로, 관리되지 않는 Job이 만든 파드가 그 Job이 완전히 삭제된 후에도 남아 있을 수 있기 때문이에요. 제어 플레인이 결국 삭제된 Job의 파드를 실패하거나 완료된 후에 가비지 컬렉션하지만, 때로는 그러한 남아 있는 파드가 클러스터 성능 저하를 일으키거나 최악의 경우 이 저하 때문에 클러스터가 오프라인 상태가 될 수 있어요.

LimitRanges와 ResourceQuotas를 사용해 특정 네임스페이스가 소비할 수 있는 리소스 양에 상한을 둘 수 있어요.

Job 패턴

Job 객체는 독립적이지만 관련된 작업 항목 집합을 처리하는 데 사용될 수 있어요. 이것들은 보낼 이메일, 렌더링할 프레임, 트랜스코딩할 파일, 스캔할 NoSQL 데이터베이스의 키 범위 등일 수 있어요.

복잡한 시스템에는 여러 다른 작업 항목 집합이 있을 수 있어요. 여기서는 사용자가 함께 관리하려는 한 집합의 작업 항목 — 배치 작업(batch job) — 만 고려하고 있어요.

각각 장단점이 있는 여러 병렬 컴퓨테이션 패턴이 있어요. 트레이드오프는 다음과 같아요:

  • 작업 항목마다 하나의 Job 객체 대신 모든 작업 항목에 대해 하나의 Job 객체. 작업 항목당 하나의 Job은 많은 수의 Job 객체를 관리하기 위해 사용자와 시스템에 약간의 오버헤드를 만들어요. 모든 작업 항목에 대해 하나의 Job은 많은 수의 항목에 더 좋아요.
  • 생성되는 파드 수가 작업 항목 수와 같음 대신 각 파드가 여러 작업 항목을 처리. 파드 수가 작업 항목 수와 같을 때 파드는 일반적으로 기존 코드와 컨테이너에 대한 수정이 덜 필요해요. 각 파드가 여러 작업 항목을 처리하는 것은 많은 수의 항목에 더 좋아요.
  • 여러 접근 방식이 작업 큐를 사용해요. 이것은 큐 서비스 실행과 기존 프로그램이나 컨테이너가 작업 큐를 사용하도록 수정하는 것을 필요로 해요. 다른 접근 방식은 기존 컨테이너화된 애플리케이션에 적용하기 더 쉬워요.
  • Job이 헤드리스 Service와 연관되면 Job 내의 파드가 서로 통신해 컴퓨테이션에서 협력하도록 활성화할 수 있어요.

트레이드오프는 여기 요약되어 있고, 2열에서 4열은 위의 트레이드오프에 해당해요. 패턴 이름은 예시와 더 자세한 설명에 대한 링크이기도 해요.

패턴 단일 Job 객체 작업 항목보다 적은 파드? 앱 수정 없이 사용?
작업 항목당 파드가 있는 큐(Queue with Pod Per Work Item) 때때로
가변 파드 수가 있는 큐(Queue with Variable Pod Count)
정적 작업 할당이 있는 Indexed Job
파드 간 통신이 있는 Job 때때로 때때로
Job 템플릿 확장(Job Template Expansion)

.spec.completions로 completions를 지정하면 Job 컨트롤러가 만든 각 파드는 동일한 spec을 가져요. 이것은 작업의 모든 파드가 같은 명령줄과 같은 이미지, 같은 볼륨, 그리고 (거의) 같은 환경 변수를 가질 것임을 의미해요. 이러한 패턴은 파드가 다른 것들을 작업하도록 배열하는 다양한 방식이에요.

이 표는 각 패턴에 대한 .spec.parallelism.spec.completions의 필수 설정을 보여 줘요. 여기서 W는 작업 항목 수예요.

패턴 .spec.completions .spec.parallelism
작업 항목당 파드가 있는 큐 W any
가변 파드 수가 있는 큐 null any
정적 작업 할당이 있는 Indexed Job W any
파드 간 통신이 있는 Job W W
Job 템플릿 확장 1 should be 1

고급 사용법

Job 일시 중지 (Suspending a Job)

Job이 생성되면 Job 컨트롤러는 즉시 Job의 요구 사항을 충족하기 위해 파드 만들기를 시작하고 Job이 완료될 때까지 계속해요. 그러나 Job의 실행을 일시적으로 일시 중지하고 나중에 재개하고 싶을 수 있고, 일시 중지 상태로 Job을 시작해 사용자 지정 컨트롤러가 언제 시작할지 나중에 결정하게 할 수도 있어요.

Job을 일시 중지하려면 Job의 .spec.suspend 필드를 true로 업데이트할 수 있고; 나중에 다시 재개하고 싶으면 false로 업데이트해요. .spec.suspend가 true로 설정된 Job을 만들면 일시 중지 상태로 만들어져요.

쿠버네티스 1.35 이상에서 MutableSchedulingDirectivesForSuspendedJobs 기능 게이트가 활성화되면 .status.startTime 필드는 Job 일시 중지 시 지워져요.

Job이 일시 중지에서 재개되면 .status.startTime 필드는 현재 시간으로 재설정돼요. 이것은 .spec.activeDeadlineSeconds 타이머가 Job이 일시 중지되고 재개될 때 중지되고 재설정됨을 의미해요.

Job을 일시 중지하면 Completed 상태가 아닌 실행 중인 파드는 SIGTERM 신호로 종료돼요. 파드의 정상 종료 기간이 존중되며 파드는 이 기간 안에 이 신호를 처리해야 해요. 이것은 나중을 위해 진행 상황을 저장하거나 변경을 되돌리는 것을 포함할 수 있어요. 이렇게 종료된 파드는 Job의 completions 횟수로 계산되지 않아요.

일시 중지 상태의 Job 정의 예시는 다음과 같아요:

kubectl get job myjob -o yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: myjob
spec:
  suspend: true
  parallelism: 1
  completions: 5
  template:
    spec:
      ...

명령줄을 사용해 Job을 패치해 Job 일시 중지를 토글할 수도 있어요.

활성 Job 일시 중지하기:

kubectl patch job/myjob --type=strategic --patch '{"spec":{"suspend":true}}'

일시 중지된 Job 재개하기:

kubectl patch job/myjob --type=strategic --patch '{"spec":{"suspend":false}}'

Job의 상태를 사용해 Job이 일시 중지되었는지 또는 이전에 일시 중지되었는지 결정할 수 있어요:

더 알아보기 (Learn more)