Kubernetesクラスタースケジューリング(ノードアフィニティ、ポッドアフィニティ、汚染および許容度)

ガイダンス:すべてのポッドのスケジュールがランダムなイベントであることがわかりました。ポッドがどのノードにスケジュールされるかわかりません。

1.はじめに

スケジューラーはkubernetesのスケジューラーであり、その主なタスクは、定義されたポッドをクラスターのノードに割り当てることです。非常に単純に聞こえますが、考慮すべき多くの問題があります。

  • 公平性:各ノードにリソースを割り当てることができるようにする方法
  • リソースの効率的な使用:クラスターのすべてのリソースが最大限に使用されます
  • 効率:スケジューリングのパフォーマンスが向上し、多数のポッドのスケジューリング作業をできるだけ早く完了することができます
  • 柔軟性:ユーザーが自分のニーズに応じてスケジューリングロジックを制御できるようにします

スケジューラは個別のプログラムとして実行されます。起動後、APIサーバーを維持し、PodSpec.NodeNameが空のポッドを取得し、ポッドを配置するノードを示す各ポッドのバインディング(従う必要があります)を作成します。

2つ目は、スケジューリングプロセスです。

スケジューリングはいくつかの部分に分かれています。

  1. 1つ目は、条件を満たさないノードを除外することです。このプロセスは、述語(事前選択)と呼ばれます。
  2. 次に、通過するノードを優先度に従って並べ替えます。これが優先度です(推奨)。
  3. 最後に、優先度が最も高いノードが選択されます。
    途中のいずれかのステップでエラーが発生した場合は、直接エラーに戻ります(最初に事前選択し、次に優先)

述語には、使用できる一連のアルゴリズムがあります。

  • PodFitsResources:ノード上の残りのリソースがポッドによって要求されたリソースよりも大きいかどうか
  • PodFitsHost:ポッドでNodeNameが指定されている場合は、ノード名がNodeNameと一致するかどうかを確認します
  • PodFitsHostPorts:ノードですでに使用されているポートは、ポッドによって要求されたポートと競合しますか?
  • PodSelectorMatches:ポッドで指定されたラベルと一致しないノードを除外します
  • NoDiskConflict:マウントされたボリュームは、両方が読み取り専用でない限り、ポッドによって指定されたボリュームと競合しません

述語処理中に適切なノードがない場合、ポッドは常に保留状態(保留中:待機中)になり、ノードが条件を満たすまでスケジューリングが再試行されます。この手順の後、複数のノードが条件を満たす場合は、優先度プロセスを続行します。優先度に従ってノードを並べ替えます。

優先度は一連のキーと値のペアで構成され、キーは優先度の高いアイテムの名前、値はその重み(アイテムの重要度)です。これらの優先オプションは次のとおりです。

  • LeastRequestedPriority:CPUとメモリの使用量を計算して重みを決定します。使用量が少ないほど、重みは大きくなります。つまり、この優先度インデックスは、リソース使用率が低いノードになりがちです。

  • BalancedResourceAllocation:ノードのCPUとメモリの使用率が近いほど、重みが大きくなります。これは、単独ではなく、上記と一緒に使用する必要があります

  • ImageLocalityPriority:ミラーリングを使用するノードがある傾向があり、ミラーの合計サイズが大きいほど、重みが大きくなります

アルゴリズムを使用してすべての優先項目と重みを計算し、最終結果を取得します

3つのカスタムスケジューラ

kubernetesに付属のスケジューラーに加えて、独自のスケジューラーを作成することもできます。spec:schedulernameパラメーターを使用してスケジューラーの名前を指定すると、スケジュールするポッドのスケジューラーを選択できます。たとえば、次のポッドは、デフォルトのdefault-schedulerの代わりにmy-schedulerをスケジューリングに選択します。

4.ノードアフィニティ(ポッドとノード間のアフィニティ)

pod.spec.nodeAffinity

  • PreferredDuringSchedulingIgnoredDuringExecution(優先実行計画):ソフト戦略
  • requiredDuringSchedulingIgnoredDuringExecution(必要な実行計画):ハード戦略

優先:優先、優先
必須:必須、必須

キー値操作関係

  • In:ラベルの値はリストにあります
  • NotIn:ラベルの値がリストにありません
  • Gt:ラベルの値が特定の値より大きい
  • Lt:ラベルの値が特定の値未満です
  • 存在する:ラベルが存在する
  • DoesNotExist:ラベルが存在しません

1.ハード戦略:requiredDuringSchedulingIgnoredDuringExecution

#节点硬策略。排除node02,只能在node01上运行
apiVersion: v1
kind: Pod
metadata:
  name: affinity
  labels:
    app: node-affinity-pod
spec:
  containers:
  - name: with-node-affinity
    image: hub.atguigu.com/library/myapp:v1
  affinity:            #亲和性
    nodeAffinity:        #node亲和性
      # 硬亲和性限制
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/hostname # 标签键名
            operator: NotIn      #键值运算关系 ,NotIn:label的值不在某个列表中。 表示不是node02节点就可运行
            values:
            - k8s-node02 # 标签键值

