Change:
This is a Feature Request <!-- Please only use this template for submitting feature/enhancement requests --<!-- See for guidance on writing an actionable issue description. --What would you like to be <!-- Describe as precisely as possible how this feature/enhancement should work from the user perspective. What should be changed, etc. --Updated Japanese translation for the file. Why is this needed There are several updates in and therefore this page is outdated. Comments <!-- Any additional related comments that might help. Drawings/mockups would be extremely helpful (if required). --/language ja /assign
This issue is currently awaiting triage. SIG Docs takes a lead on issue triage for this website, but any Kubernetes member can accept issues by applying the label. The label can be by org members by writing in a comment. <detailsInstructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details

Discussion:
<!-- overview --> <del> {{< glossary_tooltip text="Pod" term_id="pod" >}}が稼働する{{< glossary_tooltip text="Node" term_id="node" >}}を特定のものに指定したり、優先条件を指定して制限することができます。 これを実現するためにはいくつかの方法がありますが、推奨されている方法は[ラベルでの選択](/ja/docs/concepts/overview/working-with-objects/labels/)です。 スケジューラーが最適な配置を選択するため、一般的にはこのような制限は不要です(例えば、複数のPodを別々のNodeへデプロイしたり、Podを配置する際にリソースが不十分なNodeにはデプロイされないことが挙げられます)が、 SSDが搭載されているNodeにPodをデプロイしたり、同じアベイラビリティーゾーン内で通信する異なるサービスのPodを同じNodeにデプロイする等、柔軟な制御が必要なこともあります。 </del> <ins> {{< glossary_tooltip text="Pod" term_id="pod" >}}を特定の{{< glossary_tooltip text="Node" term_id="node" >}}で実行するように _制限_ したり、特定のNodeで実行することを _優先_ させたりといった制約をかけることができます。 これを実現するためにはいくつかの方法がありますが、推奨されている方法は、すべて[ラベルセレクター](/ja/docs/concepts/overview/working-with-objects/labels/)を使用して選択を容易にすることです。 多くの場合、このような制約を設定する必要はなく、{{< glossary_tooltip text="スケジューラー" term_id="kube-scheduler" >}}が自動的に妥当な配置を行います(例えば、Podを複数のNodeに分散させ、空きリソースが十分でないNodeにPodを配置しないようにすることができます)。 しかし、例えばSSDが接続されているNodeにPodが配置されるようにしたり、多くの通信を行う2つの異なるサービスのPodを同じアベイラビリティーゾーンに配置したりする等、どのNodeに配置するかを制御したい状況もあります。 <!-- body --> Kubernetesが特定のPodの配置場所を選択するために、以下の方法があります: </ins> <del> <!-- body --> </del> <ins> * [nodeラベル](#built-in-node-labels)に対してマッチングを行う[nodeSelector](#nodeselector)フィールド * [アフィニティとアンチアフィニティ](#affinity-and-anti-affinity) * [nodeName](#nodename)フィールド * [Podのトポロジー分散制約](#pod-topology-spread-constraints) </ins> <del> ## nodeSelector </del> <ins> ## Nodeラベル {#built-in-node-labels} </ins> <del> `nodeSelector`は、Nodeを選択するための、最も簡単で推奨されている手法です。 `nodeSelector`はPodSpecのフィールドです。これはkey-valueペアのマップを特定します。 あるノードでPodを稼働させるためには、そのノードがラベルとして指定されたkey-valueペアを保持している必要があります(複数のラベルを保持することも可能です)。 最も一般的な使用方法は、1つのkey-valueペアを付与する方法です。 </del> <ins> 他の多くのKubernetesオブジェクトと同様に、Nodeにも[ラベル](/ja/docs/concepts/overview/working-with-objects/labels/)があります。[手動でラベルを付ける](/ja/docs/tasks/configure-pod-container/assign-pods-nodes/#ラベルをNodeに追加する)ことができます。 また、Kubernetesはクラスター内のすべてのNodeに対し、いくつかの標準ラベルを付けます。Nodeラベルの一覧については[よく使われるラベル、アノテーションとtaint](/docs/reference/labels-annotations-taints/)を参照してください。 </ins> <del> 以下に、`nodeSelector`の使用例を紹介します。 </del> <ins> {{<note>}} これらのラベルの値はクラウドプロバイダー固有のもので、信頼性を保証できません。 例えば、`kubernetes.io/hostname`の値はある環境ではNode名と同じになり、他の環境では異なる値になることがあります。 {{</note>}} </ins> <del> ### ステップ0: 前提条件 </del> <ins> ### Nodeの分離/制限 </ins> <del> この例では、KubernetesのPodに関して基本的な知識を有していることと、[Kubernetesクラスターのセットアップ](/ja/docs/setup/)がされていることが前提となっています。 </del> <ins> Nodeにラベルを追加することで、Podを特定のNodeまたはNodeグループ上でのスケジューリングの対象にすることができます。この機能を使用すると、特定のPodが一定の独立性、安全性、または規制といった属性を持ったNode上でのみ実行されるようにすることができます。 </ins> <del> ### ステップ1: Nodeへのラベルの付与 </del> <ins> Node分離するのにラベルを使用する場合、{{<glossary_tooltip text="kubelet" term_id="kubelet">}}が修正できないラベルキーを選択してください。 これにより、侵害されたNodeが自身でそれらのラベルを設定することで、スケジューラーがそのNodeにワークロードをスケジュールしてしまうのを防ぐことができます。 </ins> <del> `kubectl get nodes`で、クラスターのノードの名前を取得してください。 そして、ラベルを付与するNodeを選び、`kubectl label nodes <node-name> <label-key>=<label-value>`で選択したNodeにラベルを付与します。 例えば、Nodeの名前が'kubernetes-foo-node-1.c.a-robinson.internal'、付与するラベルが'disktype=ssd'の場合、`kubectl label nodes kubernetes-foo-node-1.c.a-robinson.internal disktype=ssd`によってラベルが付与されます。 </del> <ins> [`NodeRestriction`アドミッションプラグイン](/docs/reference/access-authn-authz/admission-controllers/#noderestriction)は、kubeletが`node-restriction.kubernetes.io/`というプレフィックスを持つラベルを設定または変更するのを防ぎます。 </ins> <del> `kubectl get nodes --show-labels`によって、ノードにラベルが付与されたかを確認することができます。 また、`kubectl describe node "nodename"`から、そのNodeの全てのラベルを表示することもできます。 </del> <ins> ラベルプレフィックスをNode分離に利用するには: </ins> <del> ### ステップ2: PodへのnodeSelectorフィールドの追加 </del> <ins> 1. [Node認可](/docs/reference/access-authn-authz/node/)を使用していることと、`NodeRestriction` アドミッションプラグインが _有効_ になっていることを確認します。 2. `node-restriction.kubernetes.io/`プレフィックスを持つラベルをNodeに追加し、 [nodeSelector](#nodeselector)でそれらのラベルを使用します。 例えば、`example.com.node-restriction.kubernetes.io/fips=true`や`example.com.node-restriction.kubernetes.io/pci-dss=true`などです。 </ins> <del> 該当のPodのconfigファイルに、nodeSelectorのセクションを追加します: 例として以下のconfigファイルを扱います: </del> <ins> ## nodeSelector {#nodeselector} </ins> <del> ```yaml apiVersion: v1 kind: Pod metadata: name: nginx labels: env: test spec: containers: - name: nginx image: nginx ``` </del> <ins> `nodeSelector`は、Node選択制約の中で最もシンプルな推奨形式です。 Podのspec(仕様)に`nodeSelector`フィールドを追加することで、ターゲットNodeが持つべき[Nodeラベル](#built-in-node-labels)を指定できます。 Kubernetesは指定された各ラベルを持つNodeにのみ、Podをスケジューリングします。 詳しい情報については[PodをNodeに割り当てる](/ja/docs/tasks/configure-pod-container/assign-pods-nodes/)を参照してください。 </ins> <del> nodeSelectorを以下のように追加します: </del> <ins> ## アフィニティとアンチアフィニティ {#affinity-and-anti-affinity} </ins> <del> {{< codenew file="pods/pod-nginx.yaml" >}} </del> <ins> `nodeSelector`はPodを特定のラベルが付与されたNodeに制限する最も簡単な方法です。 アフィニティとアンチアフィニティでは、定義できる制約の種類が拡張されています。 アフィニティとアンチアフィニティのメリットは以下の通りです。 </ins> <del> `kubectl apply -f https://k8s.io/examples/pods/pod-nginx.yaml`により、Podは先ほどラベルを付与したNodeへスケジュールされます。 `kubectl get pods -o wide`で表示される"NODE"の列から、PodがデプロイされているNodeを確認することができます。 </del> <ins> * アフィニティとアンチアフィニティで使われる言語は、より表現力が豊かです。`nodeSelector`は指定されたラベルを全て持つNodeを選択するだけです。アフィニティとアンチアフィニティは選択ロジックをより細かく制御することができます。 * ルールが*柔軟*であったり*優先*での指定ができたりするため、一致するNodeが見つからない場合でも、スケジューラーはPodをスケジュールします。 * Node自体のラベルではなく、Node(または他のトポロジカルドメイン)上で稼働している他のPodのラベルを使ってPodを制約することができます。これにより、Node上にどのPodを共存させるかのルールを定義することができます。 </ins> <del> ## 補足: ビルトインNodeラベル {#built-in-node-labels} </del> <ins> アフィニティ機能は、2種類のアフィニティで構成されています: </ins> <del> 明示的に[付与](#step-one-attach-label-to-the-node)するラベルの他に、事前にNodeへ付与されているものもあります。 これらのラベルのリストは、[Well-Known Labels, Annotations and Taints](/docs/reference/kubernetes-api/labels-annotations-taints/)を参照してください。 </del> <ins> * *Nodeアフィニティ*は`nodeSelector`フィールドと同様に機能しますが、より表現力が豊かで、より柔軟にルールを指定することができます。 * *Pod間アフィニティとアンチアフィニティ*は、他のPodのラベルを元に、Podを制約することができます。 </ins> <del> {{< note >}} これらのラベルは、クラウドプロバイダー固有であり、確実なものではありません。 例えば、`kubernetes.io/hostname`の値はNodeの名前と同じである環境もあれば、異なる環境もあります。 {{< /note >}} </del> <ins> ### Nodeアフィニティ {#node-affinity} Nodeアフィニティは概念的には、NodeのラベルによってPodがどのNodeにスケジュールされるかを制限する`nodeSelector`と同様です。 </ins> <del> ## Nodeの隔離や制限 Nodeにラベルを付与することで、Podは特定のNodeやNodeグループにスケジュールされます。 これにより、特定のPodを、確かな隔離性や安全性、特性を持ったNodeで稼働させることができます。 この目的でラベルを使用する際に、Node上のkubeletプロセスに上書きされないラベルキーを選択することが強く推奨されています。 これは、安全性が損なわれたNodeがkubeletの認証情報をNodeのオブジェクトに設定したり、スケジューラーがそのようなNodeにデプロイすることを防ぎます。 </del> <ins> Nodeアフィニティには2種類あります: </ins> <del> `NodeRestriction`プラグインは、kubeletが`node-restriction.kubernetes.io/`プレフィックスを有するラベルの設定や上書きを防ぎます。 Nodeの隔離にラベルのプレフィックスを使用するためには、以下のようにします。 </del> <ins> * `requiredDuringSchedulingIgnoredDuringExecution`: スケジューラーは、ルールが満たされない限り、Podをスケジュールすることができません。これは`nodeSelector`と同じように機能しますが、より表現力豊かな構文になっています。 * `preferredDuringSchedulingIgnoredDuringExecution`: スケジューラーは、対応するルールを満たすNodeを探そうとします。 一致するNodeが見つからなくても、スケジューラーはPodをスケジュールします。 </ins> <del> 1. [Node authorizer](/docs/reference/access-authn-authz/node/)を使用していることと、[NodeRestriction admission plugin](/docs/reference/access-authn-authz/admission-controllers/#noderestriction)が _有効_ になっていること。 2. Nodeに`node-restriction.kubernetes.io/` プレフィックスのラベルを付与し、そのラベルがnode selectorに指定されていること。 例えば、`example.com.node-restriction.kubernetes.io/fips=true` または `example.com.node-restriction.kubernetes.io/pci-dss=true`のようなラベルです。 </del> <ins> {{<note>}} 上記の2種類にある`IgnoredDuringExecution`は、KubernetesがPodをスケジュールした後にNodeラベルが変更されても、Podは実行し続けることを意味します。 {{</note>}} </ins> <del> ## アフィニティとアンチアフィニティ {#affinity-and-anti-affinity} </del> <ins> Podのspec(仕様)にある`.spec.affinity.nodeAffinity`フィールドを使用して、Nodeアフィニティを指定することができます。 </ins> <del> `nodeSelector`はPodの稼働を特定のラベルが付与されたNodeに制限する最も簡単な方法です。 アフィニティ/アンチアフィニティでは、より柔軟な指定方法が提供されています。 拡張機能は以下の通りです。 </del> <ins> 例えば、次のようなPodのspec(仕様)を考えてみましょう: </ins> <del> 1. アフィニティ/アンチアフィニティという用語はとても表現豊かです。この用語は論理AND演算で作成された完全一致だけではなく、より多くのマッチングルールを提供します。 2. 必須条件ではなく優先条件を指定でき、条件を満たさない場合でもPodをスケジュールさせることができます。 3. Node自体のラベルではなく、Node(または他のトポロジカルドメイン)上で稼働している他のPodのラベルに対して条件を指定することができ、そのPodと同じ、または異なるドメインで稼働させることができます。 </del> <ins> {{< codenew file="pods/pod-with-node-affinity.yaml" >}} </ins> <del> アフィニティは"Nodeアフィニティ"と"Pod間アフィニティ/アンチアフィニティ"の2種類から成ります。 Nodeアフィニティは`nodeSelector`(前述の2つのメリットがあります)に似ていますが、Pod間アフィニティ/アンチアフィニティは、上記の3番目の機能に記載している通り、NodeのラベルではなくPodのラベルに対して制限をかけます。 </del> <ins> この例では、以下のルールが適用されます: </ins> <del> ### Nodeアフィニティ </del> <ins> * Nodeには`topology.kubernetes.io/zone`をキーとするラベルが*必要*で、そのラベルの値は`antarctica-east1`または`antarctica-west1`のいずれかでなければなりません。 * Nodeにはキー名が`another-node-label-key`で、値が`another-node-label-value`のラベルを持つことが*望ましい*です。 </ins> <del> Nodeアフィニティは概念的には、NodeのラベルによってPodがどのNodeにスケジュールされるかを制限する`nodeSelector`と同様です。 </del> <ins> `operator`フィールドを使用して、Kubernetesがルールを解釈する際に使用できる論理演算子を指定することができます。`In`、`NotIn`、`Exists`、`DoesNotExist`、`Gt`、`Lt`が使用できます。 </ins> <del> 現在は2種類のNodeアフィニティがあり、`requiredDuringSchedulingIgnoredDuringExecution`と`preferredDuringSchedulingIgnoredDuringExecution`です。 前者はNodeにスケジュールされるPodが条件を満たすことが必須(`nodeSelector`に似ていますが、より柔軟に条件を指定できます)であり、後者は条件を指定できますが保証されるわけではなく、優先的に考慮されます。 "IgnoredDuringExecution"の意味するところは、`nodeSelector`の機能と同様であり、Nodeのラベルが変更され、Podがその条件を満たさなくなった場合でも PodはそのNodeで稼働し続けるということです。 将来的には、`requiredDuringSchedulingIgnoredDuringExecution`に、PodのNodeアフィニティに記された必須要件を満たさなくなったNodeからそのPodを退避させることができる機能を備えた`requiredDuringSchedulingRequiredDuringExecution`が提供される予定です。 </del> <ins> `NotIn`と`DoesNotExist`を使って、Nodeのアンチアフィニティ動作を定義することができます。また、[NodeのTaint](/ja/docs/concepts/scheduling-eviction/taint-and-toleration/)を使用して、特定のNodeからPodをはじくこともできます。 </ins> <del> それぞれの使用例として、 `requiredDuringSchedulingIgnoredDuringExecution` は、"インテルCPUを供えたNode上でPodを稼働させる"、 `preferredDuringSchedulingIgnoredDuringExecution`は、"ゾーンXYZでPodの稼働を試みますが、実現不可能な場合には他の場所で稼働させる" といった方法が挙げられます。 </del> <ins> {{<note>}} `nodeSelector`と`nodeAffinity`の両方を指定した場合、*両方の*条件を満たさないとPodはNodeにスケジュールされません。 </ins> <del> Nodeアフィニティは、PodSpecの`affinity`フィールドにある`nodeAffinity`フィールドで特定します。 </del> <ins> `nodeAffinity`タイプに関連付けられた`nodeSelectorTerms`内に、複数の条件を指定した場合、Podは指定した条件のいずれかを満たしたNodeへスケジュールされます(条件はORされます)。 </ins> <del> Nodeアフィニティを使用したPodの例を以下に示します: </del> <ins> `nodeSelectorTerms`内の条件に関連付けられた1つの`matchExpressions`フィールド内に、複数の条件を指定した場合、Podは全ての条件を満たしたNodeへスケジュールされます(条件はANDされます)。 {{</note>}} </ins> <del> {{< codenew file="pods/pod-with-node-affinity.yaml" >}} </del> <ins> 詳細については[Nodeアフィニティを利用してPodをNodeに割り当てる](/ja/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/)を参照してください。 #### Nodeアフィニティの重み `preferredDuringSchedulingIgnoredDuringExecution`アフィニティタイプの各インスタンスに、1から100の範囲の`weight`を指定できます。 Podの他のスケジューリング要件をすべて満たすNodeを見つけると、スケジューラーはそのNodeが満たすすべての優先ルールを繰り返し実行し、対応する式の`weight`値を合計に加算します。 最終的な合計は、そのNodeの他の優先度関数のスコアに加算されます。合計スコアが最も高いNodeが、スケジューラーがPodのスケジューリングを決定する際に優先されます。 例えば、次のようなPodのspec(仕様)を考えてみましょう: {{< codenew file="pods/pod-with-affinity-anti-affinity.yaml" >}} </ins> <del> このNodeアフィニティでは、Podはキーが`kubernetes.io/e2e-az-name`、値が`e2e-az1`または`e2e-az2`のラベルが付与されたNodeにしか配置されません。 加えて、キーが`another-node-label-key`、値が`another-node-label-value`のラベルが付与されたNodeが優先されます。 </del> <ins> `preferredDuringSchedulingIgnoredDuringExecution`ルールにマッチするNodeとして、一つは`label-1:key-1`ラベル、もう一つは`label-2:key-2`ラベルの2つの候補がある場合、スケジューラーは各Nodeの`weight`を考慮し、その重みとNodeの他のスコアを加え、最終スコアが最も高いNodeにPodをスケジューリングします。 </ins> <del> この例ではオペレーター`In`が使われています。 Nodeアフィニティでは、`In`、`NotIn`、`Exists`、`DoesNotExist`、`Gt`、`Lt`のオペレーターが使用できます。 `NotIn`と`DoesNotExist`はNodeアンチアフィニティ、またはPodを特定のNodeにスケジュールさせない場合に使われる[Taints](/ja/docs/concepts/scheduling-eviction/taint-and-toleration/)に使用します。 </del> <ins> {{<note>}} この例でKubernetesにPodを正常にスケジュールさせるには、`kubernetes.io/os=linux`ラベルを持つ既存のNodeが必要です。 {{</note>}} </ins> <del> `nodeSelector`と`nodeAffinity`の両方を指定した場合、Podは**両方の**条件を満たすNodeにスケジュールされます。 </del> <ins> #### スケジューリングプロファイルごとのNodeアフィニティ {#node-affinity-per-scheduling-profile} </ins> <del> `nodeAffinity`内で複数の`nodeSelectorTerms`を指定した場合、Podは**いずれかの**`nodeSelectorTerms`を満たしたNodeへスケジュールされます。 </del> <ins> {{< feature-state for_k8s_version="v1.20" state="beta" >}} </ins> <del> `nodeSelectorTerms`内で複数の`matchExpressions`を指定した場合にはPodは**全ての**`matchExpressions`を満たしたNodeへスケジュールされます。 </del> <ins> 複数の[スケジューリングプロファイル](/ja/docs/reference/scheduling/config/#multiple-profiles)を設定する場合、プロファイルにNodeアフィニティを関連付けることができます。これは、プロファイルが特定のNode群にのみ適用される場合に便利です。[スケジューラーの設定](/ja/docs/reference/scheduling/config/)にある[`NodeAffinity`プラグイン](/ja/docs/reference/scheduling/config/#scheduling-plugins)の`args`フィールドに`addedAffinity`を追加すると実現できます。例えば: </ins> <del> PodがスケジュールされたNodeのラベルを削除したり変更しても、Podは削除されません。 言い換えると、アフィニティはPodをスケジュールする際にのみ考慮されます。 </del> <ins> ```yaml apiVersion: kubescheduler.config.k8s.io/v1beta3 kind: KubeSchedulerConfiguration profiles: - schedulerName: default-scheduler - schedulerName: foo-scheduler pluginConfig: - name: NodeAffinity args: addedAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: scheduler-profile operator: In values: - foo ``` `addedAffinity`は、Podの仕様(spec)で指定されたNodeアフィニティに加え、`.spec.schedulerName`を`foo-scheduler`に設定したすべてのPodに適用されます。つまり、Podにマッチするためには、Nodeは`addedAffinity`とPodの`.spec.NodeAffinity`を満たす必要があるのです。 `addedAffinity`はエンドユーザーには見えないので、その動作はエンドユーザーにとって予期しないものになる可能性があります。スケジューラープロファイル名と明確な相関関係のあるNodeラベルを使用すべきです。 {{< note >}} [DaemonSetのPodを作成する](/ja/docs/concepts/workloads/controllers/daemonset/#scheduled-by-default-scheduler)DaemonSetコントローラーは、スケジューリングプロファイルをサポートしていません。DaemonSetコントローラーがPodを作成すると、デフォルトのKubernetesスケジューラーがそれらのPodを配置し、DaemonSetコントローラーの`nodeAffinity`ルールに優先して従います。 {{< /note >}} </ins> <del> `preferredDuringSchedulingIgnoredDuringExecution`内の`weight`フィールドは、1から100の範囲で指定します。 全ての必要条件(リソースやRequiredDuringSchedulingアフィニティ等)を満たしたNodeに対して、スケジューラーはそのNodeがMatchExpressionsを満たした場合に、このフィルードの"weight"を加算して合計を計算します。 このスコアがNodeの他の優先機能のスコアと組み合わせれ、最も高いスコアを有したNodeが優先されます。 </del> <ins> ### Pod間のアフィニティとアンチアフィニティ </ins> <del> ### Pod間アフィニティとアンチアフィニティ </del> <ins> Pod間のアフィニティとアンチアフィニティは、Nodeのラベルではなく、すでにNode上で稼働している**Pod**のラベルに従って、PodがどのNodeにスケジュールされるかを制限できます。 </ins> <del> Pod間アフィニティとアンチアフィニティは、Nodeのラベルではなく、すでにNodeで稼働しているPodのラベルに従ってPodがスケジュールされるNodeを制限します。 このポリシーは、"XにてルールYを満たすPodがすでに稼働している場合、このPodもXで稼働させる(アンチアフィニティの場合は稼働させない)"という形式です。 Yはnamespaceのリストで指定したLabelSelectorで表されます。 Nodeと異なり、Podはnamespaceで区切られているため(それゆえPodのラベルも暗黙的にnamespaceで区切られます)、Podのラベルを指定するlabel selectorは、どのnamespaceにselectorを適用するかを指定する必要があります。 概念的に、XはNodeや、ラック、クラウドプロバイダゾーン、クラウドプロバイダのリージョン等を表すトポロジードメインです。 これらを表すためにシステムが使用するNodeラベルのキーである`topologyKey`を使うことで、トポロジードメインを指定することができます。 先述のセクション[補足: ビルトインNodeラベル](#interlude-built-in-node-labels)にてラベルの例が紹介されています。 </del> <ins> XはNodeや、ラック、クラウドプロバイダーのゾーンやリージョン等を表すトポロジードメインで、YはKubernetesが満たそうとするルールである場合、Pod間のアフィニティとアンチアフィニティのルールは、"XにてルールYを満たすPodがすでに稼働している場合、このPodもXで実行すべき(アンチアフィニティの場合はすべきではない)"という形式です。 これらのルール(Y)は、オプションの関連する名前空間のリストを持つ[ラベルセレクター](/ja/docs/concepts/overview/working-with-objects/labels/#label-selectors)で表現されます。PodはKubernetesの名前空間オブジェクトであるため、Podラベルも暗黙的に名前空間を持ちます。Kubernetesが指定された名前空間でラベルを探すため、Podラベルのラベルセレクターは、名前空間を指定する必要があります。 トポロジードメイン(X)は`topologyKey`で表現され、システムがドメインを示すために使用するNodeラベルのキーになります。具体例は[よく知られたラベル、アノテーションとTaint](/docs/reference/labels-annotations-taints/)を参照してください。 </ins> {{< note >}} <del> Pod間アフィニティとアンチアフィニティは、大規模なクラスター上で使用する際にスケジューリングを非常に遅くする恐れのある多くの処理を要します。 そのため、数百台以上のNodeから成るクラスターでは使用することを推奨されません。 </del> <ins> Pod間アフィニティとアンチアフィニティはかなりの処理量を必要とするため、大規模クラスターでのスケジューリングが大幅に遅くなる可能性があります そのため、数百台以上のNodeから成るクラスターでの使用は推奨されません。 </ins> {{< /note >}} {{< note >}} <del> Podのアンチアフィニティは、Nodeに必ずラベルが付与されている必要があります。 言い換えると、クラスターの全てのNodeが、`topologyKey`で指定されたものに合致する適切なラベルが必要になります。 それらが付与されていないNodeが存在する場合、意図しない挙動を示すことがあります。 </del> <ins> Podのアンチアフィニティは、Nodeに必ず一貫性の持つラベルが付与されている必要があります。 言い換えると、クラスターの全てのNodeが、`topologyKey`に合致する適切なラベルが必要になります。 一部、または全部のNodeに`topologyKey`ラベルが指定されていない場合、意図しない挙動に繋がる可能性があります。 </ins> {{< /note >}} <del> Nodeアフィニティと同様に、PodアフィニティとPodアンチアフィニティにも必須条件と優先条件を示す`requiredDuringSchedulingIgnoredDuringExecution`と`preferredDuringSchedulingIgnoredDuringExecution`があります。 前述のNodeアフィニティのセクションを参照してください。 `requiredDuringSchedulingIgnoredDuringExecution`を指定するアフィニティの使用例は、"Service AのPodとService BのPodが密に通信する際、それらを同じゾーンで稼働させる場合"です。 また、`preferredDuringSchedulingIgnoredDuringExecution`を指定するアンチアフィニティの使用例は、"ゾーンをまたいでPodのサービスを稼働させる場合"(Podの数はゾーンの数よりも多いため、必須条件を指定すると合理的ではありません)です。 </del> <ins> #### Pod間のアフィニティとアンチアフィニティの種類 [Nodeアフィニティ](#node-affinity)と同様に、Podアフィニティとアンチアフィニティにも下記の2種類があります: * `requiredDuringSchedulingIgnoredDuringExecution` * `preferredDuringSchedulingIgnoredDuringExecution` </ins> <del> Pod間アフィニティは、PodSpecの`affinity`フィールド内に`podAffinity`で指定し、Pod間アンチアフィニティは、`podAntiAffinity`で指定します。 </del> <ins> 例えば、`requiredDuringSchedulingIgnoredDuringExecution`アフィニティを使用して、2つのサービスのPodはお互いのやり取りが多いため、同じクラウドプロバイダーゾーンに併置するようにスケジューラーに指示することができます。 同様に、`preferredDuringSchedulingIgnoredDuringExecution`アンチアフィニティを使用して、あるサービスのPodを複数のクラウドプロバイダーゾーンに分散させることができます。 </ins> <del> #### Podアフィニティを使用したPodの例 </del> <ins> Pod間アフィニティを使用するには、Pod仕様(spec)の`affinity.podAffinity`フィールドで指定します。Pod間アンチアフィニティを使用するには、Pod仕様(spec)の`affinity.podAntiAffinity`フィールドで指定します。 #### Podアフィニティ使用例 {#an-example-of-a-pod-that-uses-pod-affinity} 次のようなPod仕様(spec)を考えてみましょう: </ins> {{< codenew file="pods/pod-with-pod-affinity.yaml" >}} <del> このPodのアフィニティは、PodアフィニティとPodアンチアフィニティを1つずつ定義しています。 この例では、`podAffinity`に`requiredDuringSchedulingIgnoredDuringExecution`、`podAntiAffinity`に`preferredDuringSchedulingIgnoredDuringExecution`が設定されています。 Podアフィニティは、「キーが"security"、値が"S1"のラベルが付与されたPodが少なくとも1つは稼働しているNodeが同じゾーンにあれば、PodはそのNodeにスケジュールされる」という条件を指定しています(より正確には、キーが"security"、値が"S1"のラベルが付与されたPodが稼働しており、キーが`topology.kubernetes.io/zone`、値がVであるNodeが少なくとも1つはある状態で、 Node Nがキー`topology.kubernetes.io/zone`、値Vのラベルを持つ場合に、PodはNode Nで稼働させることができます)。 Podアンチアフィニティは、「すでにあるNode上で、キーが"security"、値が"S2"であるPodが稼働している場合に、Podを可能な限りそのNode上で稼働させない」という条件を指定しています (`topologyKey`が`topology.kubernetes.io/zone`であった場合、キーが"security"、値が"S2"であるであるPodが稼働しているゾーンと同じゾーン内のNodeにはスケジュールされなくなります)。 PodアフィニティとPodアンチアフィニティや、`requiredDuringSchedulingIgnoredDuringExecution`と`preferredDuringSchedulingIgnoredDuringExecution`に関する他の使用例は[デザインドック](https://git.k8s.io/community/contributors/design-proposals/scheduling/podaffinity.md)を参照してください。 </del> <ins> この例では、PodアフィニティルールとPodアンチアフィニティルールを1つずつ定義しています。 Podアフィニティルールは"ハード"な`requiredDuringSchedulingIgnoredDuringExecution`を使用し、アンチアフィニティルールは"ソフト"な`preferredDuringSchedulingIgnoredDuringExecution`を使用しています。 </ins> <del> PodアフィニティとPodアンチアフィニティで使用できるオペレーターは、`In`、`NotIn`、 `Exists`、 `DoesNotExist`です。 </del> <ins> アフィニティルールは、スケジューラーがNodeにPodをスケジュールできるのは、そのNodeが、`security=S1`ラベルを持つ1つ以上の既存のPodと同じゾーンにある場合のみであることを示しています。より正確には、現在Podラベル`security=S1`を持つPodが1つ以上あるNodeが、そのゾーン内に少なくとも1つ存在する限り、スケジューラーは`topology.kubernetes.io/zone=V`ラベルを持つNodeにPodを配置しなければなりません。 </ins> <del> 原則として、`topologyKey`には任意のラベルとキーが使用できます。 しかし、パフォーマンスやセキュリティの観点から、以下の制約があります: </del> <ins> アンチアフィニティルールは、`security=S2`ラベルを持つ1つ以上のPodと同じゾーンにあるNodeには、スケジューラーがPodをスケジュールしないようにすることを示しています。より正確には、Podラベル`Security=S2`を持つPodが稼働している他のNodeが、同じゾーン内に存在する場合、スケジューラーは`topology.kubernetes.io/zone=R`ラベルを持つNodeにはPodを配置しないようにしなければなりません。 </ins> <del> 1. アフィニティと、`requiredDuringSchedulingIgnoredDuringExecution`を指定したPodアンチアフィニティは、`topologyKey`を指定しないことは許可されていません。 2. `requiredDuringSchedulingIgnoredDuringExecution`を指定したPodアンチアフィニティでは、`kubernetes.io/hostname`の`topologyKey`を制限するため、アドミッションコントローラー`LimitPodHardAntiAffinityTopology`が導入されました。 トポロジーをカスタマイズする場合には、アドミッションコントローラーを修正または無効化する必要があります。 3. `preferredDuringSchedulingIgnoredDuringExecution`を指定したPodアンチアフィニティでは、`topologyKey`を省略することはできません。 4. 上記の場合を除き、`topologyKey` は任意のラベルとキーを指定することができます。 </del> <ins> Podアフィニティとアンチアフィニティの使用例についてもっと知りたい方は[デザイン案](https://git.k8s.io/design-proposals-archive/scheduling/podaffinity.md)を参照してください。 </ins> <del> `labelSelector`と`topologyKey`に加え、`labelSelector`が合致すべき`namespaces`のリストを特定することも可能です(これは`labelSelector`と`topologyKey`を定義することと同等です)。 省略した場合や空の場合は、アフィニティとアンチアフィニティが定義されたPodのnamespaceがデフォルトで設定されます。 </del> <ins> Podアフィニティとアンチアフィニティの`operator`フィールドで使用できるのは、`In`、`NotIn`、 `Exists`、 `DoesNotExist`です。 </ins> <del> `requiredDuringSchedulingIgnoredDuringExecution`が指定されたアフィニティとアンチアフィニティでは、`matchExpressions`に記載された全ての条件が満たされるNodeにPodがスケジュールされます。 </del> <ins> 原則として、`topologyKey`には任意のラベルキーが指定できますが、パフォーマンスやセキュリティの観点から、以下の例外があります: * Podアフィニティとアンチアフィニティでは、`requiredDuringSchedulingIgnoredDuringExecution`と`preferredDuringSchedulingIgnoredDuringExecution`内のどちらも、`topologyKey`フィールドが空であることは許可されていません。 * Podアンチアフィニティルールの`requiredDuringSchedulingIgnoredDuringExecution`では、アドミッションコントローラー`LimitPodHardAntiAffinityTopology`が`topologyKey`を`kubernetes.io/hostname`に制限しています。アドミッションコントローラーを修正または無効化すると、トポロジーのカスタマイズができるようになります。 </ins> <del> #### 実際的なユースケース </del> <ins> `labelSelector`と`topologyKey`に加え、`labelSelector`と`topologyKey`と同じレベルの`namespaces`フィールドを使用して、`labelSelector`が合致すべき名前空間のリストを任意に指定することができます。省略または空の場合、`namespaces`がデフォルトで、アフィニティとアンチアフィニティが定義されたPodの名前空間に設定されます。 </ins> <del> Pod間アフィニティとアンチアフィニティは、ReplicaSet、StatefulSet、Deploymentなどのより高レベルなコレクションと併せて使用するとさらに有用です。 Workloadが、Node等の定義された同じトポロジーに共存させるよう、簡単に設定できます。 </del> <ins> #### 名前空間セレクター {{< feature-state for_k8s_version="v1.24" state="stable" >}} `namespaceSelector`を使用し、ラベルで名前空間の集合に対して検索することによって、名前空間を選択することができます。 アフィニティ項は`namespaceSelector`と`namespaces`フィールドによって選択された名前空間に適用されます。 要注意なのは、空の`namespaceSelector`({})はすべての名前空間にマッチし、nullまたは空の`namespaces`リストとnullの`namespaceSelector`は、ルールが定義されているPodの名前空間にマッチします。 </ins> <del> ##### 常に同じNodeで稼働させる場合 </del> <ins> #### 実践的なユースケース </ins> <del> ３つのノードから成るクラスターでは、ウェブアプリケーションはredisのようにインメモリキャッシュを保持しています。 このような場合、ウェブサーバーは可能な限りキャッシュと共存させることが望ましいです。 </del> <ins> Pod間アフィニティとアンチアフィニティは、ReplicaSet、StatefulSet、Deploymentなどのより高レベルなコレクションと併せて使用するとさらに有用です。これらのルールにより、ワークロードのセットが同じ定義されたトポロジーに併置されるように設定できます。たとえば、2つの関連するPodを同じNodeに配置することが好ましい場合です。 </ins> <del> ラベル`app=store`を付与した3つのレプリカから成るredisのdeploymentを記述したyamlファイルを示します。 Deploymentには、1つのNodeにレプリカを共存させないために`PodAntiAffinity`を付与しています。 </del> <ins> 例えば、3つのNodeで構成されるクラスターを想像してください。そのクラスターを使用してウェブアプリケーションを実行し、さらにインメモリーキャッシュ(Redisなど)を使用します。この例では、ウェブアプリケーションとメモリーキャッシュの間のレイテンシーは実用的な範囲の低さも想定しています。Pod間アフィニティやアンチアフィニティを使って、ウェブサーバーとキャッシュをなるべく同じ場所に配置することができます。 以下のRedisキャッシュのDeploymentの例では、各レプリカはラベル`app=store`が付与されています。`podAntiAffinity`ルールは、`app=store`ラベルを持つ複数のレプリカを単一Nodeに配置しないよう、スケジューラーに指示します。これにより、各キャッシュが別々のNodeに作成されます。 </ins> ```yaml apiVersion: apps/v1

image: redis:3.2-alpine ``` <del> ウェブサーバーのDeploymentを記載した以下のyamlファイルには、`podAntiAffinity` と`podAffinity`が設定されています。 全てのレプリカが`app=store`のラベルが付与されたPodと同じゾーンで稼働するよう、スケジューラーに設定されます。 また、それぞれのウェブサーバーは1つのノードで稼働されないことも保証されます。 </del> <ins> 次のウェブサーバーのDeployment例では、`app=web-store`ラベルが付与されたレプリカを作成します。Podアフィニティルールは、各レプリカを、`app=store`ラベルが付与されたPodを持つNodeに配置するようスケジューラーに指示します。Podアンチアフィニティルールは、1つのNodeに複数の`app=web-store`サーバーを配置しないようにスケジューラーに指示します。 </ins> ```yaml apiVersion: apps/v1

image: nginx:1.16-alpine ``` <del> 上記2つのDeploymentが生成されると、3つのノードは以下のようになります。 </del> <ins> 上記2つのDeploymentが生成されると、以下のようなクラスター構成になり、各ウェブサーバーはキャッシュと同位置に、3つの別々のNodeに配置されます。 </ins> |       node-1         |       node-2        |       node-3       | |:--------------------:|:-------------------:|:------------------:| | *webserver-1*        |   *webserver-2*     |    *webserver-3*   | |  *cache-1*           |     *cache-2*       |     *cache-3*      | <del> このように、3つの`web-server`は期待通り自動的にキャッシュと共存しています。 ``` kubectl get pods -o wide ``` 出力は以下のようになります: ``` NAME                           READY     STATUS    RESTARTS   AGE       IP           NODE redis-cache-1450370735-6dzlj   1/1       Running   0          8m        10.192.4.2   kube-node-3 redis-cache-1450370735-j2j96   1/1       Running   0          8m        10.192.2.2   kube-node-1 redis-cache-1450370735-z73mh   1/1       Running   0          8m        10.192.3.1   kube-node-2 web-server-1287567482-5d4dz    1/1       Running   0          7m        10.192.2.3   kube-node-1 web-server-1287567482-6f7v5    1/1       Running   0          7m        10.192.4.3   kube-node-3 web-server-1287567482-s330j    1/1       Running   0          7m        10.192.3.2   kube-node-2 ``` ##### 同じNodeに共存させない場合 上記の例では `PodAntiAffinity`を`topologyKey: "kubernetes.io/hostname"`と合わせて指定することで、redisクラスター内の2つのインスタンスが同じホストにデプロイされない場合を扱いました。 同様の方法で、アンチアフィニティを用いて高可用性を実現したStatefulSetの使用例は[ZooKeeper tutorial](/docs/tutorials/stateful-application/zookeeper/#tolerating-node-failure)を参照してください。 </del> <ins> 全体的な効果として、各キャッシュインスタンスは、同じNode上で実行している単一のクライアントによってアクセスされる可能性が高いです。この方法は、スキュー(負荷の偏り)とレイテンシーの両方を最小化することを目的としています。 Podアンチアフィニティを使用する理由は他にもあります。 この例と同様の方法で、アンチアフィニティを用いて高可用性を実現したStatefulSetの使用例は[ZooKeeperチュートリアル](/docs/tutorials/stateful-application/zookeeper/#tolerating-node-failure)を参照してください。 </ins> ## nodeName <del> `nodeName`はNodeの選択を制限する最も簡単な方法ですが、制約があることからあまり使用されません。 `nodeName`はPodSpecのフィールドです。 ここに値が設定されると、schedulerはそのPodを考慮しなくなり、その名前が付与されているNodeのkubeletはPodを稼働させようとします。 そのため、PodSpecに`nodeName`が指定されると、上述のNodeの選択方法よりも優先されます。 </del> <ins> `nodeName`はアフィニティや`nodeSelector`よりも直接的なNode選択形式になります。`nodeName`はPod仕様(spec)内のフィールドです。`nodeName`フィールドが空でない場合、スケジューラーはPodを考慮せずに、指定されたNodeにあるkubeletがそのNodeにPodを配置しようとします。`nodeName`を使用すると、`nodeSelector`やアフィニティおよびアンチアフィニティルールを使用するよりも優先されます。 </ins> <del> `nodeName`を使用することによる制約は以下の通りです: </del> <ins> `nodeName`を使ってNodeを選択する場合の制約は以下の通りです: </ins> <del> -   その名前のNodeが存在しない場合、Podは起動されす、自動的に削除される場合があります。 -   その名前のNodeにPodを稼働させるためのリソースがない場合、Podの起動は失敗し、理由は例えばOutOfmemoryやOutOfcpuになります。 -   クラウド上のNodeの名前は予期できず、変更される可能性があります。 </del> <ins> -   指定されたNodeが存在しない場合、Podは実行されず、場合によっては自動的に削除されることがあります。 -   指定されたNodeがPodを収容するためのリソースを持っていない場合、Podの起動は失敗し、OutOfmemoryやOutOfcpuなどの理由が表示されます。 -   クラウド環境におけるNode名は、常に予測可能で安定したものではありません。 </ins> <del> `nodeName`を指定したPodの設定ファイルの例を示します: </del> <ins> {{< note >}} `nodeName`は、カスタムスケジューラーや、設定済みのスケジューラーをバイパスする必要がある高度なユースケースで使用することを目的としています。 スケジューラーをバイパスすると、割り当てられたNodeに過剰なPodの配置をしようとした場合には、Podの起動に失敗することがあります。 [Nodeアフィニティ](#node-affinity)または[`nodeSelector`フィールド](#nodeselector)を使用すれば、スケジューラーをバイパスせずに、特定のNodeにPodを割り当てることができます。 {{</ note >}} 以下は、`nodeName`フィールドを使用したPod仕様(spec)の例になります: </ins> ```yaml apiVersion: v1

nodeName: kube-01 ``` <del> 上記のPodはkube-01という名前のNodeで稼働します。 </del> <ins> 上記のPodは`kube-01`というNodeでのみ実行されます。 ## Podトポロジー分散制約 {#pod-topology-spread-constraints} </ins> <del> ## {{% heading "whatsnext" %}} </del> <ins> _トポロジー分散制約_ を使って、リージョン、ゾーン、Nodeなどの障害ドメイン間、または定義したその他のトポロジードメイン間で、クラスター全体にどのように{{< glossary_tooltip text="Pod" term_id="Pod" >}}を分散させるかを制御することができます。これにより、パフォーマンス、予想される可用性、または全体的な使用率を向上させることができます。 </ins> <del> [Taints](/ja/docs/concepts/scheduling-eviction/taint-and-toleration/)を使うことで、NodeはPodを追い出すことができます。 </del> <ins> 詳しい仕組みについては、[トポロジー分散制約](/docs/concepts/scheduling-eviction/topology-spread-constraints/)を参照してください。 </ins> <del> [Nodeアフィニティ](https://git.k8s.io/community/contributors/design-proposals/scheduling/nodeaffinity.md)と [Pod間アフィニティ/アンチアフィニティ](https://git.k8s.io/community/contributors/design-proposals/scheduling/podaffinity.md) のデザインドキュメントには、これらの機能の追加のバックグラウンドの情報が記載されています。 </del> <ins> ## {{% heading "whatsnext" %}} </ins> <del> 一度PodがNodeに割り当たると、kubeletはPodを起動してノード内のリソースを確保します。 [トポロジーマネージャー](/docs/tasks/administer-cluster/topology-manager/)はNodeレベルのリソース割り当てを決定する際に関与します。 </del> <ins> * [TaintとToleration](/ja/docs/concepts/scheduling-eviction/taint-and-toleration/)についてもっと読む。 * [Nodeアフィニティ](https://git.k8s.io/design-proposals-archive/scheduling/nodeaffinity.md)と[Pod間アフィニティ/アンチアフィニティ](https://git.k8s.io/design-proposals-archive/scheduling/podaffinity.md)のデザインドキュメントを読む。 * [トポロジーマネージャー](/ja/docs/tasks/administer-cluster/topology-manager/)がNodeレベルのリソース割り当ての決定にどのように関与しているかについて学ぶ。 * [nodeSelector](/ja/docs/tasks/configure-pod-container/assign-pods-nodes/)の使用方法について学ぶ。 * [アフィニティとアンチアフィニティ](/ja/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/)の使用方法について学ぶ。 </ins>

<ins> apiVersion: v1 kind: Pod metadata: name: with-affinity-anti-affinity spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/os operator: In values: - linux preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: label-1 operator: In values: - key-1 - weight: 50 preference: matchExpressions: - key: label-2 operator: In values: - key-2 containers: - name: with-node-affinity image: registry.k8s.io/pause:2.0 </ins>  No newline at end of file