えいのうにっき

a-knowの日記です

Kubernetes での少し特殊なユースケースでの Pod の作成方法・DaemonSet と Job (入門k8s 読書メモ)

入門 Kubernetes の読書メモ、第5弾。

入門 Kubernetes

入門 Kubernetes

DaemonSet

DaemonSet の必要性

  • ある種のエージェントやデーモンなどを、Kuberenetes クラスタを構成する各ノード上で動作させたいというユースケースがある
  • 特定ノードへの割り当てを制限したり、Pod が同じノード上に配置されないようにパラメータを調整することを ReplicaSet でおこなうことは推奨されない。
  • このようなユースケースの際に利用できるのが DaemonSet。

DaemonSet スケジューラ

  • DaemonSet による Pod の作成・管理は、Kubernetes スケジューラではなく、DaemonSet スケジューラ・コントローラがおこなう。
  • どのノードに Pod を作成するかは、Pod の定義の nodeName フィールドの値に従う。
$ kubectl get pods <pod-name> -o yaml | grep nodeName
  nodeName: xxxxx

DaemonSet の作成

  • DaemonSet の作成は、kind: DaemonSet によりおこなう。Pod のテンプレートが必要な点も ReplicaSet と同じ。
  • DaemonSet は、Kubernetes の Namespace 内でのすべての DaemonSet に対して一意な名前が付けられている必要がある。

特定ノードに対する DaemonSet の割り当ての制限

  • DaemonSet では、ノードセレクタを使わない限り、全ノードに Pod が作られる。
  • ただ、特定のノードの集合にだけ特定の Pod をデプロイしたい、というユースケースも考えられる。
    • クラスタ内の特定ノードにしか接続されていないハードウェアを使用するワークロードがある場合、など。
  • ノードに対する Label を使用することで対応可能。
    • kubectl label nodes <node-name> key=value
  • そして、ノードセレクタを用いることで Pod のデプロイ先を制限できる。
    • ノードから対象の Label が削除されると、調整ループによりそのノードから Pod は削除される。
spec:
  template:
    metadata:
      labels:
        app: nginx
        ssd: true
    spec:
      nodeSelector:
        ssd: true
      containers:
        - name: nginx
          image: nginx:1.10.0

DaemonSet コンテナのアップグレード

個別の Pod の削除による DaemonSet の更新

  • DaemonSet による Pod を何秒かおきに順番に削除していくようなスクリプトを書き、調整ループによる新規 Pod の作成を図る方法。
  • DaemonSet 自体を削除し、その後新しい DaemonSet を新しい設定で作成する方法。
    • ダウンタイムは避けられない。

ローリングアップデート

  • spec.updateStrategy.type フィールドを RollingUpdate にしておくと、spec.template フィールドに変更があったときにローリングアップデートが開始される。
  • DaemonSet のローリングアップデートを制御するパラメータが2つある
    • spec.minReadySeconds
      • ローリングアップデートが次の Pod の更新に移る前に、Pod が使用可能な状態になるまでの時間。
    • spec.updateStrategy.rollingUpdate.maxU_navailable
      • ローリングアップデートの際に使用不可能になってもよい Pod の数(同時に更新がおこなわれる Pod の数)。
  • ローリングアップデートの状態は kubectl rollout status daemonsts <daemonset-name> で確認可能。

Job

Job オブジェクトの必要性

  • ReplicaSet, DaemonSet などは、データベースやWebアプリケーション、監視エージェントなど、長時間(基本的にはずっと・アップグレードするか不要になるまで)動き続けるプロセスに焦点を当てたもの。
  • 一方で、Job オブジェクトは、バッチ処理など、短時間だけ動かすタスクを扱うもの。
  • Job は、処理が正常終了する(終了コード 0 での終了など)まで動く Pod を作成する。

Job オブジェクト

  • Jobオブジェクトは、その他のオブジェクトと同じく、マニフェストに書かれた Pod テンプレートで定義された Pod の作成や管理をおこなうもの。
    • 特徴として、そのPod は処理が成功するまで動き続ける
      • 失敗した場合、Job コントローラは Pod テンプレートを元に新しい Pod を作成する。
    • 複数の Pod を並列に動かすための調整もおこなうことができる。
  • 「Job の失敗」は、「コンテナが 0 以外の戻り値で終了する」「処理の途中で止まってしまい、それ以降動かなくなる」といったパターンがある
  • 注意点としては、
    • Pod はどこかのノードに割り当てる必要があり、必要なリソースを見つけられない場合も考えられるため、そのような場合には Job がすぐに実行されない可能性もある。
    • 分散システムの性質上、同じタスクを実行する Pod が複数作られることもある。
      • 【疑問】これは、parallelism のパラメータによらず、複数作られてしまうこともある、という意味であるという理解でよいか?
  • Job が完了しても、ログ出力を確認できるようにするため、Job オブジェクトとそれに関連する Pod は残る。
    • kubectl get pods -a などで確認できる

Job のパターン

  • Job は、その設定の completionsparallelism により、以下のようないくつかのパターンのワークロードに対応できる。
completions parallelism 動作 パターン 使用例
1 1 1つの Pod が処理 1回限り データベースマイグレーションのようなもの
1以上 1以上 指定回数成功するまで、1つ以上の Pod が複数回処理 一定数成功するまで並列実行 複数の Pod でタスクの集まりを並列処理するようなもの
1 2以上 1回成功するまで複数の Pod が処理 並列処理実行キュー 集約されたキューに入れられたタスクを複数の Pod で処理するようなもの

「1回限り」パターン

  • kind: Job spec.template.spec.restartPolicy: OnFailure で作成可能
    • restartPolicy: OnFailure とすることで、Job(コンテナ)の処理が失敗した際に Pod が自動的に再起動される
      • Job ではなく kubelet によりおこなわれる
    • restartPolicy: Never とすると、Job 失敗時、kubelet は Pod を再起動せず、失敗と宣言する(STATUS が Error)
      • これを Job オブジェクトが検知すると、代わりの Pod を作成する。

「一定数成功するまで並列実行」パターン

  • kind: Job spec.parallelism: 5 spec.completion: 10 spec.template.spec.restartPolicy: OnFailure などで作成

「並列処理実行キュー」パターン

  • kind: Job spec.parallelism: 5 spec.template.spec.restartPolicy: OnFailure などで作成
    • spec.completion は指定しなければデフォルト 1

入門 Kubernetes

入門 Kubernetes