企業実戦--kubernetes(十五)---k 8 sスケジューリング


一、kubernetesスケジューリング
スケジューラはkubernetesのwatchメカニズムによってクラスタ内で新しく作成され、ノード上のPodにスケジューリングされていないことを発見する.スケジューラは、検出された各未スケジュールのPodを適切なノードにスケジューリングして実行します.
**kube-schedulerはKubernetesクラスタのデフォルトスケジューラであり、**はクラスタ制御面の一部である.もしあなたが本当にこの方面の需要を望んでいるか、あるいはこの方面の需要があるならば、kube-schedulerは設計の上であなたが自分でスケジューリングコンポーネントを書いて、元のkube-schedulerを置き換えることを許可します.
スケジューリングの決定に際して考慮すべき要因は、単独および全体のリソース要求、ハードウェア/ソフトウェア/ポリシー制限、親和性および反親和性要件、データローカル性、負荷間の干渉などである.
二、nodeName方式のスケジューリング
NodeNameはノード選択コンストレイントの最も簡単な方法ですが、一般的には推奨されません.NodeNameがPodSpecで指定されている場合は、他のノードの選択方法よりも優先されます.
ノードの制限を選択するには、nodeNameを使用します.
          。
               pod, pod     。
                    。

例:
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx
  nodeName: server3

このpodを実行すると、podはserver 3にスケジューリングされ、server 3というノードにリソースが足りないなどの問題が発生した場合、他の健康なノードがあってもこのpodはserver 3にスケジューリングされ、結果としてスケジューリングに失敗します.
三、nodeSelector方式のスケジューリング
NodeSelectorは、ノード選択コンストレイントの最も簡単な推奨形式です.
選択したノードにラベルを追加するには、次の手順に従います.
kubectl label nodes server2 disktype=ssd

ノードラベルを表示するには、次のコマンドを使用します.
kubectl get nodes --show-labels

nodeSelectorフィールドをpod構成に追加します.
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  nodeSelector:
    disktype: ssd

このpodはdisktype:ssdラベルのあるノードserver 2にスケジューリングされる.
四、親和と反親和スケジューリング
NodeSelectorはpodを特定のラベルを持つノードに制約する非常に簡単な方法を提供します.親和/反親和機能は、制約を表現できるタイプを大きく拡張します.
ルールは「ソフト」/「好み」であり、ハードな要件ではないことがわかります.そのため、スケジューラが要件を満たすことができない場合はpodをスケジューリングします.
ノード自体のラベルではなく、ノード上のpodのラベルを使用して制約することができます.どのpodが一緒に配置できるか、一緒に配置できないかを許可します.
ノード親和性nodeaffinity
Nodeaffinityは、複数のルールマッチング条件の構成をサポートします.
In:label       
NotIn:label        
Gt:label         ,   Pod   
Lt:label         ,   pod   
Exists:   label   
DoesNotExist:    label    
requiredDuringSchedulingIgnoredDuringExecutionpreferredDuringSchedulingIgnoredDuringExecutionの傾向を満たさなければならない.IgnoreDuringExecution は、Podの実行中にノードのラベルが変化し、親和性ポリシーが満たされない場合、現在のPodを実行し続けることを示す.
ノード親和性podの例:
apiVersion: v1
kind: Pod
metadata:
  name: node-affinity
spec:
  containers:
  - name: nginx
    image: nginx
  affinity:
    nodeAffinity:    #    
      requiredDuringSchedulingIgnoredDuringExecution: #    
           nodeSelectorTerms:
           - matchExpressions:
             - key: disktype
               operator: In
               values:
                 - ssd

上記の配置ファイルは、podがdisktype:ssdラベルのあるノードにスケジューリングされる必要があることを示しています.valuesの値は、次のように複数あります.
apiVersion: v1
kind: Pod
metadata:
  name: node-affinity
spec:
  containers:
  - name: nginx
    image: nginx
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
           nodeSelectorTerms:
           - matchExpressions:
             - key: disktype
               operator: In
               values:
                 - ssd
                 - sata

