Kubernetes ツアー: Kube-Scheduler

Kubernetes ツアー: Kube-Scheduler

概要

kube-scheduler とは何ですか?

Kubernetes クラスターのコア コンポーネントの 1 つであり、新しく作成された Pod にノードを割り当てる役割を担います。次のようなさまざまな要素に基づいて決定が下されます。

1. リソースの要件と制限: 各ポッドによって要求されるリソース (CPU やメモリなど) の量とノードで使用可能なリソースを考慮します。

2. アフィニティ ルールとアンチアフィニティ ルール: Pod のアフィニティ設定に基づいて最適なノードを選択します。

3. ヘルスチェック: 選択したノードが正常であり、ポッドを実行できることを確認します。

4. 負荷分散: クラスター内の各ノードの負荷を分散するようにします。

使用

制限と要件

デプロイメント オブジェクトの仕様では、制限と要求に関する宣言がよく見られます。次に例を示します。

 apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx resources: limits: memory: 1Gi cpu: 1 requests: memory: 256Mi cpu: 100m

ここで、制限とリクエストは、Pod コンテナのリソース管理に関連する 2 つの重要な概念です。

• 制限: コンテナの実行時に使用できるリソースの最大量を指定します。

• リクエスト: コンテナを起動するために必要な最小限のリソースを指定します

制限とリクエストとスケジューラの関係は何ですか?

クラスターでは、kube-scheduler は常に静かに舞台裏で動作していました。主な業務内容は以下のとおりです。

1. この nginx のようなデプロイメントを作成すると、どのノードで実行するかをスケジュールするのは kube-scheduler によって決定されます。

2. kube-schedulerはapiserverをリッスンしてクラスターのグローバルビューを取得し、Podのリソース要求(要求と制限)を分析します。

3. 最後に、kube-scheduler はリソース要求とクラスターの実際の状況に基づいて Pod をスケジュールします。

つまり、kube-scheduler は、実行中のリソース要件を満たすノードに Pod がスケジュールされるようにします。

制限範囲

説明する

LimitRange はリソース記述オブジェクトであり、主に名前空間内のリソースの使用を制限するために使用されます。デフォルトのリソース要求と制限、およびリソース使用量の最大値と最小値を設定できます。これにより、各ポッドまたはコンテナがリソース使用に関して特定のポリシーに従うようになり、単一のポッドまたはコンテナが過剰なリソースを占有することがなくなります。以下に使用例をいくつか示します。

LimitRange コンテンツを保存する YAML ファイルを作成します (例: mem-limit-range.yaml)。

 apiVersion: v1 kind: LimitRange metadata: name: mem-limit-range spec: limits: - default: memory: 512Mi defaultRequest: memory: 256Mi type: Container

クラスターに適用します。

 $ kubectl apply -f mem-limit-range.yaml

作成された LimitRange オブジェクトを表示します。

 $ kubectl describe limitrange mem-limit-range

出力:

 Name: mem-limit-range Namespace: default Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio ---- -------- --- --- --------------- ------------- ----------------------- Container memory - - 256Mi 512Mi -

例:

• Kind: 名前空間内のリソースの使用を制限するには、LimitRange に設定します。

• メタデータ: リソースの名前を設定する

• 仕様:

制限:

デフォルト: 明示的なリソース制限のないコンテナのデフォルトのメモリ制限が512 Miであることを指定します。

defaultRequest: 明示的なリソース要求を持たないコンテナーのデフォルトのメモリ要求を指定します。ここでは256Miに設定されています

type: これらの制限が適用されるリソースの種類。この場合はコンテナ

確認する

リソース要求を宣言せずにデプロイメント オブジェクトを定義します。ファイル名は nginx-without-resource.yaml で、次のようになります。

 apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx

アプリケーションをクラスターにデプロイします。

 $ kubectl apply -f nginx-without-resource.yaml

Pod が作成された後、その構成をチェックして、LimitRange が有効になっているかどうかを確認できます。

 $ kubectl describe pod [POD_NAME]

出力:

 Containers: #.. ignore Limits: memory: 512Mi Requests: memory: 256Mi

コンテナの初期化