kubectl get node --show-labels
mkdir affi
cd affi
vim pod1.yaml
kubectl create -f pod1.yaml
kubectl get pod -o wide
ここに写真の説明を挿入

kubectl delete pod --all && kubectl create -f pod1.yaml && kubectl get pod -o wide
ここに写真の説明を挿入
 
change pod1.yaml to In node3。
ここに写真の説明を挿入
ただし、node3ノードがないため、保留状態になっています。これは難しい戦略です。
ここに写真の説明を挿入

2.ソフト戦略:preferredDuringSchedulingIgnoredDuringExecution
は、存在する場合は実行され、存在しない場合は
vimpod2.yamlで実行されます。

#软策略
apiVersion: v1
kind: Pod
metadata:
  name: affinity2
  labels:
    app: node-affinity-pod
spec:
  containers:
  - name: with-node-affinity
    image: hub.atguigu.com/library/myapp:v1
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1   #权重,权重越大越亲和(多个软策略的情况)
        preference: 
          matchExpressions:
          - key: kubernetes.io/hostname
            operator: In
            values:
            - k8s-node03  # 期望是node03

 查看:kubectl get node --show-labels

ここに写真の説明を挿入

3.ソフト戦略とハード戦略(最初にハード戦略を満たし、次にソフト戦略を満たします)

#软硬合体
apiVersion: v1
kind: Pod
metadata:
  name: affinity2
  labels:
    app: node-affinity-pod
spec:
  containers:
  - name: with-node-affinity
    image: hub.atguigu.com/library/myapp:v1
  affinity:
    nodeAffinity:        #node亲和性
      # 硬亲和性限制
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/hostname # 标签键名
            operator: NotIn      #键值运算关系 ,NotIn:label的值不在某个列表中。 表示不是node02节点就可运行
            values:
            - k8s-node02 # 标签键值
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1   #权重,权重越大越亲和(多个软策略的情况)
        preference: 
          matchExpressions:
          - key: kubernetes.io/hostname
            operator: In
            values:
            - k8s-node03  # 期望是node03

5.ポッドアフィニティ(ポッドとポッド間のアフィニティ)

pod.spec.affinity.podAffinity / podAntiAffinity

  • PreferredDuringSchedulingIgnoredDuringExecution:ソフト戦略
  • requiredDuringSchedulingIgnoredDuringExecution:ハード戦略

アフィニティ/非アフィニティスケジューリング戦略は、次のように比較されます
ここに写真の説明を挿入
 
。kubectlget pod --show-labels
ここに写真の説明を挿入

vim pod3.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-3
  labels:
    app: pod-3
spec:
  containers:
  - name: pod-3
    image: hub.atguigu.com/library/myapp:v1
  affinity:
    #想让两个pod运行在同一个node上
    podAffinity:
      #硬策略
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:  #标签选择
          matchExpressions:
          - key: app #当app存在node-affinity-pod时就选择
            operator: In
            values: 
            - node-affinity-pod
        topologyKey: kubernetes.io/hostname 
        #hostname判断是否在同一个pod,唯一

同じトポロジドメインで見つかりましたtopologyKeyvim
ここに写真の説明を挿入
 
pod4.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-4
  labels:
    app: pod-4
spec:
  containers:
  - name: pod-4
    image: hub.atguigu.com/library/myapp:v1
  affinity:
    #不想让两个pod运行在同一个node上
    #匹配标签如果app=pod-2,那么则不运行在这个节点
    podAntiAffinity:
      #软策略
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: app #匹配app=node-affinity-pod
              operator: In
              values:
              - node-affinity-pod
          topologyKey: kubernetes.io/hostname

ここに写真の説明を挿入
補足:ラベルが満たされない場合、ラベルを変更すると
kubectl label pod podnameapp = label--overwrite = trueを満たすことができます

 

シックス、汚染と寛容

ノードアフィニティはポッドの属性(優先度またはハード要件)であり、ポッドを特定のタイプのノードに引き付けます。汚染は反対で、ノードが特定のタイプのポッドを除外できるようにします

汚染と耐性が連携して、ポッドが不適切なノードに割り当てられるのを防ぎます。各ノードに1つ以上の汚染を適用できます。つまり、これらの汚染に耐えられないポッドはノードに受け入れられません。許容誤差がポッドに適用される場合、これらのポッドは、汚染が一致するノードにスケジュールできる(必須ではない)ことを意味します。

汚染

1.汚染の構成(汚染)
kubectl taintコマンドを使用して、ノードノードに汚染を設定します。ノードが汚染された後、ポッドとの排他的な関係があり、ノードはポッドのスケジュールされた実行を拒否できます。既存のノードのポッドを追い出します。各汚染の構成は次のとおりです。

key=value:effect

