✔️ CronJob
크론잡은 반복 일정에 따라 잡을 만든다.
하나의 크론잡 오브젝트는 크론탭 (크론 테이블) 파일의 한 줄과 같다. 크론잡은 잡을 크론 형식으로 쓰여진 주어진 일정에 따라 주기적으로 동작시킨다.
크론잡은 비교적 최근에 stable 되었다.
1.8 버전부터 ~ 1.20 버전까지 베타버전이었다가 1.21 버전부터 stable 되었다.
 vagrant@k8s-node1  ~  kubectl api-versions              
batch/v1
batch/v1beta1
api-versions를 보면 아직 v1, v1beta1이 존재한다.CronJob을 1.8 ~ 1.20 버전까지는 yaml 파일 작성시 v1beta1을 사용해야 했다.
1.20 버전은 아직 많이 사용하는 버전이므로 v1beta1을 사용해야 한다.
1.20 버전에서 v1 을 사용하면 오류가 난다.
 vagrant@k8s-node1  ~  kubectl explain cj                      
KIND:     CronJob
VERSION:  batch/v1
DESCRIPTION:
     CronJob represents the configuration of a single cron job.
FIELDS:
   apiVersion   <string>
     APIVersion defines the versioned schema of this representation of an
     object. Servers should convert recognized schemas to the latest internal
     value, and may reject unrecognized values. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
   kind <string>
     Kind is a string value representing the REST resource this object
     represents. Servers may infer this from the endpoint the client submits
     requests to. Cannot be updated. In CamelCase. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
   metadata     <Object>
     Standard object's metadata. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
   spec <Object>
     Specification of the desired behavior of a cron job, including the
     schedule. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
   status       <Object>
     Current status of a cron job. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
 vagrant@node1  ~/cont/job  kubectl explain cj --help       
 Options:
      --api-version='': Get different explanations for particular API version (API group/version)         
 vagrant@node1  ~/cont/job  kubectl explain cj --api-version=batch/v1beta1               
KIND:     CronJob
VERSION:  batch/v1beta1           
해당 오브젝트가 다른 버전의 API를 지원하는 경우 --api-version 옵션을 사용해 다른 버전의 필드를 볼 수 있다.
대표적인 예제가 autoscaling이다
 vagrant@k8s-node1  ~  kubectl api-versions | grep autoscaling       
autoscaling/v1
autoscaling/v2beta1
autoscaling/v2beta2
현재 v1을 쓰지만 최신의 기능을 사용하고 싶다면 v2beta1, v2beta2를 사용해야 한다.
 vagrant@node1  ~/cont/job  kubectl explain hpa                                          
KIND:     HorizontalPodAutoscaler
VERSION:  autoscaling/v1
기본적으로 stable버전이 사용 가능하면 explain을 실행했을 때 stable 버전만 나오게 된다.
 vagrant@node1  ~/cont/job  kubectl explain hpa --api-version=autoscaling/v2beta2             
KIND:     HorizontalPodAutoscaler
VERSION:  autoscaling/v2beta2
이런식으로 확인할 수 있다.
 vagrant@k8s-node1  ~  kubectl explain cj.spec                       
KIND:     CronJob
VERSION:  batch/v1
RESOURCE: spec <Object>
DESCRIPTION:
     Specification of the desired behavior of a cron job, including the
     schedule. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
     CronJobSpec describes how the job execution will look like and when it will
     actually run.
FIELDS:
   concurrencyPolicy    <string>
     Specifies how to treat concurrent executions of a Job. Valid values are: -
     "Allow" (default): allows CronJobs to run concurrently; - "Forbid": forbids
     concurrent runs, skipping next run if previous run hasn't finished yet; -
     "Replace": cancels currently running job and replaces it with a new one
   failedJobsHistoryLimit       <integer>
     The number of failed finished jobs to retain. Value must be non-negative
     integer. Defaults to 1.
   jobTemplate  <Object> -required-
     Specifies the job that will be created when executing a CronJob.
   schedule     <string> -required-
     The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron.
   startingDeadlineSeconds      <integer>
     Optional deadline in seconds for starting the job if it misses scheduled
     time for any reason. Missed jobs executions will be counted as failed ones.
   successfulJobsHistoryLimit   <integer>
     The number of successful finished jobs to retain. Value must be
     non-negative integer. Defaults to 3.
   suspend      <boolean>
     This flag tells the controller to suspend subsequent executions, it does
     not apply to already started executions. Defaults to false.
컨트롤러의 이벤트를 보면 suspend가 됐는지 볼 수 있다.
크론잡은 잡이지만 주기적으로 작동시키는 것이다. 리눅스의 크론탭과 유사하다.
크론탭의 경우 시스템에서 어플리케이션을 주기적으로 실행하는 용도라면,
크론잡은 잡을 주기적으로 실행하는 용도로 사용한다.
 vagrant@node1  ~/cont/job  kubectl explain cronjob.spec