initContainers は、メイン アプリケーション コンテナーが起動される前にいくつかの予備タスクを実行するために使用されます。次のようなシナリオでよく見られます:

  1. 1. 準備: 必要な構成ファイルを設定し、データベースを移行し、他のサービスの準備が整うのを待つなどします。
  2. 2. セキュリティ: ファイル権限の変更や特定のセキュリティ チェックの実行などの権限昇格操作。
  3. 3. サービス依存性: 他のサービスまたはデータベースが利用可能になるまで待機します。

initContainers はタスクを実行した後に停止し、メイン コンテナーを起動する前に正常に完了する必要があります。起動前の初期化タスクに非常に適しています。

例:

デプロイメント オブジェクトで initContainers プロパティを宣言します。

 apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: initContainers: - name: init-myservice image: busybox:1.28 command: ['sh', '-c', 'echo The app is running! && sleep 10'] containers: - name: nginx image: nginx

デプロイメント オブジェクトをクラスターに適用します。

 $ kubectl apply -f init-container.yaml

Pod が起動すると、イベント ログを表示して、コンテナーがロードされる順序を確認できます。

 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 2m20s default-scheduler Successfully assigned default/nginx-deployment-6445f86ddc-fmmzw to docker-desktop Normal Pulling 2m20s kubelet Pulling image "busybox:1.28" Normal Pulled 116s kubelet Successfully pulled image "busybox:1.28" in 23.099396719s (23.099404677s including waiting) Normal Created 116s kubelet Created container init-myservice Normal Started 116s kubelet Started container init-myservice Normal Pulling 106s kubelet Pulling image "nginx" Normal Pulled 88s kubelet Successfully pulled image "nginx" in 18.382000675s (18.382006008s including waiting) Normal Created 88s kubelet Created container nginx Normal Started 88s kubelet Started container nginx

initContainers によって宣言されたコンテナがロードされたことを確認し、特定のログを表示して Pod ログ出力をチェックします。

 $ kubectl logs [POD_NAME] -c init-myservice

出力:

 The app is running!

検証が完了しました。

initContainers と kube-scheduler の関係は何ですか?

initContainers がリソース要件を宣言しない場合は、LimitRange によって宣言されたデフォルトのリソースがデフォルトで使用されます。つまり、initContainers も kube-scheduler によってスケジュールされ、作成されることになります。したがって、initContainers にリソース要件を追加すると、kube-scheduler のスケジュール決定にも影響します。

ノードセレクタ

デプロイメント オブジェクトでは、nodeSelector 属性を使用して、指定された Pod を特定のラベルを持つノードにスケジュールします。要件を満たすノードがない場合、ポッドは待機を続けます。例:

 apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx nodeSelector: disktype: ssd

この例では、nodeSelector プロパティの値は disktype: ssd です。これは、このポッドをラベル disktype=ssd を持つノードにスケジュールする必要があることを示します。スケジュール設定時に、kube-scheduler はこの Pod を実行するのに適したノードを選択します。

まず、デプロイメント オブジェクトをクラスターに適用します。

 $ kubectl apply -f node-selector.yaml

次に、ポッドのステータスを確認します。

 $ kubectl get pod

出力:

 NAME READY STATUS RESTARTS AGE nginx-deployment-f5bc98d57-pmq9v 0/1 Pending 0 2m17s

作成された Pod が「保留中」状態のままであることがわかります。具体的な原因についてはイベント ログを確認してください。

 $ kubectl describe pod [POD_NAME]

出力:

 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 4m38s default-scheduler 0/1 nodes are available: 1 node(s) didn't match Pod's node affinity/selector. preemption: 0/1 nodes are available: 1 Preemption is not helpful for scheduling..

イベント ログから、設定されたノード選択基準を満たすノードがないため、このポッドをスケジュールできないことがわかります。クラスター内に disktype: ssd とマークされたノードが実際には実行されていないためです。

親和性

NodeSelector の進化版で、より複雑な選択ルールを提供します。単純なマッチングに加えて、「存在する」、「等しくない」、「セット内にある」などのより豊富な条件式もサポートし、ポッド間 (ポッド アフィニティ/アンチ アフィニティ) およびポッドとノード間 (ノード アフィニティ) のアフィニティ/アンチ アフィニティ設定もサポートします。 Kubernetes のその後のバージョンでは、Affinity が徐々に NodeSelector に取って代わりました。

