【Kubernetes】ワークロードリソース【Jobs編】

前回の記事に続き、ワークロードリソースについて書いていきたいと思います。今回はJobsについてです。


Jobsとは

公式サイトを見てみましょう。

Jobは一つ以上のPodを作成し、指定された数のPodが正常に終了するまで、Podの実行を再試行し続けます。Podが正常に終了すると、Jobは成功したPodの数を追跡します。指定された完了数に達すると、そのタスク(つまりJob)は完了したとみなされます。Jobを削除すると、作成されたPodも一緒に削除されます。Jobを一時停止すると、再開されるまで、稼働しているPodは全部削除されます。

単純なケースを言うと、確実に一つのPodが正常に完了するまで実行されるよう、一つのJobオブジェクトを作成します。 一つ目のPodに障害が発生したり、(例えばノードのハードウェア障害またノードの再起動が原因で)削除されたりすると、Jobオブジェクトは新しいPodを作成します。

公式サイト

その名の通り、Podを作成するためのジョブのようですが、Podが正常終了するとJob自体が完了となるようです。

実装

(ちょっと何言ってるか分からないので)公式サイトに載っているyamlを実装して挙動を確認してみます。このyamlではPerlのコンテナを立ち上げ、円周率を2,000桁まで出力させるようです。

apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  template:
    spec:
      containers:
      - name: pi
        image: perl:5.34.0
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never
  backoffLimit: 4

いざデプロイ

kubectl apply -f controllers-job.yaml                       
job.batch/pi created

Podの状態を確認します。あっという間に円周率表示処理が終わったので、「Completed」になっています。

kubectl get po         
NAME       READY   STATUS      RESTARTS   AGE
pi-sk5rd   0/1     Completed   0          104s

次にjobの状態を見てみます。PodがCompletedになったことでJobとしては完了扱いとなり、「Job Completed」が表示されています(一番下の行)。

kubectl describe job pi
Name:             pi
Namespace:        default
Selector:         batch.kubernetes.io/controller-uid=c765aeed-f12e-450d-a15c-a21df4ba081b
Labels:           batch.kubernetes.io/controller-uid=c765aeed-f12e-450d-a15c-a21df4ba081b
                  batch.kubernetes.io/job-name=pi
                  controller-uid=c765aeed-f12e-450d-a15c-a21df4ba081b
                  job-name=pi
Annotations:      <none>
Parallelism:      1
Completions:      1
Completion Mode:  NonIndexed
Start Time:       Sat, 03 Feb 2024 16:53:28 +0900
Completed At:     Sat, 03 Feb 2024 16:54:50 +0900
Duration:         82s
Pods Statuses:    0 Active (0 Ready) / 1 Succeeded / 0 Failed
Pod Template:
  Labels:  batch.kubernetes.io/controller-uid=c765aeed-f12e-450d-a15c-a21df4ba081b
           batch.kubernetes.io/job-name=pi
           controller-uid=c765aeed-f12e-450d-a15c-a21df4ba081b
           job-name=pi
  Containers:
   pi:
    Image:      perl:5.34.0
    Port:       <none>
    Host Port:  <none>
    Command:
      perl
      -Mbignum=bpi
      -wle
      print bpi(2000)
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Events:
  Type    Reason            Age   From            Message
  ----    ------            ----  ----            -------
  Normal  SuccessfulCreate  97s   job-controller  Created pod: pi-sk5rd
  Normal  Completed         15s   job-controller  Job completed

コンテナ初心者は気になった

今回はPodの中で所定の処理を行わせていますが、特にそういった処理はさせずただコンテナをあげっぱなしにしている時はどうなるのでしょうか。
というわけで、以下のJobでnginxコンテナをデプロイしJobのステータスを見てみます(Jobの名前とコンテナのイメージを変えただけです)。

apiVersion: batch/v1
kind: Job
metadata:
  name: ng
spec:
  template:
    spec:
      containers:
      - name: ng
        image: nginx:1.14.2
        ports:
        - containerPort: 80
      restartPolicy: Never
  backoffLimit: 4

上記yamlをapplyした後にPodの状態を確認します。
円周率コンテナ(?)とは異なり、「Running」のままです。

kubectl get po
NAME       READY   STATUS      RESTARTS   AGE
ng-t8j4d   1/1     Running     0          38s  →2番目に作ったnginxコンテナ
pi-sk5rd   0/1     Completed   0          14m  →初めに作った円周率表示コンテナ

続いてJobの状態です。

kubectl describe job/ng 
Name:             ng
Namespace:        default
Selector:         batch.kubernetes.io/controller-uid=5a2f4256-a027-4795-afae-46202a49a5e8
Labels:           batch.kubernetes.io/controller-uid=5a2f4256-a027-4795-afae-46202a49a5e8
                  batch.kubernetes.io/job-name=ng
                  controller-uid=5a2f4256-a027-4795-afae-46202a49a5e8
                  job-name=ng
Annotations:      <none>
Parallelism:      1
Completions:      1
Completion Mode:  NonIndexed
Start Time:       Sat, 03 Feb 2024 17:07:06 +0900
Pods Statuses:    1 Active (1 Ready) / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  batch.kubernetes.io/controller-uid=5a2f4256-a027-4795-afae-46202a49a5e8
           batch.kubernetes.io/job-name=ng
           controller-uid=5a2f4256-a027-4795-afae-46202a49a5e8
           job-name=ng
  Containers:
   ng:
    Image:        nginx:1.14.2
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Events:
  Type    Reason            Age   From            Message
  ----    ------            ----  ----            -------
  Normal  SuccessfulCreate  33s   job-controller  Created pod: ng-t8j4d

PodがCompletedになっていないのでJobも終わるわけにはいかず、「Job completed」は出ていないことがわかりました。

後始末

今回作ったリソースを削除します。

kubectl delete -f controllers-job.yaml
job.batch "pi" deleted

Job,Podいずれも削除されました。

kubectl get job
No resources found in default namespace.

kubectl get po
No resources found in default namespace.

まとめ

Deploymentと同様にPodのスペックを指定して起動することができますが、JobはPodがCompletedになると自分自身もCompletedになることがわかりました。(実装v2で逆のパターンも実験しました)
夜間バッチのように実行する処理が決まっている場合に使うといいのかなと思いました。

今回もご覧いただきありがとうございました。