Kubernetes 리소스 Job, CronJob에 대해 이해하고 실습해보기

Bakumando·2022년 5월 27일
1

Kubernetes

목록 보기
12/17
post-thumbnail

들어가기에 앞서...

  • 본 글은 쿠버네티스 시리즈 중의 하나로, kubernetes 실습을 위한 기본 환경 세팅이 이루어져 있지 않은 분은 시리즈 1편을 확인해주시길 바란다.
  • 쿠버네티스 실습 시리즈는 아래 학습 자료를 참고하고 있다.

0. 블로깅 목적

  • Job과 CronJob의 정의 및 기능에 대해 이해한다.
  • Job과 CronJob 실습을 통해 활용 방법을 이해한다.

1. Job과 CronJob의 정의 및 기능에 대해 이해한다.

1) Job?

  • Job은 지속적으로 실행되는 서비스가 아, 특정 동작을 수행하고 종료하는 작업을 정의하기 위한 리소스이다.
  • 내부적으로 Pod를 생성하여 작업을 수행하게 되는데, Pod의 상태가 Running이 아닌 Completed가 되는 것이 최종상태이다.
  • 실패 시 재시작, 작업 수행 횟수 지정, 동시 실행 작업 수 지정 등의 세부 옵션도 제공한다.

2) CronJob?

  • CronJob은 주기적으로 특정 동작을 수행하고 종료하는 작업(배치 작업)을 정의하기 위한 리소스이다.
  • 리눅스 크론(Cron) 스케쥴링 방법을 그대로 사용한다.
  • 내부적으로 Job을 생성하여 작업을 수행한다. (그리고 Job은 내부적으로 Pod를 만든다.)
  • 주기적으로 데이터를 백업하거나 데이터 점검 및 알림 전송 등의 목적으로 사용한다.

2. Job 실습을 통해 활용 방법을 이해한다.

  • yml 파일을 4가지 준비한다.

job.yml

apiVersion: batch/v1
kind: Job
metadata:
  name: hello
spec:
  template:
    spec:
      restartPolicy: Never
      containers:
      - name: hello
        image: ubuntu:focal
        command: ["sh", "-c", "echo Hello World!"]
  • apiVersion에 batch 그룹으로 들어간다는 게 특징이다.
  • Deployment와 마찬가지로 내부적으로 Pod를 감싸고 있기 때문에, template이라는 키워드를 사용한다.
    • Deployment에는 selector 및 labels를 매칭하는 영역이 필수인데, 이 Job 메니페스트 파일엔 그런 영역이 필수는 아니다. Job 오브젝트가 생성될 때 Job 컨트롤러가, labels selector와 template(Pod)의 labels를 임의로 생성해서 넣어주기 때문이다.
    • 다만 특수한 목적으로, 직접 커스텀하게 selector 및 labels를 설정하고 싶다면 기재해줘도 된다.
  • Job을 명세할 때 주의할 점은 restartPolicy를 반드시 설정해줘야 한다는 것이다. restartPolicy에는 Always, Never, OnFailure가 있다. Job만들 때는 이 중에 Always 옵션은 사용을 안하는 것이 적절하다.
  • command로 Hello World!라는 문자열을 출력하도록 지정하였다.

job-parallelism.yml

apiVersion: batch/v1
kind: Job
metadata:
  name: hello
spec:
  completions: 10
  parallelism: 2
  template:
    spec:
      restartPolicy: Never
      containers:
      - name: hello
        image: ubuntu:focal
        command: ["sh", "-c", "sleep 2; echo Hello World!"]
  • job.yml과 달리 competions와 parallelism 옵션이 추가되어 있다.
  • competions 옵션은 Job을 몇 번 성공시킬 것인지, parallelism은 최대 동시 실행 횟수를 지정하는 것이다.
  • 그리고 결과를 제대로 보기 위해서 sleep 2를 넣어 2초간 기다리게 한다.

job-deadline.yml

apiVersion: batch/v1
kind: Job
metadata:
  name: hello
spec:
  activeDeadlineSeconds: 3
  template:
    spec:
      restartPolicy: Never
      containers:
      - name: hello
        image: ubuntu:focal
        command: ["sh", "-c", "sleep 5; echo Hello World!"]
  • activeDeadlineSeconds 옵션을 넣는다. Job이 최대 실행될 수 있는 타임아웃 시간을 주는 것이다.
  • 즉 위 파일을 해석해보면, hello라는 Job이 Pod를 생성할 때 3초를 넘어가면 실패로 간주하겠다는 것이다.
  • 실패 결과를 보기 위해 5초 슬립을 주었다.

