Batch on GKE でのジョブの実行

このページでは、Batch on GKE(Batch)を使用してバッチジョブを実行する方法を説明します。ジョブを Batch で送信する方法は次の 2 つ(ksubkubectl)です。ksub コマンドを使えばジョブとしてシェル スクリプトを送信できます。また、kubectl を使えば yaml ファイルを使用してジョブを送信できます。

ksub を構成する

ksub は、Batch システムでジョブ関連のアクションを実行するコマンドライン ツールです。#KB の接頭辞を持つキーワードを使用してジョブのプロパティを指定できます。

ksub を構成するには、次の手順を行います。

  1. ksub に対して API アクセスのために自身のユーザー認証情報の使用を許可します。

    gcloud auth application-default login
    
  2. kbatch ディレクトリに移動します。使用している OS に応じて、ksub フォルダから適切な ksub バージョンを選択します。たとえば、Linux ユーザーの場合は、次のバージョンを使用します。

    cd ksub/linux/amd64
    
  3. デフォルトの構成ファイルを設定します。

    ./ksub --config --create-default
    

    これで ~/.ksubrc に構成ファイルが作成されます。

  4. 次のような ksub コマンドを使用して、project-id、cluster-name、namespace-name(デフォルトの名前空間で作業していない場合)の値を追加します。

    ./ksub --config --set-project-id project-id \
    --set-clustername cluster-name --set-namespace namespace-name
    
  5. マウント ポイントを設定します [クラスタ管理者が作成した非公開の PersistentVolumeClaim を使用しない場合は省略可]。

    ./ksub --config --add-volume fs-volume --volume-source PersistentVolumeClaim
     --params claimName:[PVC_NAME] --params readOnly:false
    

    [PVC_NAME] は、個人用の非公開入出力ファイルを保存するために管理者が作成した PersistentVolumeClaim 名です。Filestore インスタンスを使用する場合、これは Filestore インスタンスの名前です。

  6. $PATH に ksub のインストール ディレクトリを追加します。

    export PATH=$PATH:/path/to/kbatch/
    

kubectl を構成する

Kubernetes のデフォルトのツールは kubectl で、すでに Cloud SDK に含まれています。

最新バージョンの kubectl で作業するために、以下のコマンドを実行します。

gcloud components update

サンプルジョブの実行

Batch on GKE には、サンプルジョブがいくつか含まれています。

単一タスクジョブの実行

  1. サンプルを取得します。

    git clone https://github.com/GoogleCloudPlatform/Kbatch.git
    
  2. 「デフォルト」の K8s 名前空間にデフォルトの Batch 管理者リソースを作成します。

    ./samples/defaultresources/create.sh
    

ジョブは、ksub または kubectl を使用して送信できます。

ksub

  1. /samples/computepi で ComputePi ジョブを実行します。

    ksub run_pi_with_ksub.sh
    

    このコマンドは、ジョブ名を出力します。

  2. ジョブが完了するまで待ちます。

    ksub -Gw [JOB_NAME]
    
  3. タスク名を取得します。

    ksub -Ga [JOB_NAME]
    

    このコマンドはタスク名を出力します。

  4. ログを表示します。

    ksub -L [TASK_NAME]
    

kubectl

  1. /samples/computepi で ComputePi ジョブを実行します。

    kubectl create -f pi-job.yaml
    

    ここでの出力は次のようになります。

    batchjob.kbatch.k8s.io/[JOB_NAME] created
    
  2. ジョブに関連付けられているポッドを確認します。

    kubectl get pods | grep [JOB_NAME]
    

    次のように出力されます。

    [POD_NAME]   0/1     Completed   0          1m
    
  3. ログを表示します。

    kubectl logs pod/[POD_NAME]
    

プリエンプティブル VM を使用するジョブの実行

  1. サンプルを取得します。他のサンプルジョブで実行済みの場合、この手順はスキップします。

    git clone https://github.com/GoogleCloudPlatform/Kbatch.git
    
  2. 「デフォルト」の K8s 名前空間にデフォルトの Batch 管理者リソースを作成します。他のサンプルジョブで実行済みの場合、この手順はスキップします。

    ./samples/defaultresources/create.sh
    

