Kubernetes/05. 컨트롤러 종류 및 설명

[쿠버네티스] k8s 잡(Job) 컨트롤러란? 단일잡, 다중잡, 병렬잡

Jaden Park 2021. 6. 28. 12:01

들어가며: 잡소개

 

잡 컨트롤러의 레이블 셀렉터

잡 컨트롤러

  • 잡 컨트롤러 생성
  • 잡 컨트롤러 확인
  • 잡 컨트롤러 삭제

 

다중 잡 컨트롤러

  • 다중 잡 컨트롤러 생성
  • 다중 잡 컨트롤러 확인
  • 다중 잡 컨트롤러 삭제

 

병렬 다중 잡 컨트롤러

  • 병렬 다중 잡 컨트롤러 생성
  • 병렬 다중 잡 컨트롤러 확인
  • 병렬 다중 잡 컨트롤러 삭제

 

잡의 종료

  • 파드 백오프(backoff)
  • 유효 데드라인

 

 

들어가며: 잡 소개

잡(Job) 컨트롤러는 파드(컨테이너)의 애플리케이션(잡)의 실행이 완료/종료되는 것에 초점을 맞춘 컨트롤러입니다.

 

레플리케이션 컨트롤러, 레플리카셋, 데몬셋은 파드의 애플리케이션이 계속적으로 잘 동작하는 것을 초점으로 맞춘 것에 대비됩니다. 즉, 애플리케이션이 실행되고 실행이 완료되면 파드의 할 일이 끝난 것으로 간주하고 파드를 종료시킵니다. 

 

잡 컨트롤러는 임시(Ad-hoc) 작업 및 배치(Batch) 작업에 유용하게 사용될 수 있습니다. 

 

만약 애플리케이션이 실행되고 있는 중에 노드가 죽거나 파드의 실행이 완료되지 않았다면, 파드를 다시 스케줄링하여 재실행하게 구성할 수 있습니다.

 

잡 리소스에서는 설정 내용에 따라 여러 개의 처리를 병렬로 실행할 수 있습니다.

잡의 실행 수를 규정하는 파라미터에는 잡 정의와 관련된 .spec.completions 와 .spec.parallelism 가 있습니다.

 

 .spec.completions: 잡이 완료될 때까지 실행 종료해야 하는 파드의 수 (default: 1)

.spec.parallelism: 잡을 실행할 때 병렬로 실행되는 파드 수 (default: 1)

 

추가적으로 잡 재시도 횟수 설정에 대한 파라미터로 .spec.backoffLimit 가 있습니다.

.spec.backoffLimit: 비정상 종료한 경우 몇 번을 재실행할 지 설정하는 것 (default: 6)

 

아래 내용들은 이를 살펴볼 것 입니다.


잡 컨트롤러의 레이블 셀렉터

지금까지 확인했던 컨트롤러와 다르게, 잡/크론잡 컨트롤러는 일반적으로 파드 레이블 셀렉터(.spec.selector)를 직접 지정해 사용하지 않습니다. 종료되는 것을 원칙으로 하는 것인데 기본에 있던 다른 컨트롤러가 관리하고 있던 파드와 겹치게 된다면 충돌이 발생할 수 있습니다.

 

즉, 일반적으로 레이블 셀렉터를 사용하지 않는 이유는 셀렉터에 의해 관련 없는 파드가 선택되어 잡이 이미 실행되고 있다고 판단하거나, 잡이 이미 완료되었다고 판단해 잡을 삭제하는 경우 등 예상하지 못한 결과를 발생할 수 있기 때문입니다.

 

클러스터가 잡/크론잡 컨트롤러를 생성할 때 컨트롤러에 부여된 UID 기반의 레이블을 셀렉터로 사용합니다.

 

 


잡 컨트롤러

잡 컨트롤러 생성

 

잡 오브젝트의 API는 batch 그룹의 v1 버전을 사용합니다. 오브젝트의 종류는 job 입니다. 

 

잡 컨트롤러는 레플리케이션 컨트롤러, 레플리카셋, 데몬셋처럼 계속 동작하는 방식이 아니기 때문에 재시작 정책(restartPolicy)을 기본값이 Always가 아닌 Onfailure 또는 Never 로 명시적으로 선언해야 합니다. 즉, 잡 컨트롤러의 파드 오브젝트는 재실행되지 않습니다.

 

job.spec.template.spec.restartPolicy 재시작 정책:

  • Always: (기본값) 종료/실패 시 항상 재시작
  • Onfailure: 실패 시 재시작 (정상 종료 시 재시작하지 않음)
  • Never: 종료 또는 오류 시 절대 재시작 하지 않음

 

// myapp-job.yaml

apiVersion: batch/v1
kind: Job
metadata:
  name: myapp-job
spec:
  template:
    metadata:
      labels:
        app: myapp-job
    spec:
      restartPolicy: OnFailure
      containers:
      - name: myapp
        image: busybox
        command: ["sleep", "60"]

 

 

단일 파드를 실행하는 패턴으로 잡리소스 1개에 대해 파드가 하나 생성되며, 그 파드가 정상 종료되면 잡이 종료됩니다.

 

 

잡 컨트롤러 확인

잡 오브젝트를 생성한 뒤 확인해보면 1분이 지난 뒤 Completed 상태를 보고하는 것으로 확인할 수 있습니다.

 

 

