코알못

[CKA] kubernetes Controller - JobController 본문

ETC

[CKA] kubernetes Controller - JobController

코린이s 2023. 9. 10. 01:03
728x90

쿠버네티스는 Running 을 유지 하려는 동작 방식을 가지고 있어 Pod 가 정상 종료 되더라도 계속적으로 재 실행 된다.

이를 위해 나온것이 Job Controller 이다!

Job Controller를 이용하면 Batch 처리하는 Pod를 만들어 잡이 정상 종료되면 완료 상태가 되고 비정상 종료시 재 실행 되도록 할 수 있다.

아래는 Job 을 생성하는 yaml 형식이며 template도 기존 controller 와 동일하게 담는다.

여기서 resartPolicy가 Naver인데 이는 비정상 종료일시 계속적으로 파드를 다시 생성한다는 의미이다.

# job.yaml

apiVersion: batch/v1
kind: Job
metadata:
  name: centos-job
spec:
#  completions: 5
#  parallelism: 2
#  activeDeadlineSeconds: 15
  template:
    spec:
      containers:
      - name: centos-container
        image: centos:7
        command: ["bash"]
        args:
        - "-c"
        - "echo 'Hello Corin'; sleep 50; echo 'Bye'"
      restartPolicy: Never

이제 해당 job을 생성한다.

$ kubectl create -f job.yaml 
job.batch/centos-job created

잡을 보면 하나의 잡이 성공했고 파드를 보면 정상적으로 completed 상태임을 알 수 있다.

$ kubectl get job
NAME         COMPLETIONS   DURATION   AGE
centos-job   1/1           60s        84s
$ kubectl get pod
NAME               READY   STATUS      RESTARTS   AGE
centos-job-xxx   0/1     Completed   0          2m15s

이제 해당 job을 제거하고

$ kubectl delete -f job.yaml 
job.batch "centos-job" deleted

잡을 다시 생성하는데 이번에는 비정상 종료시 어떻게 되는지 볼 것이다.

$ kubectl create -f job.yaml 
job.batch/centos-job created

비정상 종료를 발생시키기 위해 complete 되기전 파드를 얼른 제거한다.

$ kubectl delete pod centos-job-bh6d6
pod "centos-job-bh6d6" deleted

비정상 종료이므로 policy 가 Naver 이기에 파드를 다시 생성했을것이고 잡은 성공적으로 완료 되었다.

$ kubectl get pod
NAME               READY   STATUS      RESTARTS   AGE
centos-job-g8ngb   0/1     Completed   0          2m15s
$ kubectl get job
NAME         COMPLETIONS   DURATION   AGE
centos-job   1/1           73s        91s

정말 예상대로 동작했는지 보기위해 잡의 상세정보를 보며 pod 가 한번더 생성 되었음을 알 수 있다.

$ kubectl describe job
Name:             centos-job
Events:
  Type    Reason            Age   From            Message
  ----    ------            ----  ----            -------
  Normal  SuccessfulCreate  119s  job-controller  Created pod: centos-job-bh6d6
  Normal  SuccessfulCreate  99s   job-controller  Created pod: centos-job-g8ngb
  Normal  Completed         46s   job-controller  Job completed

restartPolicy의 값 중 실패시 파드를 재 생성 하는 Naver과는 다르게 OnFailure는 지정한 횟수만큼 컨테이너를 재 시작 하며 재시작 횟수 만큼 시도후에도 실패시 파드를 제거한다.

실패 할 수 있도록 command도 bash 가 아닌 이상한 단어를 적고 restartPolicy 를 OnFailure로 수정하고 재기동 횟수인 backoffLimit 를 3으로 지정한다.

# job.yaml

apiVersion: batch/v1
kind: Job
metadata:
  name: centos-job
spec:
#  completions: 5
#  parallelism: 2
#  activeDeadlineSeconds: 15
  template:
    spec:
      containers:
      - name: centos-container
        image: centos:7
        command: ["basch"]
        args:
        - "-c"
        - "echo 'Hello Corin'; sleep 50; echo 'Bye'"
      restartPolicy: OnFailure
  backoffLimit: 3

이제 해당 잡을 생성하며

$ kubectl create -f job.yaml 
job.batch/centos-job created

파드 상태를 보면 오류 발생시 파드가 아닌 컨테이너를 재시작 하며 3번까지 재시작 했음에도 불구하고 실패이므로 파드를 자동으로 제거한다.

[node1 ~]$ kubectl get pod -w
NAME               READY   STATUS              RESTARTS     AGE
centos-job-zg48v   0/1     RunContainerError   1 (4s ago)   5s
centos-job-zg48v   0/1     RunContainerError   2 (0s ago)    14s
centos-job-zg48v   0/1     RunContainerError   3 (0s ago)    44s
centos-job-zg48v   0/1     Terminating         3 (1s ago)    45s