FIELDS:
   jobTemplate  <Object> -required-
     Specifies the job that will be created when executing a CronJob.
   schedule     <string> -required-
     The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron.
cronjob.spec의 필수 FIELDS는 jobTemplate과 schedule이다.
vagrant@node1  ~/cont/job  kubectl explain cronjob.spec.schedule
KIND:     CronJob
VERSION:  batch/v1
FIELD:    schedule <string>
DESCRIPTION:
     The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron.
크론 포맷을 사용한다.
크론 스케줄 문법
# ┌───────────── 분 (0 - 59)
# │ ┌───────────── 시 (0 - 23)
# │ │ ┌───────────── 일 (1 - 31)
# │ │ │ ┌───────────── 월 (1 - 12)
# │ │ │ │ ┌───────────── 요일 (0 - 6) (일요일부터 토요일까지;
# │ │ │ │ │                                   특정 시스템에서는 7도 일요일)
# │ │ │ │ │
# │ │ │ │ │
# * * * * *
✔️ CronJob YAML 명세
이제 작성해보자mypi-cj.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: mypi-cj
spec:
  schedule: "* * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
            - name: mypi
              image: perl
              command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
          restartPolicy: OnFailure
매 분마다 실행하도록 작성한다.
Every 1.0s: kubectl get cj,pods                                                   node1: Thu May 19 05:32:44 2022
NAME                    SCHEDULE    SUSPEND   ACTIVE   LAST SCHEDULE   AGE
cronjob.batch/mypi-cj   * * * * *   False     0        44s             2m49s
NAME                            READY   STATUS      RESTARTS   AGE
pod/mypi-cj-27548970--1-zvxf7   0/1     Completed   0          2m44s
pod/mypi-cj-27548971--1-rn8wl   0/1     Completed   0          102s
pod/mypi-cj-27548972--1-q6w9w   0/1     Completed   0          44s
Every 1.0s: kubectl get cj,pods                                                   node1: Thu May 19 05:34:08 2022
NAME                    SCHEDULE    SUSPEND   ACTIVE   LAST SCHEDULE   AGE
cronjob.batch/mypi-cj   * * * * *   False     0        8s              4m13s
NAME                            READY   STATUS      RESTARTS   AGE
pod/mypi-cj-27548972--1-q6w9w   0/1     Completed   0          2m8s
pod/mypi-cj-27548973--1-bb2m4   0/1     Completed   0          68s 
pod/mypi-cj-27548974--1-jhm7f   0/1     Completed   0          8s                                                                
1분마다 실행을 하고 가장 오래된것이 지워진다.
기본적으로 4개의 Job만 가지고 있다.
✔️ CronJob YAML FIELDS
 vagrant@node1  ~  kubectl explain cj.spec
FIELDS:
   concurrencyPolicy    <string>
     Specifies how to treat concurrent executions of a Job. Valid values are: -
     "Allow" (default): allows CronJobs to run concurrently; - "Forbid": forbids
     concurrent runs, skipping next run if previous run hasn't finished yet; -
     "Replace": cancels currently running job and replaces it with a new one
   failedJobsHistoryLimit       <integer>
     The number of failed finished jobs to retain. Value must be non-negative
     integer. Defaults to 1.
   jobTemplate  <Object> -required-
     Specifies the job that will be created when executing a CronJob.
   schedule     <string> -required-
     The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron.
   startingDeadlineSeconds      <integer>
     Optional deadline in seconds for starting the job if it misses scheduled
     time for any reason. Missed jobs executions will be counted as failed ones.
   successfulJobsHistoryLimit   <integer>
     The number of successful finished jobs to retain. Value must be
     non-negative integer. Defaults to 3.
