目次
4.2.1 優先ノード アフィニティを使用した Pod のスケジューリング
4.2.2 必須のノード アフィニティに基づく Pod のスケジューリング
1. ポッドのスケジューリング プロセス
Kubernetes は、list-watch メカニズムに基づくコントローラー アーキテクチャを使用して、コンポーネント間の相互作用を分離します。
他のコンポーネントは、担当するリソースを監視します. これらのリソースが変更されると、kube-apiserver はこれらのコンポーネントに通知します. このプロセスは、発行と購読に似ています.
スケジューリングの一般的なプロセス
- ユーザーは create yaml を使用して Pod を作成し、それを apiServer に要求し、apiserver は yaml 内の属性情報 (メタデータ) を etcd に書き込みます
- apiServer は監視メカニズムをトリガーして Pod を作成し、情報をスケジューラーに転送します。スケジューラーはスケジューリング アルゴリズムを使用してノードを選択し、スケジューラーはノード情報を apiServer に送信し、apiServer はバインドされたノード情報を etcd に書き込みます。
- apiServer は、watch メカニズムを介して kubelet を呼び出し、ポッド情報を指定し、docker run コマンドをトリガーしてコンテナーを作成します。
- 作成が完了すると kubelet にフィードバックされ、kubelet は Pod のステータス情報を apiserver に送信します。
- apiserver は Pod のステータス情報を etcd に書き込みます。
- その中で、etcd_ 情報は kubectl get pods コマンドによって呼び出されます。
2. コンテナ リソースの制限
2.1 メモリと CPU の制限
コンテナーが使用する最大リソース制限:
• resources.limits.cpu
• resources.limits.memory
コンテナーで使用される最小リソース要件は、コンテナーのスケジューリング中のリソース割り当ての基準として使用されます。
• resources.requests.cpu
• resources.requests.memory
公式の例:コンテナーと Pod へのメモリ リソースの割り当て | Kubernetes
例
apiVersion: v1
kind: Pod
metadata:
name: pod-resource
spec:
containers:
- name: web
image: nginx
resources:
requests: # 容器最小资源配额
memory: "64Mi"
cpu: "250m"
limits: # 容器最大资源上限
memory: "128Mi"
cpu: "500m"
describe を使用して、ポッドの説明情報を表示します
3.ノードセレクター
nodeSelector:ラベルに一致するノードに Pod をスケジュールするために使用されます。一致するラベルがない場合、スケジュールは失敗します。効果:
• Pod を特定のノードで実行するように制限する
• 完全一致ノード ラベルの適用シナリオ:
• 専用ノード: ノードはビジネス ラインに従ってグループ化され、管理されます。
• 特別なハードウェアを装備: 一部のノードには SSD ハードディスクと GPU が装備されています
操作例
### 给node2 打上SSD 的标签
kubectl label node k8s-node2 disktype=ssd
## 查看node 的标签信息
kubectl get node k8s-node2 --show-labels
ポッドを作成し、SSD ラベルを使用してポッドを k8s-node2 ノードにスケジュールします
apiVersion: v1
kind: Pod
metadata:
name: pod-node-selector
spec:
nodeSelector:
disktype: 'ssd'
containers:
- name: web
image: nginx
k8s-node2 ノードにスケジュールされているかどうかを確認します
4.ノードの親和性
4.1 基本概念
ノード アフィニティを使用して Pod をワーカー ノードに割り当てます。
nodeAffinity: nodeSelector と同じ機能を持つノード アフィニティですが、より柔軟で、次のようなより多くの条件を満たすことができます。
• マッチングには、文字列が完全に等しいだけでなく、より多くの論理的な組み合わせがあります
• スケジューリングは、ハード要件ではなく、ソフト ポリシーとハード ポリシーに分けられます。
• ハード (必須): 満たす必要があります
• ソフト (優先): 満たそうとしますが、保証はしません。
演算子: In、NotIn、Exists、DoesNotExist、Gt、Lt
公式の例:
ノード アフィニティを使用してポッドをノードに割り当てる | Kubernetes
4.2 ポッドの例
4.2.1 優先ノード アフィニティを使用した Pod のスケジューリング
次のソフト ポリシーの例は、ノード ラベル gpu=nvidia に一致します。
apiVersion: v1
kind: Pod
metadata:
name: pod-node-affinity
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: gpu
operator: In
values:
- nvidia
containers:
- name: web
image: nginx
ソフト戦略は k8s-master1 ノードにディスパッチされます.Master1 には gpu=nvidia ラベルがなく、ソフト戦略は正常にディスパッチされます.
4.2.2 必須のノード アフィニティに基づく Pod のスケジューリング
apiVersion: v1
kind: Pod
metadata:
name: pod-node-affinity2
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: gpu
operator: In
values:
- nvidia
containers:
- name: web
image: nginx
上記がハード ポリシーに変更された後、ポッドはラベル gpu=nvidia のノードにスケジュールされる必要がありますが、k8s テスト クラスターにはそのようなノードはありません。
以下のように、pod-node-affinity2 が Pending 状態にあることがわかります。
describe を使用して Pod のステータスを表示します。一致するノードはありません
警告 FailedScheduling 36s default-scheduler 0/4 ノードが利用可能です: 4 つのノードが Pod のノード アフィニティ/セレクターと一致しませんでした。プリエンプション: 0/4 ノードが利用可能: 4 プリエンプションはスケジューリングに役立ちません。
5.汚染と寛容
5.1 基本概念
ノード アフィニティは、Pod が特定のクラスのノードに引き付けられるようにする Podのプロパティです(これは優先事項である場合もあれば、厳しい要件である場合もあります)。taintは逆で、ノードが特定のクラスの Pod を除外できるようにします。
Tolerations は Pod に適用され、Taint が一致するノードで Pod をスケジュールすることを許可します (必須ではありません)。
taint とトレランス (Toleration) は相互に連携し、Pod が不適切なノードに割り当てられるのを防ぐために使用できます。各ノードに 1 つ以上のテイントを適用できます。つまり、これらのテイントを許容できない Pod はノードによって受け入れられません。
テイント:特定のノードへの Pod スケジューリングを回避する
Tolerations: Taints を保持している Node に Pod をディスパッチできるようにします アプリケーションのシナリオ:
• 専用ノード: ノードはビジネス ラインに従ってグループ化および管理されます.このノードはデフォルトではスケジュールされないことが望まれます. テイント トレランスが設定されている場合にのみ割り当てが許可されます.
• 特別なハードウェアを装備: 一部のノードには SSD ハード ドライブと GPU が装備されています. このノードはデフォルトでスケジュールされないことが望まれます. テイント トレランスが構成されている場合にのみ割り当てが許可されます.
• テイントベースのエビクション
5.2テイントと容認
ノード ラベルを表示する
pod3.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod3
spec:
containers:
- name: web
image: nginx
k8s-master1 と k8s-master2 をマークします。キー名は gpu、キー値は nvidia、効果は NoSchedule です。このテイントに一致する許容範囲を持つ Pod のみを 2 つのマスター ノードに割り当てることができることを示します。
kubectl taint node k8s-master1 gpu=nvidia:NoSchedule
kubectl taint node k8s-master2 gpu=nvidia:NoSchedule
2 つのノード ノードも汚染します
## k8s-node1 打上 GPU 污点
kubectl taint node k8s-node1 gpu=nvidia:NoSchedule
## k8s-node2 打上 ssd 污点
kubectl taint node k8s-node2 ssd=ssd:NoSchedule
## 起一个 Pod
apiVersion: v1
kind: Pod
metadata:
name: pod4
spec:
containers:
- name: web
image: nginx
pod4 が Pending 状態にあり、テイント トレランスを設定しないと Pod を正常にスケジュールできないことがわかります。
警告 FailedScheduling 24 秒のデフォルト スケジューラ 0/4 ノードが利用可能です: 1 つのノードに許容されない汚染 {ssd: ssd} があり、3 つのノードに許容されない汚染 {gpu: nvidia} がありました。プリエンプション: 0/4 ノードが利用可能: 4 プリエンプションはスケジューリングに役立ちません。
k8s-node2 に ssd テイント トレランスを追加し、k8s-node2 で pod5 をスケジュールできるようにします。
apiVersion: v1
kind: Pod
metadata:
name: pod5
spec:
tolerations:
- key: "ssd"
operator: "Equal"
value: "ssd"
effect: "NoSchedule"
containers:
- name: web
image: nginx
他のノードにはテイントがあり、node2 には ssd テイント トレランスがあるため、pod5 は node2 で正常に実行されます。
染み抜き
kubectl taint node k8s-master2 gpu=nvidia:NoSchedule-
kubectl taint node k8s-master1 gpu=nvidia:NoSchedule-
kubectl taint node k8s-node1 gpu=nvidia:NoSchedule-
kubectl taint node k8s-node2 ssd=ssd:NoSchedule-
6.ノード名
6.1 基本概念
nodeName は、affinity や nodeSelector よりも直接的な形式です。nodeName は Pod 仕様のフィールドです。nodeName フィールドが空でない場合、スケジューラは Pod を無視し、指定されたノードの kubelet は Pod をそのノードに配置しようとします。nodeName を使用するルールは、nodeSelector またはアフィニティと非アフィニティを使用するルールよりも優先されます。
nodeName を使用してノードを選択する方法には、いくつかの制限があります。
- 参照先のノードが存在しない場合、Pod は実行できず、場合によっては自動的に削除される可能性があります。
- 参照されたノードが Pod の実行に必要なリソースを提供できない場合、Pod は失敗し、失敗の理由はメモリまたは CPU の不足が原因で実行できないかどうかを示します。
- クラウド環境のノード名は常に予測できるとは限らず、常に安定しているわけでもありません。
6.2 NodeName フィールドの Pod 指定例
apiVersion: v1
kind: Pod
metadata:
name: pod6
spec:
containers:
- name: nginx
image: nginx
nodeName: k8s-node2
k8s-master1 と k8s-master2、および k8s-node1 と k8s-node2 の両方が染色されており、nodeName の優先度が高いため、Pod は正常にスケジュールされています。