ポッドアフィニティ

podAffinity は、Pod 間のアフィニティを定義するために使用されます。これにより、特定のラベルを持つ他のポッドと同じノードにポッドをスケジュールできるようになります。

使用例: アプリケーションのさまざまなコンポーネントで低遅延の通信が必要な場合など、サービスのグループを緊密に連携させたい場合。

例:

 apiVersion: apps/v1 kind: Deployment metadata: name: nginx-anti spec: replicas: 2 selector: matchLabels: app: anti-nginx template: metadata: labels: app: anti-nginx spec: affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: a operator: In values: - b topologyKey: kubernetes.io/hostname podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - anti-nginx topologyKey: kubernetes.io/hostname containers: - name: with-pod-affinity image: nginx

デプロイメント ファイルには、アフィニティ設定が表示されます。

  • • PodAffinity: スケジュールされた Pod は、特定のラベル (キー a、値 b) を持つ Pod と同じノード上にある必要があります。
  • • PodAntiAffinity: スケジュールされた Pod が、同じラベル (キー app、値 anti-nginx) を持つ Pod と同じノード上に存在できないことを要求します。

上記のデプロイメント ファイルをクラスターに適用した後、Pod の分散を確認します。

 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-anti-5656fcbb98-62mds 0/1 Pending 0 5s <none> <none> <none> <none> nginx-anti-5656fcbb98-wxphs 0/1 Pending 0 5s <none> <none> <none> <none>

アフィニティ ルールによりポッドをスケジュールできず、待機状態のままになります。これは、特定の Pod のイベント ログを表示することで確認できます。

 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 27s default-scheduler 0/1 nodes are available: 1 node(s) didn't match pod affinity rules. preemption: 0/1 nodes are available: 1 Preemption is not helpful for scheduling..

ポッドのアフィニティ ルールと反アフィニティ ルールを使用してポッドのスケジュール場所を制御し、特定のスケジュール要件と負荷分散を実現します。

ノードアフィニティ

Pod と Node 間のアフィニティを定義するために使用されます。特定のラベルまたは属性を持つノードにスケジュールされるポッドを制御します。

適用可能なシナリオ: ハードウェア特性 (GPU、高性能ストレージなど) またはその他のカスタム ラベル (環境ラベルなど) に基づいて Pod をスケジュールする必要がある場合。

例:

 apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: disktype operator: In values: - ssd containers: - name: nginx image: nginx

デプロイメント ファイルのアフィニティ設定:

• nodeAffinity は、Pod が disktype: ssd ラベルを持つノードにスケジュールされるように設定されています。

上記のデプロイメント ファイルをクラスターに適用した後、Pod の実行ステータスを確認します。

 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deployment-565d7797dc-jf5nk 0/1 Pending 0 14s <none> <none> <none> <none>

アフィニティ ルールによりポッドをスケジュールできず、待機状態のままになります。これは、特定の Pod のイベント ログを表示することで確認できます。

 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 89s default-scheduler 0/1 nodes are available: 1 node(s) didn't match Pod's node affinity/selector. preemption: 0/1 nodes are available: 1 Preemption is not helpful for scheduling..

優先スケジュール中は無視実行中は無視

以前の requiredDuringScheduling スケジューリング タイプとは異なり、preferredDuringScheduling は優先スケジューリングであることを示します。スケジューラは、対応するルールを満たすノードを優先し、その設定に基づいてポッドをスケジュールします。ただし、ルールを満たすノードが見つからない場合、スケジューラは他のノードを選択してポッドをスケジュールします。

例:

 apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: disktype operator: In values: - ssd containers: - name: nginx image: nginx

構成の説明: ここでは、preferredDuringSchedulingIgnoredDuringExecution タイプが使用されています。これは、スケジューラが、disktype: ssd ラベルを持つノードに Pod をスケジュールするように試みますが、強制しないことを意味します。