파드를 확인해보면 제거 된것을 볼 수 있다.

$ kubectl get pod   
No resources found in default namespace.

이제 다음으로 볼 기능은 completions 이다.

이는 잡을 몇개 실행할지 지정하는것으로 replicas 와 비슷하다고 볼 수있다. 이는 기본으로 순차적으로 실행 되며 3개만 지정해서 지켜보도록 하자.

# job.yaml

apiVersion: batch/v1
kind: Job
metadata:
  name: centos-job
spec:
  completions: 3
#  parallelism: 2
#  activeDeadlineSeconds: 15
  template:
    spec:
      containers:
      - name: centos-container
        image: centos:7
        command: ["bash"]
        args:
        - "-c"
        - "echo 'Hello Corin'; sleep 10; echo 'Bye'"
      restartPolicy: OnFailure
  backoffLimit: 3

잡을 생성한다.

$ kubectl create -f job.yaml 
job.batch/centos-job created

파드를 실시간으로 보면 첫번째 파드가 Running > completed 가 되고 나서 두번째 파드가 생성되고 두번째 파드가 completed 되면 세번째 파드가 생성되고 완료시 종료 된다.

$ kubectl get pod -w
NAME               READY   STATUS    RESTARTS   AGE
centos-job-sn4pz   1/1     Running   0          3s
centos-job-sn4pz   0/1     Completed   0          13s
centos-job-jn2tw   0/1     Pending     0          0s
centos-job-sn4pz   0/1     Completed   0          14s
centos-job-jn2tw   0/1     ContainerCreating   0          0s
centos-job-jn2tw   1/1     Running             0          1s
centos-job-jn2tw   0/1     Completed           0          13s
centos-job-fbrhs   0/1     Pending             0          0s
centos-job-jn2tw   0/1     Completed           0          14s
centos-job-fbrhs   0/1     ContainerCreating   0          0s
centos-job-fbrhs   1/1     Running             0          1s
centos-job-fbrhs   0/1     Completed           0          14s

파드, 잡 정보를 보면 3개의 파드가 정상적으로 완료됨을 볼 수 있다.

$ kubectl get pod
NAME               READY   STATUS      RESTARTS   AGE
centos-job-fbrhs   0/1     Completed   0          38s
centos-job-jn2tw   0/1     Completed   0          52s
centos-job-sn4pz   0/1     Completed   0          66s
$ kubectl get job
NAME         COMPLETIONS   DURATION   AGE
centos-job   3/3           42s        85s

만약 동시에 2개의 잡이 실행 되면 좋겠다! 하면 parallelism을 2로 지정하여 2개가 동시에 실행 될 수 있도록 할 수 있다.

#job.yaml

apiVersion: batch/v1
kind: Job
metadata:
  name: centos-job
spec:
  completions: 3
  parallelism: 2
#  activeDeadlineSeconds: 15
  template:
    spec:
      containers:
      - name: centos-container
        image: centos:7
        command: ["bash"]
        args:
        - "-c"
        - "echo 'Hello Corin'; sleep 10; echo 'Bye'"
      restartPolicy: OnFailure
  backoffLimit: 3

잡을 생성한다.

$ kubectl create -f job.yaml 
job.batch/centos-job created

처음 시작부터 두개의 파드가 병렬로 실행 되었으며 완료가 되니 다른 파드가 실행되어 완료 됨을 볼 수 있다.

$ kubectl get pod -w
NAME               READY   STATUS    RESTARTS   AGE
centos-job-2469j   1/1     Running   0          2s
centos-job-r2ngv   1/1     Running   0          2s
centos-job-r2ngv   0/1     Completed   0          11s
centos-job-2469j   0/1     Completed   0          11s
centos-job-v5m79   0/1     Pending     0          0s
centos-job-v5m79   0/1     ContainerCreating   0          0s
centos-job-v5m79   1/1     Running             0          2s
centos-job-v5m79   0/1     Completed           0          12s

잡과 파드 정보를 보면 정상적으로 3개의 배치가 완료 됨을 볼 수 있다.

$ kubectl get job,pod
NAME                   COMPLETIONS   DURATION   AGE
job.batch/centos-job   3/3           27s        55s

NAME                   READY   STATUS      RESTARTS   AGE
pod/centos-job-2469j   0/1     Completed   0          55s
pod/centos-job-r2ngv   0/1     Completed   0          55s
pod/centos-job-v5m79   0/1     Completed   0          42s

이제 해당 job을 삭제하고

