Kubernetes は Pod オブジェクトのスケジューリングを深く理解しています

目次

1. ポッドのスケジューリング プロセス

2. コンテナ リソースの制限

2.1 メモリと CPU の制限

3.ノードセレクター

4.ノードの親和性

4.1 基本概念

4.2 ポッドの例

4.2.1 優先ノード アフィニティを使用した Pod のスケジューリング

4.2.2 必須のノード アフィニティに基づく Pod のスケジューリング 

5.汚染と寛容

5.1 基本概念

5.2テイントと容認

6.ノード名

6.1 基本概念

6.2 NodeName フィールドの Pod 指定例


1. ポッドのスケジューリング プロセス


Kubernetes は、list-watch メカニズムに基づくコントローラー アーキテクチャを使用して、コンポーネント間の相互作用を分離します。

他のコンポーネントは、担当するリソースを監視します. これらのリソースが変更されると、kube-apiserver はこれらのコンポーネントに通知します. このプロセスは、発行と購読に似ています.

スケジューリングの一般的なプロセス

  1. ユーザーは create yaml を使用して Pod を作成し、それを apiServer に要求し、apiserver は yaml 内の属性情報 (メタデータ) を etcd に書き込みます
  2. apiServer は監視メカニズムをトリガーして Pod を作成し、情報をスケジューラーに転送します。スケジューラーはスケジューリング アルゴリズムを使用してノードを選択し、スケジューラーはノード情報を apiServer に送信し、apiServer はバインドされたノード情報を etcd に書き込みます。
  3. apiServer は、watch メカニズムを介して kubelet を呼び出し、ポッド情報を指定し、docker run コマンドをトリガーしてコンテナーを作成します。
  4. 作成が完了すると kubelet にフィードバックされ、kubelet は Pod のステータス情報を apiserver に送信します。
  5. apiserver は Pod のステータス情報を etcd に書き込みます。
  6. その中で、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テイントと容認

テイントとトレランス | Kubernetes

ノード ラベルを表示する

 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 は正常にスケジュールされています。

 

 

おすすめ

転載: blog.csdn.net/qq_35995514/article/details/128054680