このノード親和規則は、podがラベルキーがdisktypeであり、ラベル値がssdまたはsataのノードにのみ配置されることを示す.
もちろん、ソフトリミット(preferredは必須ではありません)とハードリミット(required必須)を組み合わせることもできます.
apiVersion: v1
kind: Pod
metadata:
  name: node-affinity
spec:
  containers:
  - name: nginx
    image: nginx
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
           nodeSelectorTerms:
           - matchExpressions:
             - key: kubernetes.io/hostname
               operator: NotIn
               values:
               - server2
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: disktype
            operator: In
            values:
            - ssd     

このノード親和規則はpodをserver 2ノードに置くことができず、残りのノードではラベルキーがdisktypeでラベル値がssdのノードを優先して使用すべきであり、このlabelを満たすノードがなければserver 2以外のノードをスケジューリングすることもできることを示している.
pod親和性と反親和性podAffinityは主にPODがどのPODと同じトポロジードメインに配置できるかという問題を解決する(トポロジードメインはホストラベルで実現され、単一ホストであってもよいし、複数のホストからなるcluster、zoneなどであってもよい).podAntiAffinityは、PODが同じトポロジードメインに配置できない問題を主に解決します.それらはKubernetesクラスタ内部のPODとPODの関係を処理する.
Pod間親和性および逆親和性は、より高いレベルの集合(例えば、ReplicaSets、StatefulSets、Deploymentsなど)とともに使用される場合、より有用である可能性がある.同じ定義トポロジ(ノードなど)に存在するワークロードのセットを簡単に構成できます.
Pod親和と反親和の合法オペレータにはIn,NotIn,Exists,DoesNotExistがある.
pod親和性の例:
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx

まずapp:nginxラベルを持つpodを作成し,次にこのラベルに基づいてpod親和性と逆親和性を実現する.pod親和性の例:
apiVersion: v1
kind: Pod
metadata:
  name: mysql
  labels:
    app: mysql
spec:
  containers:
  - name: mysql
    image: mysql
    env:
     - name: "MYSQL_ROOT_PASSWORD"
       value: "westos"
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - nginx
        topologyKey: kubernetes.io/hostname			#           

上記の配置ファイルは、このpodがapp:nginxラベルのあるpodの同じノードにスケジューリングされる必要があるため、このpodと前のpodは1つのノードにスケジューリングされることを示しています.
pod反親和性の例:
apiVersion: v1
kind: Pod
metadata:
  name: mysql
  labels:
    app: mysql
spec:
  containers:
  - name: mysql
    image: mysql
    env:
     - name: "MYSQL_ROOT_PASSWORD"
       value: "westos"
  affinity:
    podAntiAffinity:		#                 
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - nginx
        topologyKey: "kubernetes.io/hostname"

上記の配置ファイルは、このpodがapp:nginxラベルのあるpodの同じノードにスケジューリングされない必要があるため、このpodと前のpodは異なるノードにスケジューリングされることを示しています.
もちろん、ノード親和のようにソフトリミットとハードリミットを設定したり、結合したりすることもできます.
五、Taints汚点スケジューリング
NodeAffinityノードの親和性は、Podが私たちの要求に従ってノードにスケジューリングできるようにしますが、Taintsは正反対で、ノードがPodの実行を拒否したり、Podを駆逐したりすることができます.
Taints(汚点)はノードの属性であり、Taintsを設定するとKubernetesはこのノードにPodをスケジューリングしないので、KubernetesはPodに属性Tolerations(許容)を設定し、Podがノード上の汚点を許容できる限り、KubernetesはNode上の汚点を無視し、Podをスケジューリングすることができる.
コマンドkubectl taintを使用して、ノードにtaintを追加できます.
$ kubectl taint nodes node1 key=value:NoSchedule	//  
$ kubectl describe nodes  server1 |grep Taints		//  
$ kubectl taint nodes node1 key:NoSchedule-		//  

ここで[effect]の値は、[NoSchedule|PreferNoSchedule|NoExecute]
NoSchedule:POD           taints   。
PreferNoSchedule:NoSchedule       。
NoExecute:         Taint   ,           POD      Tolerate   ,      。

