k8s 1.13 スケジューラ起動時の初期化とアルゴリズム設定

スケジューラの起動プロセスにおいて、デフォルトで有効になるスケジューリングアルゴリズムや設定の読み込みロジックを理解することは、カスタムスケジューラ開発やトラブルシューティングに不可欠である。ここでは Kubernetes v1.13 をベースに、kube-scheduler の初期化フローとアルゴリズム登録メカニズムを解説する。

--config フラグによる設定読み込み

kube-scheduler は --config フラグで指定された YAML ファイルから設定を読み込む。このファイルにはスケジューラの動作に関わるほとんどのパラメータが含まれる。コマンドラインフラグは非推奨となっており、設定ファイルが優先される。

cmd/kube-scheduler/app/options/options.go で定義される Options 構造体は、CLI 引数と設定ファイルパスを保持する:

type Options struct {
    ComponentConfig kubeschedulerconfig.KubeSchedulerConfiguration
    ConfigFile      string
    WriteConfigTo   string
    Master          string
    // ... 認証・認可・リーダー選出などの設定
}

ApplyTo() メソッドは、--config の有無に応じて設定を適用する:

func (o *Options) ApplyTo(c *schedulerappconfig.Config) error {
    if len(o.ConfigFile) == 0 {
        c.ComponentConfig = o.ComponentConfig
        // 非推奨フラグの適用(省略)
    } else {
        cfg, err := loadConfigFromFile(o.ConfigFile)
        if err != nil {
            return err
        }
        c.ComponentConfig = *cfg
        // 設定ファイルからの非セキュアサービング設定適用
    }
    return nil
}

Feature Gate によるアルゴリズム制御

起動時に algorithmprovider.ApplyFeatureGates() が呼び出され、機能ゲートに基づいてスケジューリングアルゴリズムが動的に調整される。

パッケージ初期化時にデフォルトプロバイダが登録される:

// pkg/scheduler/algorithmprovider/defaults/defaults.go
func init() {
    registerAlgorithmProvider(defaultPredicates(), defaultPriorities())
}

registerAlgorithmProvider は内部で factory.RegisterAlgorithmProvider を呼び出し、アルゴリズム名とそのキー集合をマップに格納する:

var algorithmProviderMap = make(map[string]AlgorithmProviderConfig)

func RegisterAlgorithmProvider(name string, predicateKeys, priorityKeys sets.String) {
    algorithmProviderMap[name] = AlgorithmProviderConfig{
        FitPredicateKeys:     predicateKeys,
        PriorityFunctionKeys: priorityKeys,
    }
}

機能ゲートが有効な場合、特定のアルゴリズムが追加または削除される例:

func ApplyFeatureGates() {
    if utilfeature.DefaultFeatureGate.Enabled(features.TaintNodesByCondition) {
        factory.RemoveFitPredicate(predicates.CheckNodeConditionPred)
        factory.RegisterMandatoryFitPredicate(predicates.PodToleratesNodeTaintsPred, predicates.PodToleratesNodeTaints)
        factory.InsertPredicateKeyToAlgorithmProviderMap(predicates.PodToleratesNodeTaintsPred)
    }
}

Scheduler インスタンスの生成

scheduler.New() はスケジューラのエントリポイントであり、アルゴリズムソース(Provider または Policy)に基づいて設定を構築する。

アルゴリズムソースは以下のいずれかを指定:

type SchedulerAlgorithmSource struct {
    Policy   *SchedulerPolicySource
    Provider *string
}

Provider モードの場合、登録済みのアルゴリズムプロバイダ(例: "DefaultProvider")からキー集合を取得し、実際の関数に変換する:

func (c *configFactory) CreateFromProvider(providerName string) (*Config, error) {
    provider, err := GetAlgorithmProvider(providerName)
    if err != nil {
        return nil, err
    }
    return c.CreateFromKeys(provider.FitPredicateKeys, provider.PriorityFunctionKeys, nil)
}

CreateFromKeys 内で、キーに対応するプレディケート関数とプライオリティ関数が解決され、GenericScheduler に注入される:

predicateFuncs, _ := c.GetPredicates(predicateKeys)
priorityConfigs, _ := c.GetPriorityFunctionConfigs(priorityKeys)

algo := core.NewGenericScheduler(
    c.schedulerCache,
    c.equivalencePodCache,
    c.podQueue,
    predicateFuncs,
    predicateMetaProducer,
    priorityConfigs,
    priorityMetaProducer,
    // ...
)

デフォルトで有効なアルゴリズム

defaultPredicates()defaultPriorities() により、以下のようなアルゴリズムが標準で登録される:

  • プレディケート(フィルタリング): NoVolumeZoneConflict, NoDiskConflict, Predicates.GeneralPredicates など
  • プライオリティ(スコアリング): LeastRequestedPriority, SelectorSpreadPriority, InterPodAffinityPriority など

これらのアルゴリズムは、機能ゲートの状態やカスタム設定によって動的に変更可能であり、スケジューラの柔軟性を支えている。

タグ: Kubernetes scheduler k8s-source-code algorithm-provider feature-gate

5月22日 01:21 投稿