cronjob.yml

apiVersion: batch/v1
kind: CronJob
metadata:
  name: hello-every-minute
spec:
  schedule: "*/1 * * * *"
  successfulJobsHistoryLimit: 5
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: Never
          containers:
          - name: hello
            image: ubuntu:focal
            command: ["sh", "-c", "echo Hello $(date)!"]
  • Kind는 당연히 CronJob이다.
  • jobTemplate이 template을 감싸고 있음을 알 수 있다. CronJob은 바로 Pod를 감쌀 수 없다는 것이다. 즉, CronJob은 Job을 감싸야하고 Job이 Pod를 감싸는 형태여야한다.
    • Deployment가 ReplicasSet을 wrapping하고 ReplicaSet이 Pod를 wrapping하는 것처럼, CronJob이 Job을 wrapping하고 Job이 Pod를 wrapping하는 방식을 비슷한 원리로 볼 수 있다.
  • schedule은 cron 표현식이 들어가게 된다. "/1 * * *" 는 매 1분마다 CronJob을 실행시키라는 의미이다.
  • successfulJobsHistoryLimit 옵션도 주었는데, 성공한 Job 기록을 최대 5개 남기라는 의미이다.

1번째 실습을 진행해보자.

  • kubectl apply -f job.yml
    • job.yml을 apply 한다.
  • watch kubectl get pod
    • 새로운 터미널을 열고 watch 모드를 실행하여 Pod를 관찰한다.
    • Running에서 바로 Completed로 바뀌었다.

  • kubectl get job
    • hello 라는 Job을 확인할 수 있다.

  • kubectl describe job hello
    • 좀 더 자세한 내역을 볼 수 있다.
    • Pod Statuses에 1 Succeeded 라는 결과를 볼 수 있다.
    • 무엇보다 기본적인 Selector와 Labels가 임의로 설정되었다는 것도 확인할 수 있다. 그리고 아래에 보면 Pod Template에도 Labels가 설정된 것을 확인할 수 있다.

  • kubectl delete -f job.yml 하고 마무리 한다.

2번째 실습을 진행해보자.

  • kubectl apply -f job-parallelism.yml
    • 적용을 하면 아래와 같은 과정이 진행된다.
    • 2개씩 수행할 수 있도록 설정했기에 2개씩 늘어난다.
    • ... (생략)
    • 최대 성공 Job 10개로 설정했기에 10개에서 멈춘다.

  • kubectl logs job/hello
    • Job의 로그를 확인할 수 있다.

  • kubectl delete -f job-parallelism.yml 하고 마무리 한다.

3번째 실습을 진행해보자.

  • kubectl apply -f job-deadline.yml
    • apply를 한다.
    • watch 모드에는 Terminating이 뜨다가 사라진다.

  • kubectl get job
    • COMPLETIONS가 0/1인걸 볼 수 있다.

  • kubectl describe job hello
    • Pod Statuses에 0 Succeeded 라는 결과를 볼 수 있다.
    • 가장 하단에 Events를 보면 어떤 과정이 일어났는지 알 수 있다.
      • SuccessfulCreate => SuccessfulDelete => DeadlineExceeded를 거치며 종료되는 걸 알 수 있다.
    • Deadline이 3초인데 슬립5설정으로 이를 넘어서며 성공하지 못하고 종료되는 것이다.

  • kubectl delete -f job-deadline.yml 하고 마무리 한다.

4번째 실습을 진행해보자.

  • kubectl apply -f cronjob.yml
    • cronjob 명세를 apply 한다.
    • ... (생략)
    • 이렇게 1분에 하나씩 추가되는 걸 알 수 있다.

    • 5개가 만들어졌어도 1분이 지나면 새로 하나를 만들면서 기존의 것을 하나 제거한다.

  • kubectl get cronjob
    • SCHEDULE에 표현식을 볼 수 있다.
    • LAST SCHEDULE을 통해 23초 전에 스케쥴링이 됐었다는 걸 확인할 수 있다.

  • kubectl get job
    • CronJob의 이름에 랜덤한 식별자가 추가되서 이름이 생성된 것을 볼 수 있다.
  • kubectl get pod
    • Pod는 거기에 또 다른 식별자가 붙어서 생성되는 걸 볼 수 있다.
profile
그렇게 바쿠만도는 개발에 퐁당 빠지고 말았답니다.

0개의 댓글