successfulJobsHistoryLimit - 성공한 작업의 history를 기본적으로 3개 기억한다.failedJobsHistoryLimit - 작업이 실행된 후 실패한 것을 1개만 기억한다.
이때 실행되고 있는 정보는 1개 이상이 될 수 있다.
concurrencyPolicy - 동시 정책 (default : allow)
시간 축에 따라서 스케줄링이 주기적으로 실행되는데 선행 작업이 끝나지 않았음에도 불구하고 작업을 실행한다.
그렇게되면 동시에 2개의 작업이 진행된다.
실행할 어플리케이션이 동시에 2개의 작업이 실행되어도 되면 상관없으나 대부분이 그렇지 않은 경우가 많다.
예를 들어 App이 주기적으로 데이터를 처리해야 할 때 두개의 스케줄러에 의해 동시에 같은 데이터를 작업하는 것이 괜찮은가 ?
그것은 App과 data의 성격에 따라 다른것이지 우리가 판별할 수 있는 것이 아니다.
데이터의 영역이 나눠져 있을 때는 상관없을 수 있겠지만 어플리케이션의 성격에 따라서 다를 수 있다.
default는 allow이며 forbid(금지) 시킬 수 있다.forbid 라면 하나가 이미 실행되고 있을 때는 실행 주기가 되더라도 실행하지 않는다.
이전의 작업이 끝나야만 주기가 되었을 때 실행한다.
replace는 실행이 되고 있을 때 주기가 오면 기존의 파드를 죽이고 새롭게 실행한다.
이런 옵션은 어플리케이션의 성격을 잘 파악하고 적용시켜야 한다.
테스트해보자
sleep-cj.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: sleep-cj
spec:
  schedule: "* * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
            - name: sleep
              image: ubuntu
              command: ["sleep", "80"]
          restartPolicy: OnFailure
  concurrencyPolicy: Forbid
Every 1.0s: kubectl get cj,po                                                     node1: Thu May 19 05:43:35 2022
NAME                     SCHEDULE    SUSPEND   ACTIVE   LAST SCHEDULE   AGE
cronjob.batch/sleep-cj   * * * * *   False     1        35s             73s
NAME                             READY   STATUS      RESTARTS   AGE
pod/sleep-cj-27548983--1-gh6cp   1/1     Running     0          35s
시간이 지난 후
Every 1.0s: kubectl get cj,po                                                     node1: Thu May 19 05:44:57 2022
NAME                     SCHEDULE    SUSPEND   ACTIVE   LAST SCHEDULE   AGE
cronjob.batch/sleep-cj   * * * * *   False     1        57s             2m35s
NAME                             READY   STATUS      RESTARTS   AGE
pod/sleep-cj-27548983--1-gh6cp   0/1     Completed   0          117s
pod/sleep-cj-27548984--1-jwrqg   1/1     Running     0          26s
forbid 옵션을 지정했고 종료되었기 때문에 실행될 수 있는것이다.
concurrencyPolicy: Replace 로 변경 후 실행해보자
Every 1.0s: kubectl get cj,pod                                                                        node1: Thu May 19 14:08:02 2022
NAME                     SCHEDULE    SUSPEND   ACTIVE   LAST SCHEDULE   AGE
cronjob.batch/sleep-cj   * * * * *   False     1        2s              4m2s
NAME                             READY   STATUS              RESTARTS   AGE
pod/sleep-cj-27549487--1-vhqvc   1/1     Terminating         0          62s
pod/sleep-cj-27549488--1-dkvhd   0/1     ContainerCreating   0          2s
60초가 되면 다음 스케줄링 시점이 되며 그때는 선행 작업이 지워지고 다음 작업으로 교체되어 실행된다.
크론잡은 기본적으로 일정이 누락이 100회가 되면 크론잡을 모두 중단시킨다.
앞서 Forbid 옵션을 지정했을 때 실행 주기임에도 불구하고 선행 작업이 있어 두번째 작업이 실행되지 못했다.
이것을 한번의 실패로 간주한다.
따라서 시스템에 문제가 발생해서 실패할 수도 있지만, forbid 상태에서도 실패가 발생할 수 있다.
이러한 실패 횟수가 100번이 되면 크론잡은 더 이상 작업하지 않는다.
- 동시에 작업해도 되는가?
 - 동시에 작업하면 절대 안되는가 ?
 - 선행 작업을 지우고 새로운 어플리케이션을 실행할 것인지 ?
어플리케이션의 성격에 따라 다르므로 이런 부분을 고려해야 한다. 
startingDeadlineSeconds
KIND:     CronJob
VERSION:  batch/v1
FIELD:    startingDeadlineSeconds <integer>
DESCRIPTION:
     Optional deadline in seconds for starting the job if it misses scheduled
     time for any reason. Missed jobs executions will be counted as failed ones.
스케줄링이 되는 시점에서 과거에 얼마동안 실패한 작업이 있는지를 체크한다.Missed jobs이 있는 지를 체크한다.
'DevOps > Kubernetes' 카테고리의 다른 글
| [Kubernetes] Service - ClusterIP (0) | 2022.05.20 | 
|---|---|
| [Kubernetes] Service & DNS (서비스와 DNS) (0) | 2022.05.20 | 
| [Kubernetes] Job (잡) (0) | 2022.05.20 | 
| [Kubernetes] Kubespray로 노드 추가/삭제하기 (0) | 2022.05.20 | 
| [Kubernetes] DaemonSet (데몬셋) (0) | 2022.05.20 | 
영차영차 성장 블로그
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!