上記のデプロイメント ファイルをクラスターに適用した後、Pod の実行ステータスを確認します。

 NAME READY STATUS RESTARTS AGE nginx-deployment-69c654d896-7qh8t 1/1 Running 0 28s

ローカルにアフィニティ ルールを満たすノードが存在しないにもかかわらず、Pod をスケジュールできることがわかります。

要約:

• podAffinityはPod間のさまざまな関係に焦点を当てています

• nodeAffinityはPodとノードの特性の関係に重点を置いています

requiredDuringScheduling: ハード アフィニティ、必須のスケジュール ルール、アフィニティ設定を満たす必要があり、そうでない場合はスケジュールは不可能です

preferredDuringScheduling: ソフトアフィニティ、優先スケジューリングルール、最初に設定を満たすノードを見つけ、そうでない場合は他のノードにスケジュールします

汚れ

Taint と Tolerations は、Kubernetes で特定のノードへの Pod のスケジュールを制御するために使用されるメカニズムです。アフィニティ メカニズムと比較すると、Taints ルールは除外メカニズムであり、特定の条件を満たさない Pod を「除外」するために使用されます。

汚染には 3 つの影響があります。

• NoSchedule (新しいポッドはスケジュールされません)

• PreferNoSchedule (新しいポッドのスケジュールを避ける)

• NoExecute (新しいポッドはスケジュールされず、既存のポッドは移行される可能性があります)

Taints の一般的な適用シナリオ:

• クラスター内で共有したくないノードには、排他的使用を示すTaintsタグを追加できます。

• マルチテナントKubernetesコンピューティングリソースの分離に使用

• Kubernetes自体はTaintsメカニズムを使用して利用できないノードを削除します

使用例:

ノードにテイントを追加し、一致する Tolerations がない限り、すべてのポッドがそのノードに自動的にスケジュールされないようにします。

 $ kubectl taint nodes docker-desktop for-special-user=cadmin:NoSchedule

まず、検証する Tolerations のない Pod を定義します。

 apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx

これをクラスターに適用し、ポッドのステータスが常に Pending であることを確認します。

 NAME READY STATUS RESTARTS AGE nginx-deployment-77b4fdf86c-wm5f9 0/1 Pending 0 23s

イベント ログから、Taints が動作していることがわかります。

 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 56s default-scheduler 0/1 nodes are available: 1 node(s) had untolerated taint {for-special-user: cadmin}. preemption: 0/1 nodes are available: 1 Preemption is not helpful for scheduling..

次に、特定の Taint を持つノードでスケジュールできるように、Pod 定義に Tolerations を追加します。

 apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx tolerations: - key: "for-special-user" operator: "Equal" value: "docker-desktop" effect: "NoSchedule"

このデプロイメントは、 for-special-user=docker-desktop と NoSchedule 効果でマークされたノードにポッドをスケジュールできるようにする Tolerations ルールを設定します。

これをクラスターに適用し、Pod のステータスを確認します。

 NAME READY STATUS RESTARTS AGE nginx-deployment-dd7d69c9c-77qlf 1/1 Running 0 31s

ポッドは通常どおりスケジュールされており、ここで Taint が作用します。

ノードが Tanint を除外する必要がなくなった場合は、削除できます。

 $ kubectl taint nodes docker-desktop for-special-user=cadmin:NoSchedule-

出力:

 node/docker-desktop untainted

優先クラス

PriorityClass は、Pod のスケジュール優先度を定義するために使用されます。一般的なシナリオは次のとおりです。

1. 主要なサービスが最初にスケジュールされていることを確認する: データベースやコア アプリケーション サービスなどの主要コンポーネントには、より高い優先順位を設定できます。

2. リソースの競合を管理する: リソースが限られている環境では、異なる優先順位を設定して、異なるポッドのスケジュール順序を管理します。

PriorityClass を使用する手順:

1. PriorityClass を作成します: apiVersion: scheduling.k8s.io/v1kind: PriorityClassmetadata: name: high-priorityvalue: 1000000globalDefault: falsedescription: "この優先度クラスは、XYZ サービス ポッドにのみ使用する必要があります。"

例:

• value: これは、この PriorityClass の優先度を表す整数です。数字が大きいほど優先度が高くなります。

