LoginSignup
13
16

More than 5 years have passed since last update.

バッチのシェルを書いて、コンテナ化して、レジストリに登録して、k8sクラスタで実行するまでのお話し

Last updated at Posted at 2018-02-01

Kuberntesには、ジョブというコントローラがあり、バッチ処理をスケジュールすることが出来ます。
しかし、Kuberntesはスケジュールするという表現が使われるのですが、業務システムで利用されるジョブのスケジューラーの様にジョブネットを組んで、前後関係を管理しながら、ジョブ全体の正常終了を管理するものでも無く、科学計算系で利用される様な、計算ノード群へ、ジョブを割り当てて、並列なバッチ処理をサポートするタイプとも、少し違う感じがします。

そこで、実際に試して確認する事にします。

シェルスクリプト作成

ローカルの環境で、下記のサンプルとなるシェル・スクリプトを作成します。 このシェルは、第一引数でループの回数を設定します。1増えるごとに、終了時間が3秒づつ長くなります。 そして、第二引数で終了コードを設定できます。

#!/bin/bash

if [ $# -ne 2 ]; then
  echo "指定された引数は$#個です。" 1>&2
  echo "実行するには2個の引数が必要です。" 1>&2
  echo "my-shell ループ数 完了時終了コード" 1>&2
  exit 1
fi

x=0
while true 
do
  let x=x+1
  echo $x `uuid`
  if [ $x -eq $1 ]; then
      exit $2
  fi
  sleep 3
done

シェルのコンテナ化

このシェルを次のDockerfileでコンテナ化します。 ここでコンテナ実行時のデフォルトの引数として、ループ回数=3、終了コード=0 を指定します。 このパラメータは後に、オーバーライトできますので、サクッとテストできるものが適切でしょう。

FROM ubuntu:latest
COPY ./my-shell /my-shell
RUN apt-get update
RUN apt-get install uuid -y
CMD ["/my-shell", "3","0"]

Dockerfile と my-shell の2つのファイルがあるディレクトリで、コンテナのビルドを実行します。

$ docker build --tag job-x .

これでローカルのリポジトリに登録されたコンテナを確認します。

$ docker images
REPOSITORY        TAG          IMAGE ID            CREATED             SIZE
job-x             latest       4481e04e94e7        37 seconds ago      151MB

次に、コンテナで動作するシェルを確認しておきます。

$ docker run --rm --name job-x job-x:latest "/my-shell" 2 7
1 ecab8456-071e-11e8-b25b-0242ac110002
2 ee7599ca-071e-11e8-aa3d-0242ac110002
$ echo $?
7

リモート・レジストリへ、コンテナ・イメージを登録

テストで問題がなければ、リモート・リポジトリのタグを付けて、リモート・リポジトリへプッシュします。

$ docker tag job-x:latest registry.au-syd.bluemix.net/takara/job:v1
$ docker push registry.au-syd.bluemix.net/takara/job:v1

リモート・リポジトリへの登録結果を確認します。

$ bx cr images
Listing images...

REPOSITORY                              NAMESPACE   TAG   CREATED         SIZE     VULNERABILITY STATUS   
registry.au-syd.bluemix.net/takara/job  takara      v1    6 minutes ago   72 MB    Vulnerable   

コンテナ・イメージの登録に失敗していたら、bx cr login を再実行して、docker pushをリトライして、認証の問題を解決します。

k8sクラスタでジョブ実行

次のジョブを実行するためのYAMLファイルを作成して、k8sクラスタ上にジョブを投入します。 ここで、command:フィールドに、オーバーライドするパラメータを書いておきます。

job.yml
apiVersion: batch/v1
kind: Job
metadata:
  name: job-batch
spec:
  template:
    spec:
      containers:
      - name: job-batch
        image: registry.au-syd.bluemix.net/takara/job:v1
        command: ["/my-shell",  "2", "0"]
      restartPolicy: Never
  backoffLimit: 4

kubectlコマンドでYAMLファイルを設定して実行するだけです。

kubctl create -f job.yml

成功終了の場合、ジョブはスグに終了して、結果を参照できます。kubectl get jobsで、ジョブの終了結果を参照できます。さらに、細かい情報が知りたければ、次の様にコマンドを実行します。 ここでは、Pod Statuses:フィールドで、正常終了が確認できます。 終了コード=0に指定しているので、正常終了したと見なされます。 もしも、ゼロ以外の値の場合は、Failed と見なされ、再試行に入ります。

$ kubectl describe job job-batch
Name:           job-batch
Namespace:      default
Selector:       controller-uid=16725165-0720-11e8-8cfc-76140a51e2a9
Labels:         controller-uid=16725165-0720-11e8-8cfc-76140a51e2a9
                job-name=job-batch
Annotations:    <none>
Parallelism:    1
Completions:    1
Start Time:     Thu, 01 Feb 2018 07:18:23 +0000
Pods Statuses:  0 Running / 1 Succeeded / 0 Failed
Pod Template:
  Labels:  controller-uid=16725165-0720-11e8-8cfc-76140a51e2a9
           job-name=job-batch
  Containers:
   job-batch:
    Image:  registry.au-syd.bluemix.net/takara/job:v1
    Port:   <none>
    Command:
      /my-shell
      2
      0
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Events:
  Type    Reason            Age   From            Message
  ----    ------            ----  ----            -------
  Normal  SuccessfulCreate  1m    job-controller  Created pod: job-batch-kk8dd

既にジョブが終了しており、'kubectl get podsでは参照できないので、--show-all`を付加して、参照します。

$ kubectl get pods --show-all
NAME                               READY     STATUS             RESTARTS   AGE
...
job-batch-kk8dd                    0/1       Completed          0          3m
...

ポッドを指定して、ログを表示すると、前述のローカルで実行したものと同じ様に、結果を見ることが出来ます。

$ kubectl logs job-batch-kk8dd 
1 1bfdf5da-0720-11e8-babf-877ba3ad5a1c
2 1dca4cd8-0720-11e8-b9d6-274d9f3cf681

ログをコマンド1行で表示するには、ちょっと長いですが、以下の様にします。

$ kubectl logs $(kubectl get pods  --show-all --selector=job-name=job-batch --output=jsonpath={.items..metadata.name})
1 1bfdf5da-0720-11e8-babf-877ba3ad5a1c
2 1dca4cd8-0720-11e8-b9d6-274d9f3cf681

ジョブの削除

次のコマンドでジョブの削除を実行して、確認します。 結果から確かに削除されたことが解ります。

$ kubectl delete -f job.yml
job "job-batch" deleted

$ kubectl get job job-batch
Error from server (NotFound): jobs.batch "job-batch" not found

ジョブの失敗ケース

シェルの終了コードが 1となる様に、command: ["/my-shell", "2", "1"] を修正します。これは、Dockerfileを参照すれば、CMD ["/my-shell", "3","0"] の様にコンテナを開始した時に、my-shellコマンドが引数と共に実行するように、セットされているのですが、job.ymlに再設定することで、コンテナのCMDを上書きすることができます。

そして、backoffLimit: 2 に設定します。 最初の実行から2回リトライして、やはり失敗したらジョブの再試行を終了するというものです。

job.yml
apiVersion: batch/v1
kind: Job
metadata:
  name: job-batch
spec:
  template:
    spec:
      containers:
      - name: job-batch
        image: registry.au-syd.bluemix.net/takara/job:v1
        command: ["/my-shell",  "2", "1"]
      restartPolicy: Never
  backoffLimit: 2

ジョブを実行します。

$ kubectl create -f job.yml

約1分後に、ジョブの状態を確認すると、SUCCESSFUL(成功)が0の状態になっています。

$ kubectl get job job-batch
NAME        DESIRED   SUCCESSFUL   AGE
job-batch   1         0            1m

何回試行(backoff)したのかを確認します。次のコマンドで確認したところ、
初回起動時に加えて、2回試行して、終了していることが確認できます。

$ kubectl describe job job-batch
Name:           job-batch
Namespace:      default
Selector:       controller-uid=f60bbdef-0723-11e8-8cfc-76140a51e2a9
Labels:         controller-uid=f60bbdef-0723-11e8-8cfc-76140a51e2a9
                job-name=job-batch
Annotations:    <none>
Parallelism:    1
Completions:    1
Start Time:     Thu, 01 Feb 2018 07:46:06 +0000
Pods Statuses:  0 Running / 0 Succeeded / 3 Failed
Pod Template:
  Labels:  controller-uid=f60bbdef-0723-11e8-8cfc-76140a51e2a9
           job-name=job-batch
  Containers:
   job-batch:
    Image:  registry.au-syd.bluemix.net/takara/job:v1
    Port:   <none>
    Command:
      /my-shell
      2
      1
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Events:
  Type     Reason                Age   From            Message
  ----     ------                ----  ----            -------
  Normal   SuccessfulCreate      27s   job-controller  Created pod: job-batch-spvnl
  Normal   SuccessfulCreate      21s   job-controller  Created pod: job-batch-w5wpt
  Normal   SuccessfulCreate      11s   job-controller  Created pod: job-batch-xq6qh
  Warning  BackoffLimitExceeded  1s    job-controller  Job has reach the specified backoff limit

以上

13
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
16