잡 컨트롤러 삭제

완료된 잡 컨트롤러를 삭제합니다.

$ kubectl delete -f myapp-job.yaml

 

 


다중 잡 컨트롤러

다중 잡 컨트롤러 생성

// myapp-job-comp.yaml

---
apiVersion: batch/v1
kind: Job
metadata:
  name: myapp-job-comp
spec:
  completions: 3
  template:
    metadata:
      labels:
        app: myapp-job-comp
    spec:
      restartPolicy: OnFailure
      containers:
      - name: myapp
        image: busybox
        command: ["sleep", "60"]

 

job.spec.completions: 작업 완료 개수 지정

 

완료해야 할 파드 수를 설정하는 실행 패턴으로 job.spec.completions 필드를 정의해 잡이 한 번으로 완료되지 않고 작업을 여러 번 순차적으로 실행할 수 있습니다. 즉, 하나의 파드가 생성되어 잡이 실행되고 완료되면, 두 번째 파드가 생성되고 잡이 완료되고, 마지막으로 세 번째 파드가 생성되고 잡이 완료되어야 모든 잡이 완료된 것 입니다.

 

다중 잡 컨트롤러 확인

시간이 지남에 따라 순차적으로 3개의 잡이 실행하고 완료하는 것을 확인할 수 있습니다.

 

 

다중 잡 컨트롤러 삭제

$ kubectl delete -f myapp-job-comp.yaml
job.batch "myapp-job-comp" deleted

 

 


병렬 다중 잡 컨트롤러

병렬 다중 잡 컨트롤러 생성

앞서 살펴본 다중 잡 컨트롤러는 순서대로 직렬 형태로 실행되지만, 이를 병렬 형태로 동시에 실행할 수도 있습니다.

// myapp-job-para.yaml

---
apiVersion: batch/v1
kind: Job
metadata:
  name: myapp-job-para
spec:
  completions: 3
  parallelism: 3
  template:
    metadata:
      labels:
        app: myapp-job-para
    spec:
      restartPolicy: OnFailure
      containers:
      - name: myapp
        image: busybox
        command: ["sleep", "60"]

job.spec.parallelism: 동시에 실행할 잡의 개수 지정

 

작업 (다중) 큐형 실행 패턴으로 job.spec.parallelism 필드를 정의해 병렬로 동시에 실행할 잡의 개수를 지정할 수 있습니다. 총 3개의 잡을 실행해야 하며, 동시에 병렬로 3개의 잡을 실행한다는 의미 입니다. 작업 큐를 사용하는 경우는  큐, 데이터베이스, 파일 등 무엇이든 상관업싱 외부 처리 대상을 유지하고 그것을 순차적으로 처리합니다.

 

병렬 다중 잡 컨트롤러 확인

동시에 3개의 파드가 실행되고 완료된 것을 확인할 수 있습니다.

 

다시 잡 컨트롤러의 상태를 확인해보면 3개의 파드(잡)이 완료된 것을 확인할 수 있습니다.

 

 

병렬 다중 잡 컨트롤러 삭제

$ kubectl delete jobs.batch myapp-job-para 
job.batch "myapp-job-para" deleted

 


잡의 종료

잡은 파드의 실패나 컨테이너의 오류가 아닌 이상 애플리케이션이 종료되어야 잡이 종료됩니다. 정상적으로 잡을 종료하는 것이 아닌, 잡의 종료를 제어할 수 있는 방법이 존재합니다.

 

파드 백오프(backoff)

잡 컨트롤러는 잡의 오류가 있을 때 기본적으로 6번의 재시도 후 잡을 실패로 만듭니다.

 

.spec.backoffLimit: 잡을 실패로 만들기 전 재시도 횟수 (기본: 6)

 

 

유효 데드라인

잡의 애플리케이션이 종료되기 전 유효 데드라인을 설정해 파드를 종료할 수 있습니다. 데드라인에 의해 종료된 파드는 실패한 것으로 간주하고, 재시작하지 않습니다.

 

.spec.activeDeadlineSeconds: 잡이 시작된 후 작동할 유효한 시간

 

잡이 실행 중이고 유효 데드라인이 설정된 경우, 백오프가 지정된 값까지 도달하지 않더라도 유효 데드라인 시간이 우선순위가 높습니다.

 

다음은 유효 데드라인이 설정된 오브젝트입니다.

// myapp-job-atvdl.yaml

---
apiVersion: batch/v1
kind: Job
metadata:
  name: myapp-job-atvdl
spec:
  backoffLimit: 3
  activeDeadlineSeconds: 30
  template:
    metadata:
      labels:
        app: myapp-job-atvdl
    spec:
      restartPolicy: OnFailure
      containers:
      - name: myapp
        image: busybox
        command: ["sleep", "60"]

 

백오프는 3번으로 제한을 하였고, 유효 데드라인은 30초로 설정하였습니다.

 

 

약 30초 후 파드가 종료되고, 백오프 3번을 실행한 뒤 다시 재시작 되지 않을 것 입니다. 위 사진은 1번만 확인하였습니다.

 

 

잡 컨트롤러의 상세 정보를 확인해보면

$ kubectl describe job

파드의 상태는 Failed로 보고하고 있고, 컨트롤러의 이벤트는 DeadlineExceeded로 보고하고 있습니다.