ジョブは、ksub または kubectl を使用して送信できます。

ksub

  1. /samples/computepi で ComputePi Preemptible Job を実行します。

    ksub run_pi_preemptible_with_ksub.sh
    

    このコマンドは、ジョブ名を出力します。

  2. ジョブが完了するまで待ちます。

    ksub -Gw [JOB_NAME]
    
  3. タスク名を取得します。

    ksub -Ga [JOB_NAME]
    

    このコマンドはタスク名を出力します。

  4. ログを表示します。

    ksub -L [TASK_NAME]
    

kubectl

  1. /samples/computepi で ComputePi Preemptible Job を実行します。

    kubectl create -f pi-job-preemptible.yaml
    

    ここでの出力は次のようになります。

    batchjob.kbatch.k8s.io/[JOB_NAME] created
    
  2. ジョブに関連付けられているポッドを確認します。

    kubectl get pods | grep [JOB_NAME]
    

    次のように出力されます。

    [POD_NAME]   0/1     Completed   0          1m
    

    この出力の代わりに、「No resources found in default namespace.」(デフォルトの名前空間にリソースが見つかりません)と表示される場合は、数秒待ってからコマンドを再試行してください。ポッドが作成されるまで 1 分以上かかることがあります。ジョブが終了すると Pod が約 90 秒後に消え、同じ「No resources...」(リソースなし)という出力がもう一度表示されます。

  3. ログを表示します。

    kubectl logs pod/[POD_NAME]
    

依存関係にあるジョブの実行

依存関係を利用して、前のジョブに関して特定の条件が発生した場合にのみジョブを実行できます。ベータ版は、3 つの依存関係タイプをサポートしています。

成功
依存関係にあるジョブがすべて成功した場合にのみジョブが実行されます。
失敗
依存関係にあるジョブがすべて失敗した場合にのみジョブが実行されます。
完了
依存関係にあるジョブがすべて完了したときにのみジョブが実行されます。

Dependency が満たされないためジョブが実行されないと判断された場合、Batch はジョブを Failed とマークします。たとえば、job1 が job2 に依存し、依存関係タイプが Success の場合、job2 が失敗すると job1 が実行されず、失敗したと見なされます。それ以外の場合、ジョブの失敗と成功は、Kubernetes Pod lifecycle で定義されたジョブに関連付けられたポッドの成功または失敗によって決まります。

このサンプルジョブを実行する前に、GKE クラスタのノードのロケーションと同じゾーンに Google Cloud Filestore インスタンスを設定する必要があります。

  1. Batch サンプル、admintools、usertools を取得して抽出します。他のサンプルジョブで実行済みの場合、この手順はスキップします。

    git clone https://github.com/GoogleCloudPlatform/Kbatch.git
    
    tar -xzvf kbatch-github.tar.gz
    
  2. 「デフォルト」の K8s 名前空間にデフォルトの Batch 管理者リソースを作成します。他のサンプルジョブで実行済みの場合、この手順はスキップします。

    ./samples/defaultresources/create.sh
    
  3. imageprocess フォルダに移動します。

    cd ../imageprocess
    
  4. apply-extra-config.sh を実行して PersistentVolume リソースと権限を作成します。「BatchTasks で root として実行し、ストレージにアクセス」できるかと尋ねられたら「y」と入力します。

    pushd ../userstorage
    ./apply-extra-config.sh
    popd
    
  5. 前の手順で作成した永続ボリューム クレームを使用するように ksub の構成を更新します。

    ./ksub --config --add-volume fs-volume --volume-source PersistentVolumeClaim \
     --params claimName:[PVC_NAME] --params readOnly:false
    

    [PVC_NAME] はステップ 4 で作成した PVC の名前です。この例では、ステップ 4 で pvc という名前の PersistentVolumeClaim が作成されているため、[PVC_NAME]pvc に置き換えます。

  6. copy-input.sh を実行して入力画像を Filestore にコピーします。

ジョブは、ksub または kubectl を使用して送信できます。

ksub

ksub を使用して依存関係にあるジョブを送信する

