企業実戦--kubernetes(十五)---k 8 sスケジューリング
12478 ワード
一、kubernetesスケジューリング
スケジューラはkubernetesのwatchメカニズムによってクラスタ内で新しく作成され、ノード上のPodにスケジューリングされていないことを発見する.スケジューラは、検出された各未スケジュールのPodを適切なノードにスケジューリングして実行します.
**kube-schedulerはKubernetesクラスタのデフォルトスケジューラであり、**はクラスタ制御面の一部である.もしあなたが本当にこの方面の需要を望んでいるか、あるいはこの方面の需要があるならば、kube-schedulerは設計の上であなたが自分でスケジューリングコンポーネントを書いて、元のkube-schedulerを置き換えることを許可します.
スケジューリングの決定に際して考慮すべき要因は、単独および全体のリソース要求、ハードウェア/ソフトウェア/ポリシー制限、親和性および反親和性要件、データローカル性、負荷間の干渉などである.
二、nodeName方式のスケジューリング
NodeNameはノード選択コンストレイントの最も簡単な方法ですが、一般的には推奨されません.NodeNameがPodSpecで指定されている場合は、他のノードの選択方法よりも優先されます.
ノードの制限を選択するには、nodeNameを使用します.
例:
このpodを実行すると、podはserver 3にスケジューリングされ、server 3というノードにリソースが足りないなどの問題が発生した場合、他の健康なノードがあってもこのpodはserver 3にスケジューリングされ、結果としてスケジューリングに失敗します.
三、nodeSelector方式のスケジューリング
NodeSelectorは、ノード選択コンストレイントの最も簡単な推奨形式です.
選択したノードにラベルを追加するには、次の手順に従います.
ノードラベルを表示するには、次のコマンドを使用します.
nodeSelectorフィールドをpod構成に追加します.
このpodはdisktype:ssdラベルのあるノードserver 2にスケジューリングされる.
四、親和と反親和スケジューリング
NodeSelectorはpodを特定のラベルを持つノードに制約する非常に簡単な方法を提供します.親和/反親和機能は、制約を表現できるタイプを大きく拡張します.
ルールは「ソフト」/「好み」であり、ハードな要件ではないことがわかります.そのため、スケジューラが要件を満たすことができない場合はpodをスケジューリングします.
ノード自体のラベルではなく、ノード上のpodのラベルを使用して制約することができます.どのpodが一緒に配置できるか、一緒に配置できないかを許可します.
ノード親和性nodeaffinity
Nodeaffinityは、複数のルールマッチング条件の構成をサポートします.
ノード親和性podの例:
上記の配置ファイルは、podがdisktype:ssdラベルのあるノードにスケジューリングされる必要があることを示しています.valuesの値は、次のように複数あります.
このノード親和規則は、podがラベルキーがdisktypeであり、ラベル値がssdまたはsataのノードにのみ配置されることを示す.
もちろん、ソフトリミット(preferredは必須ではありません)とハードリミット(required必須)を組み合わせることもできます.
このノード親和規則はpodをserver 2ノードに置くことができず、残りのノードではラベルキーがdisktypeでラベル値がssdのノードを優先して使用すべきであり、このlabelを満たすノードがなければserver 2以外のノードをスケジューリングすることもできることを示している.
pod親和性と反親和性
Pod間親和性および逆親和性は、より高いレベルの集合(例えば、ReplicaSets、StatefulSets、Deploymentsなど)とともに使用される場合、より有用である可能性がある.同じ定義トポロジ(ノードなど)に存在するワークロードのセットを簡単に構成できます.
Pod親和と反親和の合法オペレータにはIn,NotIn,Exists,DoesNotExistがある.
pod親和性の例:
まずapp:nginxラベルを持つpodを作成し,次にこのラベルに基づいてpod親和性と逆親和性を実現する.pod親和性の例:
上記の配置ファイルは、このpodがapp:nginxラベルのあるpodの同じノードにスケジューリングされる必要があるため、このpodと前のpodは1つのノードにスケジューリングされることを示しています.
pod反親和性の例:
上記の配置ファイルは、この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を追加できます.
ここで[effect]の値は、[NoSchedule|PreferNoSchedule|NoExecute]
注意:汚れをNoScheduleに設定しても既存のpodには影響しません.NoExecuteは既存のpod(駆逐)に影響します.
クエリーコマンドを使用してマスターノードの汚れを表示すると、マスターノードにはデフォルトでNoScheduleの汚れがあることがわかります.したがって、デフォルトではpodの作成はマスターノードにスケジューリングされず、他のノードには汚れがありません.
導入nginx deploymentの例:
このpodを作成します.
サーバ2ノードにtaintを打つ:
サーバ2上のPodが駆除されていることがわかります.
PodSpecでコンテナに許容ラベルを設定します.
Podに許容値を設定すると、server 2はまたPodを実行できます.
tolerationsの例:
tolerationsで定義したkey、value、effectは、nodeで設定したtaintと一致するようにします.
2つの特殊な値があります.
たとえば、すべての汚点を許容するには、許容ルールを設定します.
実験後,すべてのノードの汚点を元に戻すことに注意した.
六、cordon、drain、delete方式スケジューリング
Podスケジューリングに影響を与える命令には、cordon、drain、deleteがあり、後期に作成されたpodはこのノードにスケジューリングされませんが、操作の暴力の程度は異なります.
cordonスケジューリング停止
影響は最小で、nodeをSchedulingDisabledに変更するだけで、podを新しく作成して、このノードにスケジューリングされず、ノードの元のpodは影響を受けず、依然として正常に対外的にサービスを提供しています.
drain駆逐ノード
まずnode上のpodを駆逐し、他のノードで再作成し、ノードをSchedulingDisabledにします.
deleteノードの削除
最も暴力的な1つは、まずnode上のpodを駆逐し、他のノードで再作成し、その後、masterノードからnodeを削除し、masterはその制御を失い、スケジューリングを回復するにはnodeノードに入り、kubeletサービスを再起動する必要がある.
サーバ3で実行されるリカバリスケジュール:
以上のコマンドはnodeの自己登録機能に基づいて、使用を再開します.
スケジューラは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
requiredDuringSchedulingIgnoredDuringExecution
はpreferredDuringSchedulingIgnoredDuringExecution
の傾向を満たさなければならない.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の自己登録機能に基づいて、使用を再開します.