• globalDefault: 指定された優先度を持たないクラスター内のすべてのポッドのデフォルトの優先度を表します。

1. Pod で PriorityClass を指定します。

 apiVersion: v1 kind: Pod metadata: name: mypod spec: priorityClassName: high-priority containers: - name: mycontainer image: myimage

作成した PriorityClass を priorityClassName を通じて適用し、Pod のスケジュール優先度が確実に高くなるようにします。

カスタムスケジューラ

デフォルトのスケジューラは、一般的な使用シナリオ向けに設計されています。デフォルトの Kubernetes スケジューラがニーズを満たせない場合は、カスタム スケジューラを使用して、よりパーソナライズされたニーズを満たすこともできます。例えば:

 apiVersion: v1 kind: Pod metadata: name: mypod spec: schedulerName: my-custom-scheduler containers: - name: mycontainer image: myimage

コミュニティには、次のような成熟したオープンソースのカスタム スケジューラも多数あります。

• テンセントTKEスケジューラ

• Huawei 火山スケジューラ

kube-scheduler ソース コードを参照して独自のスケジューラを実装することもできます。

<<:  優れた Kubernetes ツールの完全ガイド

>>:  Javaマイクロサービスアーキテクチャとコンテナ化されたデプロイメントに関する深い理解

推薦する

#11.11# losangelesvps: 月額 4 ドル、KVM 仮想 VPS/2G メモリ/1Gbps 帯域幅/無制限トラフィック、月 1 回の無料 IP 変更

losangelesvpsの11.11中国イベントが始まりました。INAPのロサンゼルスデータセンタ...

情報の流れをめぐる戦いにおいて、エコロジカル・チェーンとソーシャル・ドリームのどちらが最終的な勝者となるのでしょうか?

情報フロープラットフォームは「分断」され、競争は岐路に立たされています。 2018 年を通じて、情報...

激動の時代、狂気の起業家精神

はじめに:投資家のヤンヤンはかつてこう言いました。「もし誰もが自分のビジネスを始めたら、それはこの国...

urpadの紹介

urpad は FTNhosting () のブランドであり、2008 年に設立され、同社のチームは...

BannerPlay: バナー広告の AdWords

BannerPlay: AdWords に似たバナー広告プラットフォーム予算が限られている中小企業に...

ワールドカップのマーケティング戦争: モバイル インターネットとソーシャル メディアの再来

[概要] ワールドカップはビッグネームのサッカースターたちの対決であるだけでなく、大手テクノロジー企...

ローカル展開と比較したクラウド展開の利点は何ですか?

「あなたのシステムはローカル展開をサポートしていますか?」これは、営業担当者が医療機関のシステム調達...

非常に詳細なウェブサイト外部リンク構築SEO体験の概要

2018年最もホットなプロジェクト:テレマーケティングロボットがあなたの参加を待っています外部リンク...

QRコード標準化プラットフォームは今年末に開始予定。敷居が低く、収益化も可能。

ショッピングや支払いでもウイルスが拡散する可能性がある。セキュリティの問題は真剣に受け止める必要があ...

JVMの原則の分析、誰もが良いと言った

[[317032]] 1 JVM とは何ですか? JVM は Java Virtual Machin...

tmhhost: 388元/年、米国cn2gia/cu2(as9929)/日本ソフトバンク、4Gメモリ/2コア/40g SSD/1.5Tトラフィック/20g防御

tmhhostは現在、ロサンゼルスデータセンター、cn2 gia、cuii(as9929)、日本ソフ...

企業に関するネガティブな情報への対処方法

企業に関するネガティブな情報は、どの企業も直面しなければならない問題かもしれません。ことわざにあるよ...

gfrack フランスの高防御 VPS (99 元/年、1G メモリ/1 コア/30g NVMe/無制限トラフィック) の簡単なレビュー

新しく設立されたVPSブランドgfrackは現在、フランスの高防御クラウドサーバー事業に注力しており...

同じページでもキーワードによってランキングが全く異なる

このタイトルを見ると、これはナンセンスだと言うかもしれません。もちろん、同じページでもキーワードによ...