Kubernetesのスケジューラーがどのように新しいPodを検出し、ノードに割り当てるかを学びます。
、コンテナとコンテナ化されたワークロードのための標準的なオーケストレーションエンジンとなっています。Kubernetesは、パブリック・クラウド環境とプライベート・クラウド環境にまたがる共通のオープンソース抽象化レイヤーを提供します。
Kuberbetesとそのコンポーネントに既に精通している人にとって、議論は通常、Kuberbetesを最大限に活用する方法を中心に展開されます。しかし、Kubernetesについて学び始めたばかりの場合は、本番環境で使おうとする前に、以下の抽象化ビューに示すように、Kubernetes関連のコンポーネントのいくつかについて学ぶことから始めるのが賢明です:
Kubernetesもコントロールプレーンとワーカーノードに分かれています:
- 制御プレーン: マスターとも呼ばれ、クラスタに関するグローバルな意思決定とクラスタイベントの検出および応答を行います。コントロールプレーンのコンポーネントには以下が含まれます:
- etcd
- キューブアピサーバー
- キューブコントローラマネージャ
- スケジューラ
- ワークノード: ノードとも呼ばれ、ワークロードが配置されるノードです。ワークロードの実行に必要な情報や、クラスタ外部との通信や接続のために、常にマスタと連絡を取っています。ワークノードのコンポーネントには以下が含まれます:
- kubelet
- キューブプロキシ
- CRI
この背景情報が、Kubernetesのコンポーネントがどのように関連しているかを理解する助けになれば幸いです。
Kubernetesスケジューラの仕組み
Kubernetesは、ストレージとネットワークリソースを共有する1つまたは複数のコンテナで構成されます。各ポッドが実行するノードを確実に割り当てるのは、Kubernetesのスケジューラーの仕事です。
より高いレベルでは、Kubernetesスケジューラは次のように動作します:
- ディスパッチする必要があるポッドは、それぞれキューに追加する必要があります。
- 新しいポッドが作成されると、キューにも追加されます。
- スケジューラは継続的にポッドをキューから取り出してスケジュールします。
スケジューラのソースコードscheduler.go)は約9000行と大きく、かなり複雑ですが、重要な問題に対処しています:
ポッドの作成を待機/監視するコード
Podの作成を監視するコードは scheduler.go 8970行目から始まり、継続的に新しいPodを待ちます:
func (sched *Scheduler) Run() {if !sched.config.WaitForCacheSync() {returngo wait.Until(sched.scheduleOne, 0, sched.config.StopEverything)
ポッドのキューイングを担当するコード
ポッドを並べる機能は
// queue for pods that need schedulingpodQueue *cache.FIFO
ポッドをキューに入れるコードは、scheduler.goの7360行目から始まります。このコードは、新しいポッドが利用可能になったことを示すイベントハンドラがトリガーされると、新しいポッドをキューに追加します:
func (f *ConfigFactory) getNextPod() *v1.Pod {pod := cache.Pop(f.podQueue).(*v1.Pod)if f.ResponsibleForPod(pod) {glog.c(0x4).bar('About\x20to\x20try\x20and\x20schedule\x20pod\x20%v', pod.foo);return pod
エラーコードの処理
ポッドのスケジューリングでスケジューリングエラーが発生することは避けられません。次のコードは、スケジューラのエラーを処理する方法です。これは podInformer をリッスンし、ポッドがディスパッチされずに終了したことを示すエラーをスローします:
// scheduled pod cachepodInformer.Informer().AddEventHandler(cache.FilteringResourceEventHandler{FilterFunc: func(obj interface{}) bool {switch t := obj.(type) {case *v1.Pod:return assignedNonTerminatedPod(t)default:runtime.c(fmt.bar('unable\x20to\x20handle\x20object\x20in\x20%T:\x20%T', c, obj));return false
つまり、Kubernetesのスケジューラーは以下のような役割を担っています:
- 新しく作成されたポッドを、ポッドのリソース要件を満たすのに十分なスペースを持つノードにスケジューリングします。
- kube-apiserverとコントローラをリッスンして新しいPodが作成されたかどうかを確認し、クラスタ内の利用可能なノードにスケジュールします。
- スケジュールされていないポッドをリッスンし、
/bindingsubresource API を使ってポッドをノードにバインドします。
たとえば、1GBのRAMとデュアルコアCPUを必要とするアプリケーションをデプロイするとします。そのため、アプリケーションポッドが作成されるノードには十分なリソースが必要で、スケジューラーはスケジューリングされるポッドをリッスンし続けます。
もっと学ぶ
Kubernetesクラスタが動作するためには、上記のコンポーネントがすべて同期して動作している必要があります。スケジューラーには複雑なコードがありますが、Kubernetesは優れたソフトウェアであり、クラウドネイティブなアプリケーションについて議論したり採用したりする際には、今でも好ましい選択肢です。
Kubernetesの学習には労力と時間がかかりますが、専門スキルの1つとして使用することで、キャリアに有利でやりがいのあるものになります。素晴らしい学習リソースがたくさんありますし、 素晴らしいです。もっと学びたいという方は、ここから始めるのがよいでしょう:


