backend/kubernetes in action

[kubernetes in action] 4-5. Running pods that perform a single completable task

seul chan 2020. 5. 30. 21:33

ch4. Replication and other controllers: deploying managed pods

4.5. Running pods that perform a single completable task

소챕터들

지금까지는 지속적으로 동작하는 pod에 대해서만 얘기했다. ReplicationController, ReplicaSets, DaemonSet은 모두 지속적이고 완료되지 않는 태스크들을 다룬다. 하지만 완료 가능한 태스크 (completable task)에서는 프로세스가 종료되면 다시 시작될 필요가 없다.

Introducing the Job resource

Kubernetes는 Job resource를 지원한다; 이는 pod 안의 process가 완료되면 contariner가 다시 시작하지 않게 해 준다.

이런 job의 예시는 어딘가에 저장된 data를 transform하여 다른 곳으로 export 할 때 등에 쓰인다.

ETL 프로세스같이 1회성 작업을 하는 태스크들은 Job을 사용하여 띄우면 좋을듯하다.

busybox라는, 2분이 지나면 sleep command를 시랭시키는 이미지를 띄우는 컨테이너를 만들어 볼 것이다. 이미 luksa/batch-job으로 저자가 Docker Hub에 올려두었기 때문에 따로 빌드할 필요는 없다.

Defining a Job resource

exporter.yaml 파일을 만들어보자.

apiVersion: batch/v1                  1
kind: Job                             1
metadata:
  name: batch-job
spec:                                 2
  template:
    metadata:
      labels:                         2
        app: batch-job                2
    spec:
      restartPolicy: OnFailure        3
      containers:
      - name: main
        image: luksa/batch-job
    1. Job은 batch API group, v1에 있다.
    1. 따로 pod selector를 지정하지 않았다. (pod template의 라벨에 의해 생성됨)
    1. Job은 default restart policy (Always)를 사용할 수 없다.

Seeing a Job run a pod

kubectl create 명령어로 Job을 생성해보자.

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

$ kubectl get jobs
NAME        COMPLETIONS   DURATION   AGE
batch-job   0/1           7s         7s

$ kubectl get po
NAME              READY   STATUS    RESTARTS   AGE
batch-job-7n8dq   1/1     Running   0          16s

2분이 지나면 job의 COMPLETION이 변경되고 pod는 더 이상 나타나지 않는다. 기본으로 완료된 pod는 --show-all(-a) 옵션을 주지 않으면 따로 나타나지 않는다.

현재 (2020-05) 기준으로는 --show-all 옵션은 deprecated 되었고 그냥 kubectl get을 사용하여도 complated 된 pod가 나온다.

$ kubecto get po
NAME              READY   STATUS      RESTARTS   AGE
batch-job-7n8dq   0/1     Completed   0          2m21s

실제로 해당 job이 어떻게 작동했는지 logs를 사용하여 확인할 수 있다.

$ kubectl logs batch-job-7n8dq
Sat May 23 14:30:41 UTC 2020 Batch job starting
Sat May 23 14:32:41 UTC 2020 Finished succesfully

실제로 job도 완료 된 것을 볼 수 있다.

NAME        COMPLETIONS   DURATION   AGE
batch-job   1/1           2m7s       3m9s

Running multiple pod instances in a job

Job은 여러 pod instance를 병렬, 혹은 연속적으로 생성하게 설정 가능하다.

Running job pods sequentially

completions를 설정하면 Job의 pod가 몇 번 실행될 것인지 지정할 수 있다.

multi-completion-batch-job.yaml을 만들어보자.

apiVersion: batch/v1
kind: Job
metadata:
  name: multi-completion-batch-job
spec:
  completions: 5                                1
  template:
    <template is the same as in listing 4.11>

위의 Job은 다섯개의 pod를 순차적으로 실행시킬 것이다. 하나의 pod가 실패하면 새로운 pod를 만들고, 총 5개의 pod가 실행될 때까지 계속될 것이다.

Running job pods in parallel

Job pods가 하나씩 실행되게 하는 대신에 병렬로 실행되게 할 수 있다. parallelism 옵션으로 가능

multi-completion-parallel-batch-job.yaml

apiVersion: batch/v1
kind: Job
metadata:
  name: multi-completion-batch-job
spec:
  completions: 5
  parallelism: 2
  template:
    <same as in listing 4.11>

parallelism이 2로 설정되었기 때문에 2개의 pod가 병렬로 실행된다.

$ kubectl create -f multi-completion-parallel-batch-job.yaml
job.batch/multi-completion-batch-job created

$ kubectl get jobs
NAME                         COMPLETIONS   DURATION   AGE
batch-job                    1/1           2m7s       11m
multi-completion-batch-job   0/5           21s        21s

$ kubectl get po
NAME                               READY   STATUS      RESTARTS   AGE
batch-job-7n8dq                    0/1     Completed   0          11m
multi-completion-batch-job-5s4dc   1/1     Running     0          31s
multi-completion-batch-job-qt8qw   1/1     Running     0          31s

두개가 병렬적으로 실행되고 있는 것을 볼 수 있다.

Scaling a job

Job이 실행되는 도중에도 parallelism을 변경할 수 있다.

kubectl scale 명령어를 사용해보자.

$ kubectl scale job multi-completion-batch-job --replicas 3

kubectl scale job은 더 이상 사용하지 못하는 듯 하다.

Limiting the time allowed for a Job pod to complete

activeDeadlineSeconds property를 사용하여 job이 실행시킬 수 있는 pod의 time limit을 걸 수 있다.

spec.backoffLimit을 사용하여 얼마나 retried 될 것인지도 정할 수 있다. default는 6