fix scheduling link and update
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
---
|
||||
title: "スケジューリングと退避"
|
||||
weight: 90
|
||||
description: >
|
||||
Kubernetesにおいてスケジューリングとは、稼働させたいPodをNodeにマッチさせ、kubeletが実行できるようにすることを指します。
|
||||
退避とは、リソース不足のNodeで1つ以上のPodを積極的に停止させるプロセスです。
|
||||
---
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
---
|
||||
title: Kubernetesのスケジューラー
|
||||
content_type: concept
|
||||
weight: 60
|
||||
---
|
||||
|
||||
<!-- overview -->
|
||||
|
||||
Kubernetesにおいて、_スケジューリング_ とは、{{< glossary_tooltip term_id="kubelet" >}}が{{< glossary_tooltip text="Pod" term_id="pod" >}}を稼働させるために{{< glossary_tooltip text="Node" term_id="node" >}}に割り当てることを意味します。
|
||||
|
||||
|
||||
|
||||
<!-- body -->
|
||||
|
||||
## スケジューリングの概要{#scheduling}
|
||||
|
||||
スケジューラーは新規に作成されたPodで、Nodeに割り当てられていないものを監視します。スケジューラーは発見した各Podのために、稼働させるべき最適なNodeを見つけ出す責務を担っています。そのスケジューラーは下記で説明するスケジューリングの原理を考慮に入れて、NodeへのPodの割り当てを行います。
|
||||
|
||||
Podが特定のNodeに割り当てられる理由を理解したい場合や、カスタムスケジューラーを自身で作ろうと考えている場合、このページはスケジューリングに関して学ぶのに役立ちます。
|
||||
|
||||
## kube-scheduler
|
||||
|
||||
[kube-scheduler](https://kubernetes.io/docs/reference/command-line-tools-reference/kube-scheduler/)はKubernetesにおけるデフォルトのスケジューラーで、{{< glossary_tooltip text="コントロールプレーン" term_id="control-plane" >}}の一部分として稼働します。
|
||||
kube-schedulerは、もし希望するのであれば自分自身でスケジューリングのコンポーネントを実装でき、それを代わりに使用できるように設計されています。
|
||||
|
||||
kube-schedulerは、新規に作成された各Podや他のスケジューリングされていないPodを稼働させるために最適なNodeを選択します。
|
||||
しかし、Pod内の各コンテナにはそれぞれ異なるリソースの要件があり、各Pod自体にもそれぞれ異なる要件があります。そのため、既存のNodeは特定のスケジューリング要求によってフィルターされる必要があります。
|
||||
|
||||
クラスター内でPodに対する割り当て要求を満たしたNodeは_割り当て可能_ なNodeと呼ばれます。
|
||||
もし適切なNodeが一つもない場合、スケジューラーがNodeを割り当てることができるまで、そのPodはスケジュールされずに残ります。
|
||||
|
||||
スケジューラーはPodに対する割り当て可能なNodeをみつけ、それらの割り当て可能なNodeにスコアをつけます。その中から最も高いスコアのNodeを選択し、Podに割り当てるためのいくつかの関数を実行します。
|
||||
スケジューラーは_binding_ と呼ばれる処理中において、APIサーバーに対して割り当てが決まったNodeの情報を通知します。
|
||||
|
||||
スケジューリングを決定する上で考慮が必要な要素としては、個別または複数のリソース要求や、ハードウェア/ソフトウェアのポリシー制約、affinityやanti-affinityの設定、データの局所性や、ワークロード間での干渉などが挙げられます。
|
||||
|
||||
## kube-schedulerによるスケジューリング{#kube-scheduler-implementation}
|
||||
|
||||
kube-schedulerは2ステップの操作によってPodに割り当てるNodeを選択します。
|
||||
|
||||
1. フィルタリング
|
||||
|
||||
2. スコアリング
|
||||
|
||||
_フィルタリング_ ステップでは、Podに割り当て可能なNodeのセットを探します。例えばPodFitsResourcesフィルターは、Podのリソース要求を満たすのに十分なリソースをもつNodeがどれかをチェックします。このステップの後、候補のNodeのリストは、要求を満たすNodeを含みます。
|
||||
たいてい、リストの要素は複数となります。もしこのリストが空の場合、そのPodはスケジュール可能な状態とはなりません。
|
||||
|
||||
_スコアリング_ ステップでは、Podを割り当てるのに最も適したNodeを選択するために、スケジューラーはリストの中のNodeをランク付けします。
|
||||
スケジューラーは、フィルタリングによって選ばれた各Nodeに対してスコアを付けます。このスコアはアクティブなスコア付けのルールに基づいています。
|
||||
|
||||
最後に、kube-schedulerは最も高いランクのNodeに対してPodを割り当てます。もし同一のスコアのNodeが複数ある場合は、kube-schedulerがランダムに1つ選択します。
|
||||
|
||||
### デフォルトのポリシーについて
|
||||
|
||||
kube-schedulerは、デフォルトで用意されているスケジューリングポリシーのセットを持っています。
|
||||
|
||||
### フィルタリング
|
||||
|
||||
- `PodFitsHostPorts`: Nodeに、Podが要求するポートが利用可能かどうかをチェックします。
|
||||
|
||||
- `PodFitsHost`: Podがそのホスト名において特定のNodeを指定しているかをチェックします。
|
||||
|
||||
- `PodFitsResources`: Nodeに、Podが要求するリソース(例: CPUとメモリー)が利用可能かどうかをチェックします。
|
||||
|
||||
- `PodMatchNodeSelector`: PodのNodeSelectorが、Nodeのラベルにマッチするかどうかをチェックします。
|
||||
|
||||
- `NoVolumeZoneConflict`: Podが要求するVolumeがNode上で利用可能かを、障害が発生しているゾーンを考慮して評価します。
|
||||
|
||||
- `NoDiskConflict`: NodeのVolumeがPodの要求を満たし、すでにマウントされているかどうかを評価します。
|
||||
|
||||
- `MaxCSIVolumeCount`: CSI Volumeをいくつ割り当てるべきか決定し、それが設定された上限を超えるかどうかを評価します。
|
||||
|
||||
- `CheckNodeMemoryPressure`: もしNodeがメモリーの容量が逼迫している場合、また設定された例外がない場合はそのPodはそのNodeにスケジュールされません。
|
||||
|
||||
- `CheckNodePIDPressure`: もしNodeのプロセスIDが枯渇しそうになっていた場合や、設定された例外がない場合はそのPodはそのNodeにスケジュールされません。
|
||||
|
||||
- `CheckNodeDiskPressure`: もしNodeのストレージが逼迫している場合(ファイルシステムの残り容量がほぼない場合)や、設定された例外がない場合はそのPodはそのNodeにスケジュールされません。
|
||||
|
||||
- `CheckNodeCondition`: Nodeは、ファイルシステムの空き容量が完全になくなった場合、ネットワークが利用不可な場合、kubeletがPodを稼働させる準備をできていない場合などに、その状況を通知できます。Nodeがこの状況下かつ設定された例外がない場合、Podは該当のNodeにスケジュールされません。
|
||||
|
||||
- `PodToleratesNodeTaints`: PodのTolerationがNodeのTaintを許容できるかチェックします。
|
||||
|
||||
- `CheckVolumeBinding`: Podが要求するVolumeの要求を満たすか評価します。これはPersistentVolumeClaimがバインドされているかに関わらず適用されます。
|
||||
|
||||
### スコアリング
|
||||
|
||||
- `SelectorSpreadPriority`: 同一のService、StatefulSetや、ReplicaSetに属するPodを複数のホストをまたいで稼働させます。
|
||||
|
||||
- `InterPodAffinityPriority`: weightedPodAffinityTermの要素をイテレートして合計を計算したり、もし一致するPodAffinityTermがNodeに適合している場合は、"重み"を合計値に足したりします。:最も高い合計値を持つNode(複数もあり)が候補となります。
|
||||
|
||||
- `LeastRequestedPriority`: 要求されたリソースがより低いNodeを優先するものです。言い換えると、Nodeに多くのPodが稼働しているほど、Podが使用するリソースが多くなり、その要求量が低いNodeが選択されます。
|
||||
|
||||
- `MostRequestedPriority`: 要求されたリソースがより多いNodeを優先するものです。このポリシーは、ワークロードの全体セットを実行するために必要な最小数のNodeに対して、スケジュールされたPodを適合させます。
|
||||
|
||||
- `RequestedToCapacityRatioPriority`: デフォルトのリソーススコアリング関数を使用して、requestedToCapacityベースのResourceAllocationPriorityを作成します。
|
||||
|
||||
- `BalancedResourceAllocation`: バランスのとれたリソース使用量になるようにNodeを選択します。
|
||||
|
||||
- `NodePreferAvoidPodsPriority`: Nodeの`scheduler.alpha.kubernetes.io/preferAvoidPods`というアノテーションに基づいてNodeの優先順位づけをします。この設定により、2つの異なるPodが同じNode上で実行しないことを示唆できます。
|
||||
|
||||
- `NodeAffinityPriority`: "PreferredDuringSchedulingIgnoredDuringExecution"の値によって示されたNode Affinityのスケジューリング性向に基づいてNodeの優先順位づけを行います。詳細は[NodeへのPodの割り当て](https://kubernetes.io/ja/docs/concepts/configuration/assign-pod-node/)にて確認できます。
|
||||
|
||||
- `TaintTolerationPriority`: Node上における許容できないTaintsの数に基づいて、全てのNodeの優先順位リストを準備します。このポリシーでは優先順位リストを考慮してNodeのランクを調整します。
|
||||
|
||||
- `ImageLocalityPriority`: すでにPodに対するコンテナイメージをローカルにキャッシュしているNodeを優先します。
|
||||
|
||||
- `ServiceSpreadingPriority`: このポリシーの目的は、特定のServiceに対するバックエンドのPodが、それぞれ異なるNodeで実行されるようにすることです。このポリシーではServiceのバックエンドのPodがすでに実行されていないNode上にスケジュールするように優先します。これによる結果として、Serviceは単体のNode障害に対してより耐障害性が高まります。
|
||||
|
||||
- `CalculateAntiAffinityPriorityMap`: このポリシーは[PodのAnti-Affinity](/ja/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity)の実装に役立ちます。
|
||||
|
||||
- `EqualPriorityMap`: 全てのNodeに対して等しい重みを与えます。
|
||||
|
||||
|
||||
## {{% heading "whatsnext" %}}
|
||||
|
||||
* [スケジューラーのパフォーマンスチューニング](/docs/concepts/scheduling/scheduler-perf-tuning/)を参照してください。
|
||||
* [Podトポロジーの分散制約](/docs/concepts/workloads/pods/pod-topology-spread-constraints/)を参照してください。
|
||||
* kube-schedulerの[リファレンスドキュメント](/docs/reference/command-line-tools-reference/kube-scheduler/)を参照してください。
|
||||
* [複数のスケジューラーの設定](/docs/tasks/administer-cluster/configure-multiple-schedulers/)について学んでください。
|
||||
* [トポロジーの管理ポリシー](/docs/tasks/administer-cluster/topology-manager/)について学んでください。
|
||||
* [Podのオーバーヘッド](/docs/concepts/configuration/pod-overhead/)について学んでください。
|
||||
@@ -0,0 +1,74 @@
|
||||
---
|
||||
title: スケジューラーのパフォーマンスチューニング
|
||||
content_type: concept
|
||||
weight: 70
|
||||
---
|
||||
|
||||
<!-- overview -->
|
||||
|
||||
{{< feature-state for_k8s_version="1.14" state="beta" >}}
|
||||
|
||||
[kube-scheduler](/docs/concepts/scheduling/kube-scheduler/#kube-scheduler)はKubernetesのデフォルトのスケジューラーです。クラスター内のノード上にPodを割り当てる責務があります。
|
||||
|
||||
クラスター内に存在するノードで、Podのスケジューリング要求を満たすものはPodに対して*割り当て可能*なノードと呼ばれます。スケジューラーはPodに対する割り当て可能なノードをみつけ、それらの割り当て可能なノードにスコアをつけます。その中から最も高いスコアのノードを選択し、Podに割り当てるためのいくつかの関数を実行します。スケジューラーは*Binding*と呼ばれる処理中において、APIサーバーに対して割り当てが決まったノードの情報を通知します。
|
||||
|
||||
このページでは、大規模のKubernetesクラスターにおけるパフォーマンス最適化のためのチューニングについて説明します。
|
||||
|
||||
|
||||
|
||||
<!-- body -->
|
||||
|
||||
## スコア付けするノードの割合
|
||||
|
||||
Kubernetes 1.12以前では、Kube-schedulerがクラスター内の全てのノードに対して割り当て可能かをチェックし、実際に割り当て可能なノードのスコア付けをしていました。Kubernetes 1.12では新機能を追加し、ある数の割り当て可能なノードが見つかった時点で、割り当て可能なノードの探索を止めれるようになりました。これにより大規模なクラスターにおけるスケジューラーのパフォーマンスが向上しました。その数はクラスターのサイズの割合(%)として指定されます。この割合は`percentageOfNodesToScore`というオプションの設定項目によって指定可能です。この値の範囲は1から100までです。100より大きい値は100%として扱われます。0を指定したときは、この設定オプションを指定しないものとして扱われます。Kubernetes 1.14では、この値が指定されていないときは、スコア付けするノードの割合をクラスターのサイズに基づいて決定するためのメカニズムがあります。このメカニズムでは100ノードのクラスターに対しては50%の割合とするような線形な式を使用します。5000ノードのクラスターに対しては10%となります。自動で算出される割合の最低値は5%となります。言い換えると、クラスターの規模がどれだけ大きくても、ユーザーがこの値を5未満に設定しない限りスケジューラーは少なくても5%のクラスター内のノードをスコア付けすることになります。
|
||||
|
||||
`percentageOfNodesToScore`の値を50%に設定する例は下記のとおりです。
|
||||
|
||||
```yaml
|
||||
apiVersion: kubescheduler.config.k8s.io/v1alpha1
|
||||
kind: KubeSchedulerConfiguration
|
||||
algorithmSource:
|
||||
provider: DefaultProvider
|
||||
|
||||
...
|
||||
|
||||
percentageOfNodesToScore: 50
|
||||
```
|
||||
|
||||
{{< note >}}
|
||||
割り当て可能なノードが50未満のクラスターにおいては、割り当て可能なノードの探索を止めるほどノードが多くないため、スケジューラーは全てのノードをチェックします。
|
||||
{{< /note >}}
|
||||
|
||||
**この機能を無効にするためには**、`percentageOfNodesToScore`を100に設定してください。
|
||||
|
||||
|
||||
### percentageOfNodesToScoreのチューニング
|
||||
|
||||
`percentageOfNodesToScore`は1から100の間の範囲である必要があり、デフォルト値はクラスターのサイズに基づいて計算されます。また、クラスターのサイズの最小値は50ノードとハードコードされています。これは数百のノードを持つようなクラスターにおいてこの値を50より低い値に変更しても、スケジューラーが検出する割り当て可能なノードの数に大きな影響を与えないことを意味します。このオプションは意図的なものです。その理由としては、小規模のクラスターにおいてパフォーマンスを著しく改善する可能性が低いためです。1000ノードを超える大規模なクラスターでこの値を低く設定すると、パフォーマンスが著しく改善される可能性があります。
|
||||
|
||||
この値を設定する際に考慮するべき重要な注意事項として、割り当て可能ノードのチェック対象のノードが少ないと、一部のノードはPodの割り当てのためにスコアリングされなくなります。結果として、高いスコアをつけられる可能性のあるノードがスコアリングフェーズに渡されることがありません。これにより、Podの配置が理想的なものでなくなります。したがって、この値をかなり低い割合に設定すべきではありません。一般的な経験則として、この値を10未満に設定しないことです。スケジューラーのスループットがアプリケーションにとって致命的で、ノードのスコアリングが重要でないときのみ、この値を低く設定するべきです。言いかえると、割り当て可能な限り、Podは任意のノード上で稼働させるのが好ましいです。
|
||||
|
||||
クラスターが数百のノードを持つ場合やそれに満たない場合でも、この設定オプションのデフォルト値を低くするのを推奨しません。デフォルト値を低くしてもスケジューラーのパフォーマンスを大幅に改善することはありません。
|
||||
|
||||
### スケジューラーはどのようにノードを探索するか
|
||||
|
||||
このセクションでは、この機能の内部の詳細を理解したい人向けになります。
|
||||
|
||||
クラスター内の全てのノードに対して平等にPodの割り当ての可能性を持たせるため、スケジューラーはラウンドロビン方式でノードを探索します。複数のノードの配列になっているイメージです。スケジューラーはその配列の先頭から探索を開始し、`percentageOfNodesToScore`によって指定された数のノードを検出するまで、割り当て可能かどうかをチェックしていきます。次のPodでは、スケジューラーは前のPodの割り当て処理でチェックしたところから探索を再開します。
|
||||
|
||||
ノードが複数のゾーンに存在するとき、スケジューラーは様々なゾーンのノードを探索して、異なるゾーンのノードが割り当て可能かどうかのチェック対象になるようにします。例えば2つのゾーンに6つのノードがある場合を考えます。
|
||||
|
||||
```
|
||||
Zone 1: Node 1, Node 2, Node 3, Node 4
|
||||
Zone 2: Node 5, Node 6
|
||||
```
|
||||
|
||||
スケジューラーは、下記の順番でノードの割り当て可能性を評価します。
|
||||
|
||||
```
|
||||
Node 1, Node 5, Node 2, Node 6, Node 3, Node 4
|
||||
```
|
||||
|
||||
全てのノードのチェックを終えたら、1番目のノードに戻ってチェックをします。
|
||||
|
||||
|
||||
@@ -0,0 +1,221 @@
|
||||
---
|
||||
title: TaintとToleration
|
||||
content_type: concept
|
||||
weight: 40
|
||||
---
|
||||
|
||||
|
||||
<!-- overview -->
|
||||
[_Nodeアフィニティ_](/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity)は
|
||||
{{< glossary_tooltip text="Pod" term_id="pod" >}}の属性であり、ある{{< glossary_tooltip text="Node" term_id="node" >}}群を*引きつけます*(優先条件または必須条件)。反対に _taint_ はNodeがある種のPodを排除できるようにします。
|
||||
|
||||
_toleration_ はPodに適用され、一致するtaintが付与されたNodeへPodがスケジューリングされることを認めるものです。ただしそのNodeへ必ずスケジューリングされるとは限りません。
|
||||
|
||||
taintとtolerationは組になって機能し、Podが不適切なNodeへスケジューリングされないことを保証します。taintはNodeに一つまたは複数個付与することができます。これはそのNodeがtaintを許容しないPodを受け入れるべきではないことを示します。
|
||||
|
||||
|
||||
<!-- body -->
|
||||
|
||||
## コンセプト
|
||||
|
||||
Nodeにtaintを付与するには[kubectl taint](/docs/reference/generated/kubectl/kubectl-commands#taint)コマンドを使用します。
|
||||
例えば、次のコマンドは
|
||||
|
||||
```shell
|
||||
kubectl taint nodes node1 key=value:NoSchedule
|
||||
```
|
||||
|
||||
`node1`にtaintを設定します。このtaintのキーは`key`、値は`value`、taintの効果は`NoSchedule`です。
|
||||
これは`node1`にはPodに合致するtolerationがなければスケジューリングされないことを意味します。
|
||||
|
||||
上記のコマンドで付与したtaintを外すには、下記のコマンドを使います。
|
||||
```shell
|
||||
kubectl taint nodes node1 key:NoSchedule-
|
||||
```
|
||||
|
||||
PodのtolerationはPodSpecの中に指定します。下記のtolerationはどちらも、上記の`kubectl taint`コマンドで追加したtaintと合致するため、どちらのtolerationが設定されたPodも`node1`へスケジューリングされることができます。
|
||||
|
||||
```yaml
|
||||
tolerations:
|
||||
- key: "key"
|
||||
operator: "Equal"
|
||||
value: "value"
|
||||
effect: "NoSchedule"
|
||||
```
|
||||
|
||||
```yaml
|
||||
tolerations:
|
||||
- key: "key"
|
||||
operator: "Exists"
|
||||
effect: "NoSchedule"
|
||||
```
|
||||
|
||||
tolerationを設定したPodの例を示します。
|
||||
|
||||
{{< codenew file="pods/pod-with-toleration.yaml" >}}
|
||||
|
||||
`operator`のデフォルトは`Equal`です。
|
||||
|
||||
tolerationがtaintと合致するのは、`key`と`effect`が同一であり、さらに下記の条件のいずれかを満たす場合です。
|
||||
|
||||
* `operator`が`Exists`(`value`を指定すべきでない場合)
|
||||
* `operator`が`Equal`であり、かつ`value`が同一である場合
|
||||
|
||||
{{< note >}}
|
||||
|
||||
2つ特殊な場合があります。
|
||||
|
||||
空の`key`と演算子`Exists`は全ての`key`、`value`、`effect`と一致するため、すべてのtaintと合致します。
|
||||
|
||||
空の`effect`は`key`が一致する全てのeffectと合致します。
|
||||
|
||||
{{< /note >}}
|
||||
|
||||
上記の例では`effect`に`NoSchedule`を指定しました。代わりに、`effect`に`PreferNoSchedule`を指定することができます。
|
||||
これは`NoSchedule`の「ソフトな」バージョンであり、システムはtaintに対応するtolerationが設定されていないPodがNodeへ配置されることを避けようとしますが、必須の条件とはしません。3つ目の`effect`の値として`NoExecute`がありますが、これについては後述します。
|
||||
|
||||
同一のNodeに複数のtaintを付与することや、同一のPodに複数のtolerationを設定することができます。
|
||||
複数のtaintやtolerationが設定されている場合、Kubernetesはフィルタのように扱います。最初はNodeの全てのtaintがある状態から始め、Podが対応するtolerationを持っているtaintは無視され外されていきます。無視されずに残ったtaintが効果を及ぼします。
|
||||
具体的には、
|
||||
|
||||
* effect `NoSchedule`のtaintが無視されず残った場合、KubernetesはそのPodをNodeへスケジューリングしません。
|
||||
* effect `NoSchedule`のtaintは残らず、effect `PreferNoSchedule`のtaintは残った場合、KubernetesはそのNodeへのスケジューリングをしないように試みます。
|
||||
* effect `NoExecute`のtaintが残った場合、既に稼働中のPodはそのNodeから排除され、まだ稼働していないPodはスケジューリングされないようになります。
|
||||
|
||||
例として、下記のようなtaintが付与されたNodeを考えます。
|
||||
|
||||
```shell
|
||||
kubectl taint nodes node1 key1=value1:NoSchedule
|
||||
kubectl taint nodes node1 key1=value1:NoExecute
|
||||
kubectl taint nodes node1 key2=value2:NoSchedule
|
||||
```
|
||||
|
||||
Podには2つのtolerationが設定されています。
|
||||
|
||||
```yaml
|
||||
tolerations:
|
||||
- key: "key1"
|
||||
operator: "Equal"
|
||||
value: "value1"
|
||||
effect: "NoSchedule"
|
||||
- key: "key1"
|
||||
operator: "Equal"
|
||||
value: "value1"
|
||||
effect: "NoExecute"
|
||||
```
|
||||
|
||||
この例では、3つ目のtaintと合致するtolerationがないため、PodはNodeへはスケジューリングされません。
|
||||
しかし、これらのtaintが追加された時点で、そのNodeでPodが稼働していれば続けて稼働することが可能です。 これは、Podのtolerationと合致しないtaintは3つあるtaintのうちの3つ目のtaintのみであり、それが`NoSchedule`であるためです。
|
||||
|
||||
一般に、effect `NoExecute`のtaintがNodeに追加されると、合致するtolerationが設定されていないPodは即時にNodeから排除され、合致するtolerationが設定されたPodが排除されることは決してありません。
|
||||
しかし、effect`NoExecute`に対するtolerationは`tolerationSeconds`フィールドを任意で指定することができ、これはtaintが追加された後にそのNodeにPodが残る時間を示します。例えば、
|
||||
|
||||
```yaml
|
||||
tolerations:
|
||||
- key: "key1"
|
||||
operator: "Equal"
|
||||
value: "value1"
|
||||
effect: "NoExecute"
|
||||
tolerationSeconds: 3600
|
||||
```
|
||||
|
||||
この例のPodが稼働中で、対応するtaintがNodeへ追加された場合、PodはそのNodeに3600秒残り、その後排除されます。仮にtaintがそれよりも前に外された場合、Podは排除されません。
|
||||
|
||||
## ユースケースの例
|
||||
|
||||
taintとtolerationは、実行されるべきではないNodeからPodを遠ざけたり、排除したりするための柔軟な方法です。いくつかのユースケースを示します。
|
||||
|
||||
* **専有Node**: あるNode群を特定のユーザーに専有させたい場合、そのNode群へtaintを追加し(`kubectl taint nodes nodename dedicated=groupName:NoSchedule`) 対応するtolerationをPodへ追加します(これを実現する最も容易な方法はカスタム
|
||||
[アドミッションコントローラー](/docs/reference/access-authn-authz/admission-controllers/)を書くことです)。
|
||||
tolerationが設定されたPodはtaintの設定された(専有の)Nodeと、クラスターにあるその他のNodeの使用が認められます。もしPodが必ず専有Node*のみ*を使うようにしたい場合は、taintと同様のラベルをそのNode群に設定し(例: `dedicated=groupName`)、アドミッションコントローラーはNodeアフィニティを使ってPodが`dedicated=groupName`のラベルの付いたNodeへスケジューリングすることが必要であるということも設定する必要があります。
|
||||
|
||||
* **特殊なハードウェアを備えるNode**: クラスターの中の少数のNodeが特殊なハードウェア(例えばGPU)を備える場合、そのハードウェアを必要としないPodがスケジューリングされないようにして、後でハードウェアを必要とするPodができたときの余裕を確保したいことがあります。
|
||||
これは特殊なハードウェアを持つNodeにtaintを追加(例えば `kubectl taint nodes nodename special=true:NoSchedule` または
|
||||
`kubectl taint nodes nodename special=true:PreferNoSchedule`)して、ハードウェアを使用するPodに対応するtolerationを追加することで可能です。
|
||||
専有Nodeのユースケースと同様に、tolerationを容易に適用する方法はカスタム
|
||||
[アドミッションコントローラー](/docs/reference/access-authn-authz/admission-controllers/)を使うことです。
|
||||
例えば、特殊なハードウェアを表すために[拡張リソース](/docs/concepts/configuration/manage-compute-resources-container/#extended-resources)
|
||||
を使い、ハードウェアを備えるNodeに拡張リソースの名称のtaintを追加して、
|
||||
[拡張リソースtoleration](/docs/reference/access-authn-authz/admission-controllers/#extendedresourcetoleration)
|
||||
アドミッションコントローラーを実行することが推奨されます。Nodeにはtaintが付与されているため、tolerationのないPodはスケジューリングされません。しかし拡張リソースを要求するPodを作成しようとすると、`拡張リソースtoleration` アドミッションコントローラーはPodに自動的に適切なtolerationを設定し、Podはハードウェアを備えるNodeへスケジューリングされます。
|
||||
これは特殊なハードウェアを備えたNodeではそれを必要とするPodのみが稼働し、Podに対して手作業でtolerationを追加しなくて済むようにします。
|
||||
|
||||
* **taintを基にした排除**: Nodeに問題が起きたときにPodごとに排除する設定を行うことができます。次のセクションにて説明します。
|
||||
|
||||
## taintを基にした排除
|
||||
|
||||
{{< feature-state for_k8s_version="v1.18" state="stable" >}}
|
||||
|
||||
上述したように、effect `NoExecute`のtaintはNodeで実行中のPodに次のような影響を与えます。
|
||||
|
||||
* 対応するtolerationのないPodは即座に除外される
|
||||
* 対応するtolerationがあり、それに`tolerationSeconds`が指定されていないPodは残り続ける
|
||||
* 対応するtolerationがあり、それに`tolerationSeconds`が指定されているPodは指定された間、残される
|
||||
|
||||
Nodeコントローラーは特定の条件を満たす場合に自動的にtaintを追加します。
|
||||
組み込まれているtaintは下記の通りです。
|
||||
|
||||
* `node.kubernetes.io/not-ready`: Nodeの準備ができていない場合。これはNodeCondition `Ready`が`False`である場合に対応します。
|
||||
* `node.kubernetes.io/unreachable`: NodeがNodeコントローラーから到達できない場合。これはNodeCondition`Ready`が`Unknown`の場合に対応します。
|
||||
* `node.kubernetes.io/out-of-disk`: Nodeのディスクの空きがない場合。
|
||||
* `node.kubernetes.io/memory-pressure`: Nodeのメモリーが不足している場合。
|
||||
* `node.kubernetes.io/disk-pressure`: Nodeのディスクが不足している場合。
|
||||
* `node.kubernetes.io/network-unavailable`: Nodeのネットワークが利用できない場合。
|
||||
* `node.kubernetes.io/unschedulable`: Nodeがスケジューリングできない場合。
|
||||
* `node.cloudprovider.kubernetes.io/uninitialized`: kubeletが外部のクラウド事業者により起動されたときに設定されるtaintで、このNodeは利用不可能であることを示します。cloud-controller-managerによるコントローラーがこのNodeを初期化した後にkubeletはこのtaintを外します。
|
||||
|
||||
Nodeから追い出すときには、Nodeコントローラーまたはkubeletは関連するtaintを`NoExecute`効果の状態で追加します。
|
||||
不具合のある状態から通常の状態へ復帰した場合は、kubeletまたはNodeコントローラーは関連するtaintを外すことができます。
|
||||
|
||||
{{< note >}}
|
||||
コントロールプレーンは新しいtaintをNodeに加えるレートを制限しています。
|
||||
このレート制限は一度に多くのNodeが到達不可能になった場合(例えばネットワークの断絶)に、退役させられるNodeの数を制御します。
|
||||
{{< /note >}}
|
||||
|
||||
Podに`tolerationSeconds`を指定することで不具合があるか応答のないNodeに残る時間を指定することができます。
|
||||
|
||||
例えば、ローカルの状態を多数持つアプリケーションとネットワークが分断された場合を考えます。ネットワークが復旧して、Podを排除しなくて済むことを見込んで、長時間Nodeから排除されないようにしたいこともあるでしょう。
|
||||
この場合Podに設定するtolerationは次のようになります。
|
||||
|
||||
```yaml
|
||||
tolerations:
|
||||
- key: "node.kubernetes.io/unreachable"
|
||||
operator: "Exists"
|
||||
effect: "NoExecute"
|
||||
tolerationSeconds: 6000
|
||||
```
|
||||
|
||||
{{< note >}}
|
||||
Kubernetesはユーザーまたはコントローラーが明示的に指定しない限り、自動的に`node.kubernetes.io/not-ready`と`node.kubernetes.io/unreachable`に対するtolerationを`tolerationSeconds=300`にて設定します。
|
||||
|
||||
自動的に設定されるtolerationは、taintに対応する問題がNodeで検知されても5分間はそのNodeにPodが残されることを意味します。
|
||||
{{< /note >}}
|
||||
|
||||
[DaemonSet](/docs/concepts/workloads/controllers/daemonset/)のPodは次のtaintに対して`NoExecute`のtolerationが`tolerationSeconds`を指定せずに設定されます。
|
||||
|
||||
* `node.kubernetes.io/unreachable`
|
||||
* `node.kubernetes.io/not-ready`
|
||||
|
||||
これはDaemonSetのPodはこれらの問題によって排除されないことを保証します。
|
||||
|
||||
## 条件によるtaintの付与
|
||||
|
||||
NodeのライフサイクルコントローラーはNodeの状態に応じて`NoSchedule`効果のtaintを付与します。
|
||||
スケジューラーはNodeの状態ではなく、taintを確認します。
|
||||
Nodeに何がスケジューリングされるかは、そのNodeの状態に影響されないことを保証します。ユーザーは適切なtolerationをPodに付与することで、どの種類のNodeの問題を無視するかを選ぶことができます。
|
||||
|
||||
DaemonSetのコントローラーは、DaemonSetが中断されるのを防ぐために自動的に次の`NoSchedule`tolerationを全てのDaemonSetに付与します。
|
||||
|
||||
* `node.kubernetes.io/memory-pressure`
|
||||
* `node.kubernetes.io/disk-pressure`
|
||||
* `node.kubernetes.io/out-of-disk` (*重要なPodのみ*)
|
||||
* `node.kubernetes.io/unschedulable` (1.10またはそれ以降)
|
||||
* `node.kubernetes.io/network-unavailable` (*ホストネットワークのみ*)
|
||||
|
||||
これらのtolerationを追加することは後方互換性を保証します。DaemonSetに任意のtolerationを加えることもできます。
|
||||
|
||||
|
||||
## {{% heading "whatsnext" %}}
|
||||
|
||||
* [リソース枯渇の対処](/docs/tasks/administer-cluster/out-of-resource/)とどのような設定ができるかについてを読む
|
||||
* [Podの優先度](/docs/concepts/configuration/pod-priority-preemption/)を読む
|
||||
Reference in New Issue
Block a user