各汚染には、汚染のラベルとしてキーと値があり、値は空にすることができ、効果は汚染の役割を説明します。現在の汚染効果は、次の3つのオプションをサポートしています。

  • NoSchedule:k8sがこの汚染でノードにポッドをスケジュールしないことを意味します
    (K8Snodeはこのeffecfタイプの汚染を追加し、新しい耐えられないポッドを再度スケジュールすることはできませんが、ノードで実行されている古いものは影響を受けません)
  • PreferNoSchedule:k8sがポッドを汚染のあるノードにスケジュールせず、ノードにすでに存在するポッドを追い出すことを示します(ポッドはポッドをノードに割り当てようとします)
  • NoExecute:k8sがこの汚染でノードへのポッドのスケジュールを回避しようとすることを意味します
    (K8Snodeはこのeffecfタイプの汚染を追加し、新しい耐えられないポッドはスケジュールできず、古いポッドも削除されます)

これが、生成されたポッドがマスターに割り当てられない理由です(汚染されたNoScheduleが作成されたため)
ここに写真の説明を挿入

2.汚れの設定、表示、除去

#查看节点污点
模板:kubectl describe node node-name
kubectl describe node k8s-node01

# 设置污点
模板:kubectl taint nodes node1 key1=value1:NoSchedule
kubectl taint nodes k8s-node01 check=guozige:NoExecute 
因为pod是自主式pod,没有控制器控制的pod。去除后就不存在了
如果是Deployment和StatefullSet,它就会在node02上创建,维持副本数

# 节点说明中,查找 Taints 字段
kubectl describe node k8s-node01

# 去除污点
模板:kubectl taint nodes node1 key1=value1:NoSchedule-
kubectl taint nodes k8s-node01 check=guozige:NoExecute-

ステインテストを設定する
ここに写真の説明を挿入

 

許容範囲

汚染されたノードは、汚染効果(NoSchedule、PreferNoSchedule、NoExecute、およびPod)の間で相互に排他的な関係になります。ポッドは、ノードに対してある程度スケジュールされません。ただし、ポッドに許容値を設定することはできます(許容値)。つまり、許容するように設定されたポッドは、汚染の存在を許容し、汚染のあるノードにスケジュールすることができます。

pod.spec.tolerations

tolerations:  #containers同级
- key: "check"  #能容忍的污点key
  operator: "Equal"  #Equal等于表示key=value , Exists不等于,表示当值不等于下面value正常
  value: "guozige"  #值
  effect: "NoExecute"  #effect策略
  tolerationSeconds: 3600  #原始的pod多久驱逐,注意只有effect: "NoExecute"才能设置,不然报错
  • キー、値、効果は、ノードに設定された汚染と一致している必要があります
  • 演算子の値はExistsであり、値の値は無視されます
  • tolerationSecondsは、ポッドを削除する必要があるときにポッドを実行し続けることができる時間を表すために使用されます

pod3.yaml vim
ここに写真の説明を挿入kubectl the Apply -f pod3.yaml
kubectl GET POD -o広く
許容される汚れ
ここに写真の説明を挿入

 
1.キー値が指定されていない場合、それはすべての汚染されたキーが許容されることを意味します。

tolerations:
- operator: "Exists"

2.効果値が指定されていない場合、それはすべての汚染効果が許容されることを意味します

tolerations:
- key: "key"
  operator: "Exists"

3.マスターが複数ある場合、リソースの浪費を防ぐために、次のように設定できます。

kubectl taint nodes Node-Name node-role.kubernetes.io/master=:PreferNoSchedule

PreferNoSchedule
尽可能不在该节点上运行,只有当节点资源不够用才运行

ノード障害後のポッド再スケジュール時間を構成します

たとえば、次の構成ファイルでは、notReadyおよびunreachable状態のノードの場合、そのポッドは300秒間待機し、それでも回復しない場合は実行を停止します。

 

8つの指定されたスケジューリングノード

親和性と汚れ、耐性はより微妙です。
指定されたスケジューリングノードは絶対的に指定されたターゲットであるため、これは

1. Pod.spec.nodeNameは、指定されたノードノードに直接Podをスケジュールし、Schedulerのスケジュールポリシーをスキップします。一致ルールは、
vimpod5.yamlの一致を強制することです。

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: myweb
spec:
  replicas: 7
  template:
    metadata:
      labels:
        app: myweb
    spec:
      nodeName: k8s-node01 #指定全在node01
      containers:
      - name: myweb
        image: hub.atguigu.com/library/myapp:v1
        ports:
        - containerPort: 80

ここに写真の説明を挿入

2. Pod.spec.nodeSelector:kubernetesのラベルセレクタメカニズムを介してノードを選択し、スケジューラのスケジューリング戦略がラベルを照合してから、ポッドをターゲットノードにスケジュールします。この照合ルールは必須の制約です。

vim pod6.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: myweb66
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: myweb66
  spec:
    nodeSelector:
      disk: ssd  #硬盘必须是ssd类型才运行
      #type: backEndNode1 #标签名,标签值
    containers:
    - name: myweb66
      image: hub.atguigu.com/library/myapp:v1
      ports:
      - containerPort: 80

テスト検証

kubectl label node k8s-node01 disk=ssd


kubectl label node k8s-node02 disk=ssd
kubectl edit deployment myweb66  增加副本数目
kubectl get pod 发现有些在node02上了 

おすすめ

転載: blog.csdn.net/qq_39578545/article/details/108936363