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
![](https://velog.velcdn.com/images/pinion7/post/4b66b374-b48e-4eb3-bfe8-96ab4dbb3259/image.png)
- job.yml을 apply 한다.
- watch kubectl get pod
![](https://velog.velcdn.com/images/pinion7/post/1a850ff7-b6ed-401b-b9bd-d1b7c63f1ba2/image.png)
- 새로운 터미널을 열고 watch 모드를 실행하여 Pod를 관찰한다.
- Running에서 바로 Completed로 바뀌었다.
- kubectl get job
![](https://velog.velcdn.com/images/pinion7/post/2c0e2f51-f350-423d-8cbb-a04cc22eed4a/image.png)
- hello 라는 Job을 확인할 수 있다.
- kubectl describe job hello
![](https://velog.velcdn.com/images/pinion7/post/9ca7c3cc-7a1c-4f8b-8658-156cbe06c362/image.png)
- 좀 더 자세한 내역을 볼 수 있다.
- Pod Statuses에 1 Succeeded 라는 결과를 볼 수 있다.
- 무엇보다 기본적인 Selector와 Labels가 임의로 설정되었다는 것도 확인할 수 있다. 그리고 아래에 보면 Pod Template에도 Labels가 설정된 것을 확인할 수 있다.
- kubectl delete -f job.yml 하고 마무리 한다.
2번째 실습을 진행해보자.
- kubectl apply -f job-parallelism.yml
![](https://velog.velcdn.com/images/pinion7/post/a2834022-1d81-4433-b5bf-79bfddac93d8/image.png)
- 적용을 하면 아래와 같은 과정이 진행된다.
![](https://velog.velcdn.com/images/pinion7/post/ccbaffb7-d72b-414b-aab7-ebea50cab8d6/image.png)
![](https://velog.velcdn.com/images/pinion7/post/b8bf1518-69a5-415a-ab04-e9a862d7f99b/image.png)
![](https://velog.velcdn.com/images/pinion7/post/38e590cd-de75-4c6a-a2d1-45022b4fa68e/image.png)
- 2개씩 수행할 수 있도록 설정했기에 2개씩 늘어난다.
- ... (생략)
![](https://velog.velcdn.com/images/pinion7/post/44b5a9d6-2437-4157-94da-bae406b632b2/image.png)
- 최대 성공 Job 10개로 설정했기에 10개에서 멈춘다.
- kubectl logs job/hello
![](https://velog.velcdn.com/images/pinion7/post/579e1818-588f-4c59-aa97-b134cfeb61ec/image.png)
- Job의 로그를 확인할 수 있다.
- kubectl delete -f job-parallelism.yml 하고 마무리 한다.
3번째 실습을 진행해보자.
- kubectl apply -f job-deadline.yml
![](https://velog.velcdn.com/images/pinion7/post/804ceb69-d9c6-4744-b962-94cbe93980f1/image.png)
- apply를 한다.
![](https://velog.velcdn.com/images/pinion7/post/97edd864-dea7-465e-913b-a777db8294a4/image.png)
- watch 모드에는 Terminating이 뜨다가 사라진다.
- kubectl get job
![](https://velog.velcdn.com/images/pinion7/post/7db5374e-25a3-47ae-9d69-5ba96292070d/image.png)
- COMPLETIONS가 0/1인걸 볼 수 있다.
- kubectl describe job hello
![](https://velog.velcdn.com/images/pinion7/post/8d15491d-3d74-4ac5-bce8-bc8a2dfed856/image.png)
- Pod Statuses에 0 Succeeded 라는 결과를 볼 수 있다.
- 가장 하단에 Events를 보면 어떤 과정이 일어났는지 알 수 있다.
- SuccessfulCreate => SuccessfulDelete => DeadlineExceeded를 거치며 종료되는 걸 알 수 있다.
- Deadline이 3초인데 슬립5설정으로 이를 넘어서며 성공하지 못하고 종료되는 것이다.
- kubectl delete -f job-deadline.yml 하고 마무리 한다.
4번째 실습을 진행해보자.
- kubectl apply -f cronjob.yml
![](https://velog.velcdn.com/images/pinion7/post/a44cd389-5c9a-4ea8-839f-fa2bc13aae49/image.png)
- cronjob 명세를 apply 한다.
![](https://velog.velcdn.com/images/pinion7/post/8fdcef92-da46-443f-950a-7effd4d29d8c/image.png)
![](https://velog.velcdn.com/images/pinion7/post/1aa5b96b-8321-43a4-86af-52f58fc8f781/image.png)
- ... (생략)
![](https://velog.velcdn.com/images/pinion7/post/922fd628-7010-4db9-926c-a9b0454e130d/image.png)
- 이렇게 1분에 하나씩 추가되는 걸 알 수 있다.
![](https://velog.velcdn.com/images/pinion7/post/89159c05-b4a9-4953-82dc-5669f6ff56bf/image.png)
![](https://velog.velcdn.com/images/pinion7/post/fe62b42f-74e7-4685-a9ba-bf48de0782ac/image.png)
- 5개가 만들어졌어도 1분이 지나면 새로 하나를 만들면서 기존의 것을 하나 제거한다.
- kubectl get cronjob
![](https://velog.velcdn.com/images/pinion7/post/6c1b7e14-4c36-43db-b82f-f5457521753d/image.png)
- SCHEDULE에 표현식을 볼 수 있다.
- LAST SCHEDULE을 통해 23초 전에 스케쥴링이 됐었다는 걸 확인할 수 있다.
- kubectl get job
![](https://velog.velcdn.com/images/pinion7/post/f8d55f32-0dec-41f9-9df7-03c36bd5a806/image.png)
- CronJob의 이름에 랜덤한 식별자가 추가되서 이름이 생성된 것을 볼 수 있다.
- kubectl get pod
![](https://velog.velcdn.com/images/pinion7/post/c7d2950c-abf4-45d2-b1cd-50425d9dedcb/image.png)
- Pod는 거기에 또 다른 식별자가 붙어서 생성되는 걸 볼 수 있다.