k8sのJobコントローラー

kubernetesには、podの稼働を制御するコントローラーの機能があり、DeploymentやDaemonsetといったコントローラーが主に知られています。Jobもコントローラーの一種で、バッチ処理用途の機能を持ちます。目的のジョブを実行するときだけpod起動する点が特徴で、失敗時のリトライやタイムアウトなどの設定を追加できます。

Jobの実行方法

Jobの起動方法は、他のコントローラーと同様、kubectlで実行できます。

$ kubectl create -f some_job.yaml

なお、Jobは実行完了後にjobとpodが消えずに残ります。この挙動の意図は、実行状況のログを確認するためとのことです。状況を確認したら、deleteします。

$ kubectl delete -f some_job.yaml

近未来には spec.ttlSecondsAfterFinished というオプションを設定に追加することで完了後に自動でクリーンアップする挙動が導入される予定です。k8s v1.12でAlphaステータスであり、Docker for Macのk8sがv1.10ということもあり、仕様がGAになるまで待つことになりそうです。

当面はジョブのリソースがCompletedで残ってしまう点につき運用を検討してみたのですが、現状手軽なのは毎回何も考えずに kubectl delete → kubectl create の2コマンドを連続実行することでしょう。

前回のJobが存在しない場合にはkubectl deleteはエラーになりますが、存在しないリソースの削除失敗に実害はありません。また、ジョブ実行後のpodについては気にせず放置となりますが、開発環境などでは実害はないでしょう。まじめに対応するならジョブの終了判定処理を開発することになりますが、非同期処理であるためそれなりの手間がかかると思います。

Jobの設定ファイル

Jobの設定ファイルの記載例は以下のようなものになります(抜粋)。

apiVersion: batch/v1
kind: Job
metadata:
  name: ridgepole
spec:
  template:
    metadata:
      name: ridgepole
    spec:
      containers:
      - name: ridgepole
        image: uniqrn/rails:5.2
        imagePullPolicy: IfNotPresent
        command: ["ridgepole"]
        args: ["-c", "database.yml", "-f", "Schemafile", "-a", "-E", "development"]
      restartPolicy: Never

この例では、ridgepoleを利用してRDBMSのスキーマを更新する処理を実行します。いくつかJob特有のキーワードがありますが、Jobを利用する際の主題は、commandとargsです。

Jobでは、コンテナイメージ内のコマンドやスクリプトを実行することになりますが、commandとargsの組み合わせで対象を指定します。

まとめ

結論として、定常稼働しないジョブについてはJobコントローラーを実装する、という方針で良さそうです。Deploymentなどで実装するテクニックもあるのですが、何もしないコンテナを起動させ続ける構成はリソースの使い方に無駄があります。

Jobコントローラーでは、起動時にコンテナ用のリソースが逼迫して確保できないというケースが起こり得ますが、この場合、稼働中のコンテナの安定性も犠牲になっているので、kubernetesのクラスタをギリギリのリソースで運用すること自体を避けるべきでしょう。

なお、本記事ではJobの基礎的な理解を優先してrestartPolicyなどサービスレベル設定について説明を割愛しました。公式ドキュメントの Job – Run to completionに利用例などを含め詳細な解説がまとまっており、参考になります。