注意:汚れをNoScheduleに設定しても既存のpodには影響しません.NoExecuteは既存のpod(駆逐)に影響します.
クエリーコマンドを使用してマスターノードの汚れを表示すると、マスターノードにはデフォルトでNoScheduleの汚れがあることがわかります.したがって、デフォルトではpodの作成はマスターノードにスケジューリングされず、他のノードには汚れがありません.
導入nginx deploymentの例:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-server
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx

このpodを作成します.
サーバ2ノードにtaintを打つ:
$ kubectl taint node  server2 key1=v1:NoExecute
	node/server2 tainted

サーバ2上のPodが駆除されていることがわかります.
$ kubectl get pod -o wide
NAME                          READY   STATUS              RESTARTS   AGE   IP             NODE      NOMINATED NODE   READINESS GATES
web-server-86c57db685-9r5pn   1/1     Running             0          80s   10.244.1.158   server2   <none>           <none>
web-server-86c57db685-d87lc   0/1     ContainerCreating   0          7s    <none>         server2   <none>           <none>
web-server-86c57db685-gsqvt   1/1     Running             0          80s   10.244.2.143   server3   <none>           <none>
web-server-86c57db685-sk4t4   0/1     Terminating         0          80s   10.244.0.79    server1   <none>           <none>

PodSpecでコンテナに許容ラベルを設定します.
 tolerations:
  - key: "key1"
    operator: "Equal"
    value: "v1"
    effect: "NoExecute"

Podに許容値を設定すると、server 2はまたPodを実行できます.
tolerationsの例:
tolerations:
- key: "key"
  operator: "Equal"
  value: "value"
  effect: "NoSchedule"
---
tolerations:
- key: "key"
  operator: "Exists"
  effect: "NoSchedule"

tolerationsで定義したkey、value、effectは、nodeで設定したtaintと一致するようにします.
   operator   Exists ,value    。
   operator   Equal , key value         。
     operator  ,     Equal。

2つの特殊な値があります.
    key,   Exists        key value ,        。
    effect ,      effect。

たとえば、すべての汚点を許容するには、許容ルールを設定します.
tolerations:
  operator: "Exists"

実験後,すべてのノードの汚点を元に戻すことに注意した.
六、cordon、drain、delete方式スケジューリング
Podスケジューリングに影響を与える命令には、cordon、drain、deleteがあり、後期に作成されたpodはこのノードにスケジューリングされませんが、操作の暴力の程度は異なります.
cordonスケジューリング停止
影響は最小で、nodeをSchedulingDisabledに変更するだけで、podを新しく作成して、このノードにスケジューリングされず、ノードの元のpodは影響を受けず、依然として正常に対外的にサービスを提供しています.
$ kubectl cordon server3
$ kubectl  get node
NAME      STATUS                     ROLES    AGE   VERSION
server1   Ready                      <none>   29m   v1.17.2
server2   Ready                      <none>   12d   v1.17.2
server3   Ready,SchedulingDisabled   <none>   9d    v1.17.2
$ kubectl uncordon server3 		//  

drain駆逐ノード
まずnode上のpodを駆逐し、他のノードで再作成し、ノードをSchedulingDisabledにします.
$ kubectl  drain server3 --ignore-daemonsets
node/server3 cordoned
evicting pod "web-1"
evicting pod "coredns-9d85f5447-mgg2k"
pod/coredns-9d85f5447-mgg2k evicted
pod/web-1 evicted
node/server3 evicted
$ kubectl uncordon server3			#  

deleteノードの削除
最も暴力的な1つは、まずnode上のpodを駆逐し、他のノードで再作成し、その後、masterノードからnodeを削除し、masterはその制御を失い、スケジューリングを回復するにはnodeノードに入り、kubeletサービスを再起動する必要がある.
$ kubectl delete node server3

サーバ3で実行されるリカバリスケジュール:
# systemctl restart kubelet	

以上のコマンドはnodeの自己登録機能に基づいて、使用を再開します.