$ kubectl delete -f job.yaml 
job.batch "centos-job" deleted

다른 기능인 activeDeadlineSeconds 를 이용하여 만약 해당 값이 5 이면 5초안에 잡이 종료 되지 않으면 오류로 판단하겠다. 라고 설정 할 수 있다.

아래와 같이 10초 sleep 상태를 걸면 5초안에 배치가 끝나지 않을 것이고 해당 잡을 오류로 판단할 것이다.

# cronjob.yaml

apiVersion: batch/v1
kind: Job
metadata:
  name: centos-job
spec:
#  completions: 3
#  parallelism: 2
  activeDeadlineSeconds: 5
  template:
    spec:
      containers:
      - name: centos-container
        image: centos:7
        command: ["bash"]
        args:
        - "-c"
        - "echo 'Hello Corin'; sleep 10; echo 'Bye'"
      restartPolicy: Never
#  backoffLimit: 3

해당 잡을 생성한다.

$ kubectl create -f job.yaml 
job.batch/centos-job created

이제 실시간으로 보면 실행하다 5초 후에 실패로 판단하여 파드가 종료 된것을 볼 수 있다.

$ kubectl get pod -w
NAME               READY   STATUS    RESTARTS   AGE
centos-job-ffwl5   1/1     Running   0          3s
centos-job-ffwl5   1/1     Terminating   0          5s

이 경우에는 실패로 판단하여 재 시작 하지는 않는다.

[node1 ~]$ kubectl get pod 
No resources found in default namespace.
[node1 ~]$ kubectl get job 
NAME         COMPLETIONS   DURATION   AGE
centos-job   0/1           76s        76s

 

이제 CronJob에 대해서 알아보자!

CronJob의 경우 Job을 제어하여 특정 시간에 반복 실행 할 수 있도록 할 수 있다.

CronSchedule의 경우 아래와 같이 표기 하여 특정 일시에 실행 될 수 있도록 한다.

  • 분(0-59)
  • 시간(0-23)
  • 일(1-31)
  • 월(1-12)
  • 요일(0-6, 0은 일요일) 

만약 매월 1일 아침 9시에 Job 실행 하고 싶다면 아래와 같이 표기하면 된다.

  • 0 9 1 * *

만약 여기서 매주 주말 10시에 Job 을 실행하고 싶다면 아래와 같이 표기도 가능하다.

  • 0 10 * * 0,6

만약 5분마다 job을 계속 실행하고 싶다면 아래와 같이 표기한다.

  • */5 * * * *

이제 yaml 작성 법은 job을 동일하게 spec.jobTemplate 부분에 작성하고 spec.schedule 에 cron 형식을 정의 하면 된다.

우선 버전을 확인하고

[node1 ~]$ kubectl api-resources | grep -i cron
cronjobs                          cj           batch/v1                               true         CronJob

yaml 을 작성한다.

우선 concurrencyPolicy(동시성정책)가 default 로 Allow 이며 해당 값은 1분마다 스케쥴링 하는데 만약 1분안에 잡이 끝나지 않아도 1분 뒤에 해당 잡을 추가로 실행 시킬 것이다. 라는 의미이다.

여기서 Forbid(금지)로 설정시에는 1분 마다 스케쥴링 인데 해당 잡이 끝나지 않았다면 추가로 잡을 실행 시키지 않는다. 라는 의미이다.

startingDeadlineSeconds 는 현재 500인데 500s 안에 시작되지 않으면 오류로 판단하여 잡을 종료 하겠다라는 의미이다.

# cronjob.yaml

apiVersion: batch/v1
kind: CronJob
metadata:
  name: cronjob
spec:
  schedule: "* * * * *"
#  concurrencyPolicy: Allow
  concurrencyPolicy: Forbid
  startingDeadlineSeconds: 500
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            args:
            - /bin/sh
            - -c
            - echo corin; sleep 10
          restartPolicy: Never

이제 해당 cron을 실행 시켜 보자!

 

$ kubectl create -f cronjob.yaml

우리가 예상한 대로 1분마다 실행 되는것을 볼 수 있다.

$ kubectl get pod -w
NAME                     READY   STATUS    RESTARTS   AGE
cronjob-28237888-x4dz6   0/1     Pending   0          0s
cronjob-28237888-x4dz6   0/1     ContainerCreating   0          0s
cronjob-28237888-x4dz6   1/1     Running             0          3s
cronjob-28237888-x4dz6   0/1     Completed           0          13s
cronjob-28237889-ncdk7   0/1     ContainerCreating   0          0s
cronjob-28237889-ncdk7   1/1     Running             0          1s
cronjob-28237889-ncdk7   0/1     Completed           0          11s

끝!

728x90
Comments