第4章 ジョブと DeamonSet の使用
4.1. デーモンセットによるノード上でのバックグラウンドタスクの自動的な実行
管理者は、デーモンセットを作成して OpenShift Container Platform クラスター内の特定の、またはすべてのノードで Pod のレプリカを実行するために使用できます。
デーモンセットは、すべて (または一部) のノードで Pod のコピーが確実に実行されるようにします。ノードがクラスターに追加されると、Pod がクラスターに追加されます。ノードがクラスターから削除されると、Pod はガベージコレクションによって削除されます。デーモンセットを削除すると、デーモンセットによって作成された Pod がクリーンアップされます。
デーモンセットを使用して共有ストレージを作成し、クラスター内のすべてのノードでロギング Pod を実行するか、またはすべてのノードでモニターエージェントをデプロイできます。
セキュリティー上の理由から、クラスター管理者とプロジェクト管理者がデーモンセットを作成できます。
デーモンセットについての詳細は、Kubernetes ドキュメント を参照してください。
デーモンセットのスケジューリングにはプロジェクトのデフォルトノードセレクターとの互換性がありません。これを無効にしない場合、デーモンセットはデフォルトのノードセレクターとのマージによって制限されます。これにより、マージされたノードセレクターで選択解除されたノードで Pod が頻繁に再作成されるようになり、クラスターに不要な負荷が加わります。
4.1.1. デフォルトスケジューラーによるスケジュール
デーモンセットは、適格なすべてのノードで Pod のコピーが確実に実行されるようにします。通常は、Pod が実行されるノードは Kubernetes のスケジューラーが選択します。ただし、これまでデーモンセット Pod はデーモンセットコントローラーが作成し、スケジュールしていました。その結果、以下のような問題が生じています。
-
Pod の動作に一貫性がない。スケジューリングを待機している通常の Pod は、作成されると Pending 状態になりますが、デーモンセット Pod は作成されても
Pending
状態になりません。これによりユーザーに混乱が生じます。 - Pod のプリエンプションがデフォルトのスケジューラーで処理される。プリエンプションが有効にされると、デーモンセットコントローラーは Pod の優先順位とプリエンプションを考慮することなくスケジューリングの決定を行います。
ScheduleDaemonSetPods 機能は、OpenShift Container Platform でデフォルトで有効にされます。これにより、spec.nodeName
の条件 (term) ではなく NodeAffinity
の条件 (term) をデーモンセット Pod に追加することで、デーモンセットコントローラーではなくデフォルトのスケジューラーを使ってデーモンセットをスケジュールすることができます。その後、デフォルトのスケジューラーは、Pod をターゲットホストにバインドさせるために使用されます。デーモンセット Pod のノードアフィニティーがすでに存在する場合、これは置き換えられます。デーモンセットコントローラーは、デーモンセット Pod を作成または変更する場合にのみこれらの操作を実行し、デーモンセットの spec.template
は一切変更されません。
nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchFields: - key: metadata.name operator: In values: - target-host-name
さらに、node.kubernetes.io/unschedulable:NoSchedule
の容認がデーモンセット Pod に自動的に追加されます。デフォルトのスケジューラーは、デーモンセット Pod をスケジュールする際に、スケジュールできないノードを無視します。
4.1.2. デーモンセットの作成
デーモンセットの作成時に、nodeSelector
フィールドは、デーモンセットがレプリカをデプロイする必要のあるノードを指定するために使用されます。
前提条件
デーモンセットの使用を開始する前に、namespace のアノテーション
openshift.io/node-selector
を空の文字列に設定することで、namespace のプロジェクトスコープのデフォルトのノードセレクターを無効にします。$ oc patch namespace myproject -p \ '{"metadata": {"annotations": {"openshift.io/node-selector": ""}}}'
ヒントまたは、以下の YAML を適用して、プロジェクト全体で namespace のデフォルトのノードセレクターを無効にすることもできます。
apiVersion: v1 kind: Namespace metadata: name: <namespace> annotations: openshift.io/node-selector: ''
新規プロジェクトを作成している場合は、デフォルトのノードセレクターを上書きします。
$ oc adm new-project <name> --node-selector=""
手順
デーモンセットを作成するには、以下を実行します。
デーモンセット yaml ファイルを定義します。
apiVersion: apps/v1 kind: DaemonSet metadata: name: hello-daemonset spec: selector: matchLabels: name: hello-daemonset 1 template: metadata: labels: name: hello-daemonset 2 spec: nodeSelector: 3 role: worker containers: - image: openshift/hello-openshift imagePullPolicy: Always name: registry ports: - containerPort: 80 protocol: TCP resources: {} terminationMessagePath: /dev/termination-log serviceAccount: default terminationGracePeriodSeconds: 10
デーモンセットオブジェクトを作成します。
$ oc create -f daemonset.yaml
Pod が作成されていることを確認し、各 Pod に Pod レプリカがあることを確認するには、以下を実行します。
daemonset Pod を検索します。
$ oc get pods
出力例
hello-daemonset-cx6md 1/1 Running 0 2m hello-daemonset-e3md9 1/1 Running 0 2m
Pod がノードに配置されていることを確認するために Pod を表示します。
$ oc describe pod/hello-daemonset-cx6md|grep Node
出力例
Node: openshift-node01.hostname.com/10.14.20.134
$ oc describe pod/hello-daemonset-e3md9|grep Node
出力例
Node: openshift-node02.hostname.com/10.14.20.137
- デーモンセット Pod テンプレートを更新しても、既存の Pod レプリカには影響はありません。
- デーモンセットを削除してから、異なるテンプレートと同じラベルセレクターを使用して新規のデーモンセットを作成する場合に、既存の Pod レプリカについてラベルが一致していると認識するため、既存の Pod レプリカは更新されず、Pod テンプレートで一致しない場合でも新しいレプリカが作成されます。
- ノードのラベルを変更する場合には、デーモンセットは新しいラベルと一致するノードに Pod を追加し、新しいラベルと一致しないノードから Pod を削除します。
デーモンセットを更新するには、古いレプリカまたはノードを削除して新規の Pod レプリカの作成を強制的に実行します。