본문 바로가기
Framework and Tool/Kubernetes

Kubernetes - job and cron job

by ocwokocw 2022. 10. 21.

- 출처: Kubernetes in action

- 잡 리소스

레플리케이션 컨트롤러, 레플리카셋, 데몬셋은 지속적인 Task를 실행하므로 이런 종류로 생성한 리소스들의 파드들은 프로세스가 종료되면 다시 시작된다. 하지만 완료 가능한 Task 같이 프로세스 종료 후 재시작 하지 않는 유형도 고려해볼 수 있다.
 
쿠버네티스에서는 잡 리소스라는것으로 이런 작업 유형을 지원한다. 잡은 파드 내부의 컨테이너에서 실행중인 프로세스가 성공적으로 완료했다고 판단되면 컨테이너를 다시 시작하지 않는 파드를 실행핸다.
 
노드에 장애가 발생하면 잡이 관리하는 파드는 레플리카셋 파드와 동일하게 다른 노드로 스케줄링 된다. 만약 프로세스 자체적으로 장애가 있다면 설정에 따라 재시작할 것인지를 설정할 수 있다.
 
잡 리소스의 예로는 데이터를 어딘가에 저장해놓고 해당 데이터를 변환해서 어딘가로 전송하는 작업이 있을 수 있다.

- 잡 리소스 생성 및 실행

apiVersion: batch/v1
kind: Job
metadata:
  name: batch-job
spec:
  template:
    metadata:
      labels:
        app: batch-job
    spec:
      restartPolicy: OnFailure
      containers:
      - name: main
        image: luksa/batch-job
 
잡은 batch API그룹과 v1 API 버전에 속한다.
 
원래 파드 스펙에서 컨테이너가 실행중인 프로세스 종료시 쿠버네티스가 수행하는 작업은 restartPolicy라는 속성으로 지정할 수 있으며 Default 값은 Always 이다. 하지만 잡 파드는 무한정 실행되지 않으므로 Always로 지정할 수 없어서 Never나 OnFailure로 지정해야 한다. 따라서 컨테이너를 재시작하지 않는 엄밀한 이유는 파드를 잡 리소스 유형으로 생성했기 때문이 아니라 restartPolicy 속성이 Always가 아니라서이다.
 
 
 
예제의 이미지는 2분 후에 종료되는 프로세스를 호출한다. 그래서 처음 잡 리소스를 생성하자 마자 kubectl get all 명령어로 조회해보면 COMPLETIONS이 0/1 인것을 알 수 있다. 2분후에 kuberctl get jobs로 조회해보면 1/1로 COMPLETIONS 필드 값이 변경되는것을 확인할 수 있다.
 
 
 
보통 파드가 완료되면 조회시 보이지 않는데 job은 완료된 파드도 목록으로 보여준다. 덕분에 이미 완료된 잡 파드의 로그도 조회할 수 있다.
 
 

- 잡에서 여러 파드 인스턴스 실행

잡은 2개 이상의 파드 인스턴스를 병렬이나 순차적으로 실행할 수 있다. 잡 spec 에서 completions와 parallelism 속성을 지정하면 된다. 우선 순차적으로 여러 인스턴스를 실행하려면 completions에 실행 횟수를 지정한다. 
 
apiVersion: batch/v1
kind: Job
metadata:
  name: batch-job
spec:
  completions: 5
  template:
    metadata:
      labels:
        app: batch-job
    spec:
      restartPolicy: OnFailure
      containers:
      - name: main
        image: luksa/batch-job
 
k create 명령어를 통해 생성하고 일정 시간이 좀 지나서 확인해보면 순차적으로 여러 파드 인스턴스를 실행함을 확인할 수 있다. 
 
 
 
병렬 실행을 하려면 아래와 같이 completions와 더불어 parallelism도 기술해주면 된다.
 
apiVersion: batch/v1
kind: Job
metadata:
  name: batch-job
spec:
  completions: 5
  parallelism: 2
  template:
    metadata:
      labels:
        app: batch-job
    spec:
      restartPolicy: OnFailure
      containers:
      - name: main
        image: luksa/batch-job
 
잡도 레플리카셋과 동일하게 스케일링을 할 수 있었으며 책에는 할 수 있다고 되어있지만 이제는 사장되었다. (https://github.com/kubernetes/kubernetes/pull/60139) scale을 사용하지 말고 parallelism 수정을 통해 스케일링 동작을 수행하자.

- Timeout 설정

파드 spec의 activeDeadlineSeconds로 파드의 실행시간을 제한할 수 있다. 또한 job의 매니페스트에서 spec.backofflimit 필드로 실패로 표시되기 전 잡 재시도 횟수를 설정할 수 있으며 기본값은 6이다.
 
 

 

- 크론잡

잡 리소스를 실행하면 곧바로 파드가 생성된다. 하지만 보통 배치작업을 하는 경우 시간을 지정하거나 실행 간격을 조정한다. 쿠버네티스는 크론잡을 통해 크론 작업을 구성한다. 설정 시간에 크론잡 오브젝트에 설정한 잡 템플릿에 따라 잡 리소스를 설정할 수 있는 방식이다.
 
 

 

- 크론잡 생성

만약 매 15분마다 배치잡을 수행해야 한다고 가정해보자. 이럴 경우 크론잡은 아래와 같이 정의한다.
 
apiVersion: batch/v1
kind: CronJob
metadata:
  name: batch-job-every-fifteen-minutes
spec:
  schedule: "0,15,30,45 * * * *"
  jobTemplate:
    spec:
      template:
        metadata:
          labels:
            app: periodic-batch-job
        spec:
          restartPolicy: OnFailure
          containers:
          - name: main
            image: luksa/batch-job
 
잡 리소스와 다른점은 우선 schedule을 지정한다는것이다. 지정 형식은 cron 스케줄과 동일하다. 크론잡에 의해 잡 리소스에 생성될때에는 jobTemplate 에 따라 생성된다.

- 스케줄된 잡의 실행 방법

예정 시간에 크론잡 리소스가 잡 리소스를 생성하면 잡은 파드를 생성한다. 쿠버네티스에서는 잡이나 파드가 항상 제시간에 수행되지 않을 수도 있다고 생각한다. 만약 예정 시각을 벗어나면 안되는 요구사항이 있는 경우 startingDeadlineSeconds 필드로 데드라인을 지정할 수 있다.
 
크론잡은 항상 하나의 잡만 생성하긴 하지만 두개 잡이 동시에 생성되거나 생성되지 않을 수도 있다. 두개 잡이 동시에 생성되는 경우를 고려해서 잡은 멱등성(여러 번 실행해도 원치 않는 결과를 초래하지 않음)을 가져야 하며, 생성되지 않는 경우 다음번 잡 실행시 이전 실행에서 완료 했어야 하는 작업을 수행하는지 확인해야 한다.
 
 

댓글