依存関係を設定してジョブを送信するには、1 つのコマンドで依存関係を指定するか、シェル スクリプトの KB Dependency Success: フィールドを手動で編集します。

ksub で依存関係を指定する

  1. samples/imageprocess から次のコマンドを実行して、依存関係を指定して両方のジョブを実行します。

    ksub --dependency Success:job_name -- run_grey_with_ksub.sh
    

    シェル変数を使用してジョブを接続することもできます。

    ジョブ 1 を作成します。

    job1=`ksub run_checkerboard_with_ksub.sh` \
    

    ジョブ 2 を送信します。

    ksub --dependency Success:${job1} -- ./run_grey_with_ksub.sh
    
  2. タスク名を取得します。

    ksub -Ga [JOB_NAME]
    

    このコマンドはタスク名を出力します。

  3. ログを表示します。

    ksub -L [TASK_NAME]
    
  4. copy-output.sh を実行し、処理された画像をローカルマシンにコピーします。

最初のジョブの名前を使用して依存関係を作成する

  1. ImageProcess Job を送信します。

    ksub run_checkerboard_with_ksub.sh
    

    次のように [JOB_NAME] が出力されます。例:

    checkerboard-64t5n
    

    次の run_grey_with_ksub.sh は、job1 への依存関係を持つ job2 のサンプル スクリプトの内容です。

    #!/bin/sh
    
    #KB Jobname grey-
    #KB Namespace default
    #KB Image gcr.io/kbatch-images/greyimage/greyimage:latest
    #KB Queuename default
    #KB MaxWallTime 5m
    #KB MinCpu 1.0
    #KB MinMemory 2Gi
    #KB Mount fs-volume /mnt/pv
    #KB Dependency Success:[JOB_NAME]
    
    echo "Starting job grey"
    # greyimage is in /app directory.
    cd /app
    ./greyimage -in=/mnt/pv/checker.png -out=/mnt/pv/checkergrey.png
    echo "Completed job grey"
    
  2. 任意のエディタで run_grey_with_ksub.sh を開き、[JOB_NAME] をジョブ名に置き換えます。

  3. 2 番目のジョブを送信する

    ksub run_grey_with_ksub.sh
    

    ジョブ名が出力されます。

  4. タスク名を取得します。

    ksub -Ga [JOB_NAME]
    

    このコマンドはタスク名を出力します。

  5. ログを表示します。

    ksub -L [TASK_NAME]
    
  6. copy-output.sh を実行し、処理された画像をローカルマシンにコピーします。

kubectl

kubectl を使用して依存関係にあるジョブを送信する

  1. ImageProcess Job を送信します。

    kubectl create -f imageprocess-job.yaml
    

    出力は次のようになります。

    batchjob.kbatch.k8s.io/checkerboard created
    batchjob.kbatch.k8s.io/grey created
    
  2. 最初のジョブを確認します。

    kubectl describe batchjob/checkerboard
    
  3. 2 番目のジョブを確認します。

    kubectl describe batchjob/grey
    
  4. copy-output.sh を実行し、処理された画像をローカルマシンにコピーします。

GPU を使用するジョブの実行

  1. Batch サンプル、admintools、usertools を取得して抽出します。他のサンプルジョブで実行済みの場合、この手順はスキップします。

    git clone https://github.com/GoogleCloudPlatform/Kbatch.git
    
    tar -xzvf kbatch-github.tar.gz
    
  2. 「デフォルト」の K8s 名前空間にデフォルトの Batch 管理者リソースを作成します。他のサンプルジョブで実行済みの場合、この手順はスキップします。

    ./samples/defaultresources/create.sh
    

ジョブは、ksub または kubectl を使用して送信できます。

ksub

  1. クラスタで使用できる GPU タイプが samples/GPUjob/run_gpu_with_ksub.sh に指定されていることを確認します。

  2. ジョブを送信します。

    ksub samples/GPUjob/run_gpu_with_ksub.sh
    

    ジョブ名が出力されます。

  3. ジョブが完了するまで待ちます。

    ksub -Gw [JOB_NAME]
    
  4. タスク名を取得します。

    ksub -Ga [JOB_NAME]
    

    このコマンドはタスク名を出力します。

  5. ログを表示します。

    ksub -L [TASK_NAME]
    

