kubernetes에서 파드는 일반적으로 Deployment나 ReplicaSet과 함께 지속적으로 수행되도록하는 목적을 가지고 있다.
하지만, 단순히 일회성을 가지고 수행되는 작업들도 존재한다.
예를 들면, 로그 데이터 처리나 데이터 백업같은 데이터 처리 작업이나 외부 API를 통해 데이터 수집이나 동기화 작업과 같은 배치 작업들이 있을 수 있다.
이러한 작업들도 Kubernetes 클러스터 내에서 실행될 수 있다. 바로 이번에 알아볼 Job과 CronJob이 여기에 해당된다.
Job
일회성 작업을 수행하는 리소스
Job은 파드를 통해서 작업을 수행하고, 지정된 작업이 성공적으로 종료될때까지 수행을 반복한다.
아래와 같이 Job은 실행할 내용을 Pod template에 담아서 생성하게 된다.
apiVersion: batch/v1
kind: Job
metadata:
name: ubuntu-job
namespace: jobtest
spec:
template:
spec:
containers:
- name: ubuntu-container
image: ubuntu:latest
command: ["/bin/bash", "-c"]
args:
- echo "Hello, Kubernetes Job!" && sleep 5
restartPolicy: Never
Job은 성공적으로 수행되어 종료되면 'Completed' 상태로 전환된다. 이는 작업이 완전종료되었다는 의미로, 해당 파드는 더이상 실행되지 않는 상태가 된다.
Job 파드의 라이프사이클
'Completed' 상태의 Job 파드는 기본적으로 삭제되지 않는다는 점이 있다.
Job의 실행 내역과 이벤트들을 보존하기 위한 의미로, Completed된 Job 파드는 Job 자체를 삭제하면 일괄적으로 삭제된다.
그밖에도 TTL 매커니즘을 사용해 일정시간이 지나면 자동으로 완료된 파드를 정리할 수 있다.
`.spec.ttlSecondsAfterFinished` 값을 지정해서 TTL 시간이 지난 파드를 완전히 삭제할 수 있게 된다.
TTL은 Job 자체가 Completed로 전환된 시점부터 카운트된다. 즉, Pod들 자체적으로 실행되는 시간과는 무관한 것이다.
apiVersion: batch/v1
kind: Job
metadata:
name: ubuntu-job
spec:
completions: 5
ttlSecondsAfterFinished: 30
template:
spec:
containers:
- name: ubuntu-container
image: ubuntu:latest
command: ["/bin/bash", "-c"]
args:
- echo "Hello, Kubernetes Job!" && sleep 5
restartPolicy: Never
위 예시에 따르면 Job을 실행하는 pod가 총 5개가 생성되고, 모두 완료되어 Job이 'completed' 상태로 전환된다.
바로 그 시점부터 ttl Second가 적용되어, 30초가 지난 후에야 이 Job의 모든 파드가 한번에 삭제되는 것을 볼 수 있다.
Job의 실패횟수 제한
실행하는 Job의 내용에 논리적인 에러가 발생해 Job을 계속 재실행하게되는 문제상황이 발생할 수 있다.
계속해서 불필요하게 재실행하는것을 방지하기 위해 backoffLimit을 사용할 수 있다.
Job에서 backoffLimit의 기본값은 6으로 지정되어있으며, `.spec.backoffLimit`에서 값을 별도로 지정할 수 있다.
아래는 Job이 항상 실패하도록 exit을 적용한 것으로, backoffLimit을 3으로 지정한 예시다.
apiVersion: batch/v1
kind: Job
metadata:
name: failing-job
namespace: jobtest
spec:
backoffLimit: 3 # 최대 3번 재시도 후 실패 처리
template:
spec:
containers:
- name: ubuntu-container
image: ubuntu:latest
command: ["/bin/bash", "-c"]
args:
- echo "This job will fail..." && exit 1
restartPolicy: Never # 실패 시 자동 재시작 안 함
이 Job을 배포하면 completion이 계속 0으로 성공하지 못하는 것을 볼 수 있다.
job의 describe를 확인하면, 3번까지 재시도한 이벤트와 함께 결국 job이 backoffLimit에 의해 중단된 내용을 확인할 수 있다.
Job의 시간 제한
Job이 무한하게 동작하지 않도록 activeDeadlineSeconds를 지정해 Job 전체가 실행될 수 있는 최대 제한시간을 설정할 수 있다.
아래 예시처럼 `activeDeadlineSeconds`를 20초로 지정하고, `completion`이 10짜리인 Job을 수행해본다.
apiVersion: batch/v1
kind: Job
metadata:
name: deadline-job
namespace: jobtest
spec:
completions: 10
activeDeadlineSeconds: 20
template:
spec:
containers:
- name: ubuntu-container
image: ubuntu:latest
command: ["/bin/bash", "-c"]
args:
- |
echo "$(date)"
sleep 1
restartPolicy: Never
이 Job을 실행 후, 계속 모니터링해보면 Job에 의해 pod들이 계속 생성되고 Completion되다가 어느 순간 Job이 Fail 처리되는 것을 볼 수 있다.
이 Job의 이벤트 describe를 확인하면 job이 계속 실행되다가 지정한 Deadline인 20초를 넘어서 Job이 중단된 것을 볼 수 있다.
이렇게 Deadline을 넘어서 중단된 Job의 실행중이던 파드는 Terminate되어 삭제되는 것도 볼 수 있다.
병렬 Jobs
더불어 parallelism을 통해 Job들의 병렬적인 처리도 가능하다. `.spec.parallelism`에서 값을 지정해서 Job을 한번에 여러개 실행할 수 있다.
아래 예시에서는 ubuntu 컨테이너에서 3개의 pod를 병렬로 실행하는 job을 볼 수 있다.
apiVersion: batch/v1
kind: Job
metadata:
name: parallel-job
namespace: jobtest
spec:
completions: 3
parallelism: 3
template:
spec:
containers:
- name: ubuntu-container
image: ubuntu:latest
command: ["/bin/bash", "-c"]
args:
- |
JOB_INDEX=$(expr $RANDOM % 100)
echo "$(date) : Job ID $JOB_INDEX"
sleep 5
restartPolicy: Never
이 Job을 실행하면 3개의 pod가 실행되고, 모두 Completed 되어 Job이 성공적으로 완료된 것을 볼 수 있다.
그리고 실행된 Job의 각 pod 로그를 확인하면 job의 pod가 모두 병렬로 실행된 내역을 확인할 수 있다.
CronJob
Job을 Cron 식에 맞게 주기적으로 수행할 수 있도록 하는 리소스
CronJob은 생성과 동시에 실행되지 않고, Cron식에 맞게 실행된다.
기본적으로 Job은 생성과 동시에 실행되고, 수행되면 Completed로 전환되는데 CronJob에서는 이러한 Job을 주기적/반복적으로 실행할 수 있도록 한다.
apiVersion: batch/v1
kind: CronJob
metadata:
name: api-caller-cronjob
spec:
schedule: "*/1 * * * *" # 매 1분마다 실행
jobTemplate:
spec:
template:
spec:
containers:
- name: ubuntu-container
image: ubuntu:latest
command: ["/bin/bash", "-c"]
args:
- |
echo "Calling external API..."
curl -s https://jsonplaceholder.typicode.com/todos/1
echo "Job completed at $(date)"
restartPolicy: Never
CronJob은 Cron식에 따라 Job을 실행하기에 Cron식을 작성하는 필드(schedule)와 Job을 가지게 된다. (jobTemplate)
CronJob에서 지원하는 Cron 표현식은 아래와 같이 5개의 필드로 나뉜다.
+) Cron 표현식을 간편하게 생성할 수 있는 외부 사이트를 이용해도 좋다.