gcloud

  1. gpu-job.yaml ファイルに記されている GPU が、オートスケーラー ゾーンで使用できる GPU タイプと一致していることを確認します。

  2. ジョブを送信します。

    kubectl create -f samples/GPUjob/run_gpu_with_ksub.sh
    

    出力は次のようになります。

    batchjob.kbatch.k8s.io/[JOB_NAME] created
    
  3. ログを表示します。

    kubectl describe batchjob/[JOB_NAME]
    

配列ジョブの実行

配列ジョブとは、同じコンテナ イメージを共有し、配列インデックスで区別されるタスクのグループのことです。IndexSpec で「taskCount」を指定すると、最大 1,000 個のタスクを作成できます。

配列ジョブのサンプルを実行するには、入出力用 {product_name_short}} クラスタのノードのロケーションと同じゾーンに Google Cloud Filestore インスタンスを設定する必要があります。filestore インスタンスの作成後、次の手順を実行して配列ジョブのサンプルを実行します。

  1. Batch サンプル、admintools、usertools を取得して抽出します。他のサンプルジョブで実行済みの場合、この手順はスキップします。

    git clone https://github.com/GoogleCloudPlatform/Kbatch.git
    
    tar -xzvf kbatch-github.tar.gz
    
  2. 「デフォルト」の K8s 名前空間にデフォルトの Batch 管理者リソースを作成します。他のサンプルジョブで実行済みの場合、この手順はスキップします。

    ./samples/defaultresources/create.sh
    
  3. arrayjob フォルダに移動します。

      cd ../arrayjob
      

  4. setup.sh を実行して PersistentVolume リソースと権限を作成します。filestore インスタンスの IP、ゾーン、ボリューム名を入力する必要があります。

    ./setup.sh
    

    「BatchTasks で root として実行し、ストレージにアクセス」できるかと聞かれた場合は「y」と入力します。

  5. 前の手順で作成した永続ボリューム クレームを使用するように ksub の構成を更新します。

      ./ksub --config --add-volume fs-volume --volume-source PersistentVolumeClaim 
    --params claimName:[PVC_NAME] --params readOnly:false

    [PVC_NAME] はステップ 4 で作成した PVC の名前です。この例では、ステップ 4 で pvc という名前の PersistentVolumeClaim が作成されているため、[PVC_NAME]pvc に置き換えます。

  6. copy-array-input.sh を実行して入力画像を Filestore にコピーします。

    ./copy-array-input.sh
    

    入力ファイルは、PVC の下にある array-image-data ディレクトリにコピーされます。

  7. ksub を使用して配列ジョブを送信します。

    ksub ./run_array_image_ksub.sh`
    

    別の方法では、yaml ファイルを使い、kubectl create -f array-image.yaml を実行して配列ジョブを送信することもできます。

  8. 配列ジョブのステータスを、前の手順で生成したジョブ名により確認します。

    ksub -Ga [JOB_NAME],/var> --output=wide
    
    または
    ksub -G [JOB_NAME],/var> --output=describe
    

    ジョブが正常に終了すると、出力ファイルは PVC の下にある array-image-data ディレクトリに保存されます。

    出力データをローカルマシンにコピーするには、次のコマンドを実行します。

    ./copy-array-output.sh
    

    確認するには、array-image-data ディレクトリに移動します。各入力ファイルには対応する出力ファイルがあります。

ジョブの送信

ジョブは、ksub または kubectl を使用して送信できます。

ksub の使用

ksub ではジョブとしてスクリプトを送信できます。#KB の接頭辞を持つキーワードを使用してジョブのプロパティを指定できます。

次の run_pi_with_ksub.sh は、サンプルの ksub ジョブの内容です。

#!/bin/sh

# Keywords to specify job parameters

#KB Jobname pi-
#KB Namespace default
#KB Image gcr.io/kbatch-images/generate-pi/generate-pi:latest
#KB Queuename default
#KB MaxWallTime 5m
#KB MinCpu 1.0
#KB MinMemory 2Gi

echo "Starting job pi"
# pi is in /app directory.
cd /app
./pi
echo "Completed job pi"

スクリプトを送信するには、次のコマンドを実行します。

ksub run_pi_with_ksub.sh

ksub キーワードの指定

キーワードを使用してジョブのパラメータを指定します。これらのキーワードには #KB の接頭辞が付きます。ksub では、不要な改行や空白文字を含めず、ブロック行でキーワードを指定することになっています。#KB で始まらない行に達すると、ksub はキーワードの解析をストップします。

ksub は以下のキーワードをサポートしています。

キーワード コメント
Jobname ジョブ名の生成に使用されるジョブ名接頭辞。 #KB Jobname pi-
Namespace ジョブが実行される名前空間。 #KB Namespace default
Queuename ジョブが送信されるキュー。 #KB Queuename default
Image ジョブコンテナを実行するイメージ。 #KB Image ubuntu
Mount マウントする PVC およびマウントする場所。 #KB Mount fs-volume /tmp
MinCpu ジョブに必要な CPU の数。 #KB MinCpu 1.0
MinMemory コンテナに必要なメモリ の量。 #KB MinMemory 2Gi
Gpu ジョブに必要な GPU の数とタイプ。右側の例では nvidia-tesla-k80 は使用される GPU のタイプで、「2」は使用される GPU の数です。 #KB GPU nvidia-tesla-k80 2
Dependency ジョブの依存関係 #KB Dependency Success:job-name1
MaxWallTime ジョブの最大実行時間 #KB MaxWallTime 5m
TaskCount 配列ジョブのタスク数(最大 1,000 件) #KB TaskCount 10

kubectl の使用

kubectl はクラスタの Kubernetes 構成を使用して Batch システムに接続します。

次の pi-job.yaml は、サンプルの YAML ジョブの内容です。

apiVersion: kbatch.k8s.io/v1beta1
kind: BatchJob
metadata:
  generateName: pi-  # generateName allows the system to generate a random name, using this prefix, for the BatchJob upon creation.
  namespace: default
spec:
  batchQueueName: default
  taskGroups:
  - name: main
    maxWallTime: 5m
    template:
      spec:
        containers:
        - name: pi
          # This image has been made public so it can be pulled from any project.
          image: gcr.io/kbatch-images/generate-pi/generate-pi:latest
          resources:
            requests:
              cpu: 1.0
              memory: 2Gi
            limits:
              cpu: 1.0
              memory: 2Gi
          imagePullPolicy: IfNotPresent
        restartPolicy: Never

ジョブを送信するには、次のコマンドを実行します。

kubectl create -f pi-job.yaml

データの管理

  1. ユーザーツールを取得します。

    git clone https://github.com/GoogleCloudPlatform/Kbatch.git
    
  2. モニタリングするディレクトリに移動します。

    cd usertools/filestore
    

Batch on GKE には、Kubernetes PersistentVolume との間でファイルコピーするためのユーティリティがあります。

このスクリプトの基本的な使い方は次のとおりです。

./datacopy.sh [-d|-u] -l [LOCAL_FILE] -r [REMOTE_FILE_PATH] -p [PVC_NAME]

ここで

  • -u は、ワークステーションからクラウドにデータをコピーします。
  • -d は、クラウドからワークステーションにデータをコピーします。
  • -h は、使い方の簡単な説明を出力します。

たとえば、入力ファイル input.dat がローカルマシンのカレント ディレクトリにあり、このファイルを使用してジョブを実行する場合は、次のコマンドを入力すると、入力ファイルを自分専用の Batch ディレクトリにコピーできます。

./datacopy.sh -u -l input.dat -r problem-1-input.data -p [NAME]-team1

ジョブの表示

ジョブは、ksub または kubectl を使用して表示できます。

ksub

キューにある特定のユーザーのジョブを表示する

特定のユーザーのジョブを表示するには、次のコマンドを実行します。

ksub -Q -n [NAMESPACE] [QUEUE_NAME]

最初の [NAMESPACE] は名前空間で、[QUEUE_NAME] はキュー名です。

出力は次のようになります。

Name: pi-s4dwl, Status: Succeeded

キュー内のジョブを表示する

キュー内のジョブを表示するには、次のコマンドを実行します。

ksub -Qa -n [NAMESPACE] [QUEUE_NAME]

最初の [NAMESPACE] は名前空間で、[QUEUE_NAME] はキュー名です。

出力は次のようになります。

Name: pi-s4dwl, Creation Time Stamp: 2019-09-12 13:03:42 -0700 PDT, Status: Succeeded

kubectl

キュー内のジョブを表示する

キュー内のジョブを表示するには、次のコマンドを実行します。

kubectl get batchjobs --selector=batchQueue=[QUEUE_NAME] --namespace [NAMESPACE]

[QUEUE_NAME] はキュー名、[NAMESPACE] は名前空間です。

出力は次のようになります。

NAME       AGE
pi-6rc7s   2m

特定のユーザーのジョブを表示する

特定のユーザーのジョブを表示するには、次の手順を実行します。

  1. ユーザー名を取得します。

    gcloud config get-value account
    

    出力は次のようになります。

    user@company.com
    
  2. 特定のユーザーの Namespace に属するジョブを一覧表示するには、次のコマンドを実行します。

    kubectl get batchjobs --selector=submittedBy=[userATexample.com] --namespace [NAMESPACE]
    

    --selector=submittedBy は emailATcompany.com で、[NAMESPACE] は名前空間です。

    出力は次のようになります。

    NAME       AGE
    pi-6rc7s   36m
    
  3. 特定のユーザーがキューに送信したジョブのリストを一覧表示するには、次のコマンドを実行します。

    kubectl get batchjobs --selector=batchQueue=[QUEUE_NAME],submittedBy=[userATexample.com] --namespace [NAMESPACE]
    

    [QUEUE_NAME] はキュー名、emailATcompany.com[NAMESPACE] は名前空間です。

    出力は次のようになります。

    NAME       AGE
    pi-6rc7s   36m
    

ジョブの停止

実行中のジョブを停止するには、ksub または kubectl を使用します。ジョブは「JobTerminationByUser」という状態で「Failed」とマークされ、ジョブ関連の履歴データは保持されます。

ksub

ジョブを停止するには次のコマンドを実行します。

ksub -T [JOB_NAME] -n [NAMESPACE]

[JOB_NAME] は Job 名、[NAMESPACE] は名前空間です。

出力は次のようになります。

Termination request for job [JOB_NAME] is sent to the server, please check the job status

次のコマンドを実行して、ジョブが完了するまで監視することもできます。

ksub -Gw [JOB_NAME] -n [NAMESPACE]

kubectl

実行中のジョブを停止させるには、次のコマンドを実行します。

kubectl patch batchjob [JOB_NAME] --namespace [NAMESPACE] --type merge --patch '{"spec": {"userCommand": "Terminate"}}'

[JOB_NAME] は Job 名、[NAMESPACE] は名前空間です。

出力は次のようになります。

batchjob.kbatch.k8s.io/[JOB_NAME] patched

ジョブのログの表示

ジョブのログを表示できるのは、ジョブの実行が開始された後(つまり、ジョブがキュー待機状態から実行中の状態に移行した場合)のみです。ログを表示する前に、ジョブが開始されるまで待つ必要があります。

ジョブのログを取得するには、次のコマンドを実行します。

ksub -L -n [NAMESPACE] [JOB_NAME]

[NAMESPACE] は名前空間、[JOB_NAME] はジョブ名です。

トラブルシューティング

BatchTask が長期間「Ready」状態になった場合は、クラスタ管理者は Cloud Console の [ワークロード] タブに移動して対応する Pod を確認できます。

GKE 1.14 では、ネットワークの設定の問題により、Pod が「ContainerCreating」ステージで停止することがあるという既知の問題があります。この場合、ジョブを終了して再送信できます。この問題は、GKE 1.15 のリリースで修正される予定です。

GKE のラベルに関する新しい制限により、ジョブを適切に実行するため、v0.9.1 以降の Batch on GKE を使用してください。

次のステップ