解决 Kubernetes 调度器启动报错:缺少 Bind 插件
问题描述
在启动自定义 Kubernetes 调度器时,出现了以下错误:
I0416 17:08:41.420188 68788 configfile.go:57] "KubeSchedulerConfiguration v1beta2 is deprecated in v1.25, will be removed in v1.28"
Error: initializing profiles: creating profile for scheduler name custom-scheduler: at least one bind plugin is needed for profile with scheduler name "custom-scheduler"
问题分析
错误原因:
-
Bind 插件缺失:
- 错误信息表明,调度器配置文件(
scheduler-config.yaml
)中为custom-scheduler
定义的 profile 缺少至少一个 Bind 插件。 - Kubernetes 调度器要求每个 profile 必须包含一个 Bind 插件(如
DefaultBinder
),用于将 Pod 绑定到选定的节点。如果 Bind 插件被禁用(例如通过disabled: - name: "*"
),调度器无法完成调度流程,导致启动失败。
- 错误信息表明,调度器配置文件(
-
KubeSchedulerConfiguration v1beta2 警告:
- 日志中的警告表明
KubeSchedulerConfiguration v1beta2
在 Kubernetes v1.25 中已废弃,并将在 v1.28 中移除。这只是警告,不影响当前运行,但建议未来升级到v1beta3
或v1
。
- 日志中的警告表明
背景:
- 在
scheduler-config.yaml
中,Bind 阶段的插件被完全禁用(disabled: - name: "*"
),导致没有可用的 Bind 插件。 - 自定义 Filter 插件(
CustomFilter
)仅处理 Filter 阶段,而 Bind 阶段是调度流程的最后一步,必须由插件(如DefaultBinder
)完成。
解决方案
为了解决这个问题,需要在 scheduler-config.yaml
中为 custom-scheduler
的 profile 启用至少一个 Bind 插件(推荐使用 DefaultBinder
)。以下是详细步骤:
1. 修改调度器配置文件
编辑 /Users/liyinlong/goproject/openmiddleware-scheduler/resources/scheduler-config.yaml
,启用 DefaultBinder
插件。修正后的配置文件如下:
apiVersion: kubescheduler.config.k8s.io/v1beta2
kind: KubeSchedulerConfiguration
profiles:- schedulerName: custom-schedulerplugins:filter:enabled:- name: CustomFilterdisabled:- name: "*"preFilter:disabled:- name: "*"score:disabled:- name: "*"bind:enabled:- name: DefaultBinderdisabled:- name: "*"
修改说明:
- 在
bind
阶段,添加enabled: - name: DefaultBinder
以启用默认的 Bind 插件。 - 保留
disabled: - name: "*"
,确保禁用其他默认 Bind 插件(如果有)。 - 其他阶段(
filter
、preFilter
、score
)保持不变,CustomFilter
仍为唯一的 Filter 插件。
注意:
DefaultBinder
是 Kubernetes 提供的标准 Bind 插件,负责将 Pod 绑定到调度器选定的节点。它不引入额外的依赖,适合最小化 Demo。- 如果需要自定义 Bind 逻辑,可实现自己的 Bind 插件。
2. 验证配置文件
确认 scheduler-config.yaml
文件路径和内容正确:
cat /Users/liyinlong/goproject/openmiddleware-scheduler/resources/scheduler-config.yaml
确保文件内容与上述示例一致。
3. 运行调度器
使用之前的命令重新运行调度器,确保 --kubeconfig
和 --config
参数正确:
./custom-scheduler --config=/Users/liyinlong/goproject/openmiddleware-scheduler/resources/scheduler-config.yaml --kubeconfig=/Users/liyinlong/istioproject/env/88.conf --bind-address=127.0.0.1
注意:
- 确保可执行文件是
./custom-scheduler
(而不是./schedule
)。 - 确认 kubeconfig 文件(
/Users/liyinlong/istioproject/env/88.conf
)有效(参考后续验证步骤)。
4. 处理 KubeSchedulerConfiguration 版本警告(可选)
日志中的警告表明 v1beta2
已废弃。为提高兼容性,可尝试升级到 v1beta3
(Kubernetes v1.27.0 支持)。修改 scheduler-config.yaml
:
apiVersion: kubescheduler.config.k8s.io/v1beta3
kind: KubeSchedulerConfiguration
profiles:- schedulerName: custom-schedulerplugins:filter:enabled:- name: CustomFilterdisabled:- name: "*"preFilter:disabled:- name: "*"score:disabled:- name: "*"bind:enabled:- name: DefaultBinderdisabled:- name: "*"
注意:
v1beta3
的配置格式与v1beta2
基本相同,但某些字段可能有细微变化。查阅 Kubernetes v1.27.0 文档以确保兼容性。- 如果升级到
v1beta3
后报错,暂时继续使用v1beta2
,因为警告不影响当前功能。
再次运行调度器:
./custom-scheduler --config=/Users/liyinlong/goproject/openmiddleware-scheduler/resources/scheduler-config.yaml --kubeconfig=/Users/liyinlong/istioproject/env/88.conf --bind-address=127.0.0.1
5. 测试调度器
-
为节点添加标签:
kubectl --kubeconfig=/Users/liyinlong/istioproject/env/88.conf label nodes <node-name> scheduler.custom/enabled=true
-
创建测试 Pod:
创建
test-pod.yaml
:apiVersion: v1 kind: Pod metadata:name: test-pod spec:schedulerName: custom-schedulercontainers:- name: nginximage: nginx
应用 Pod:
kubectl --kubeconfig=/Users/liyinlong/istioproject/env/88.conf apply -f test-pod.yaml
-
验证调度结果:
检查 Pod 是否调度到带有
scheduler.custom/enabled=true
标签的节点:kubectl --kubeconfig=/Users/liyinlong/istioproject/env/88.conf get pods -o wide
查看调度器日志(终端输出):
Node <node-name> passed custom filter # 或 Node <node-name> filtered out: missing label scheduler.custom/enabled=true
6. 确认 RBAC 权限
确保 kubeconfig 文件中的用户有足够的权限与 API Server 通信。创建 scheduler-rbac.yaml
:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:name: custom-scheduler-role
rules:
- apiGroups: [""]resources: ["nodes", "pods", "configmaps", "events"]verbs: ["get", "list", "watch"]
- apiGroups: [""]resources: ["pods/binding"]verbs: ["create"]
- apiGroups: [""]resources: ["pods/status"]verbs: ["update"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:name: custom-scheduler-binding
subjects:
- kind: Username: kind-custom-scheduler # 替换为 kubeconfig 中的用户名apiGroup: rbac.authorization.k8s.io
roleRef:kind: ClusterRolename: custom-scheduler-roleapiGroup: rbac.authorization.k8s.io
替换用户名:
-
查看 kubeconfig 中的用户名:
kubectl config view --kubeconfig=/Users/liyinlong/istioproject/env/88.conf -o jsonpath='{.users[*].name}'
-
更新
subjects.name
为实际用户名。
应用 RBAC:
kubectl --kubeconfig=/Users/liyinlong/istioproject/env/88.conf apply -f scheduler-rbac.yaml
7. 常见问题与解决方案
-
错误:Bind 插件仍缺失:
-
确认
scheduler-config.yaml
是否包含DefaultBinder
:cat /Users/liyinlong/goproject/openmiddleware-scheduler/resources/scheduler-config.yaml
-
确保文件路径正确且未被覆盖。
-
-
错误:Kubeconfig 文件无效:
-
测试 kubeconfig:
kubectl --kubeconfig=/Users/liyinlong/istioproject/env/88.conf cluster-info
-
如果无效,尝试默认 kubeconfig:
./custom-scheduler --config=/Users/liyinlong/goproject/openmiddleware-scheduler/resources/scheduler-config.yaml --kubeconfig=~/.kube/config --bind-address=127.0.0.1
-
-
错误:权限不足(Forbidden):
-
确认 RBAC 配置:
kubectl --kubeconfig=/Users/liyinlong/istioproject/env/88.conf get clusterrole custom-scheduler-role kubectl --kubeconfig=/Users/liyinlong/istioproject/env/88.conf get clusterrolebinding custom-scheduler-binding
-
确保
subjects.name
与 kubeconfig 用户名匹配。
-
-
Pod 仍未调度:
-
检查调度器日志(终端 output)。
-
确认节点标签:
kubectl --kubeconfig=/Users/liyinlong/istioproject/env/88.conf get nodes --show-labels
-
总结
当前报错是由于 scheduler-config.yaml
中缺少 Bind 插件,导致调度器无法启动。通过启用 DefaultBinder
插件,问题应得到解决。确保:
scheduler-config.yaml
包含bind.enabled: - name: DefaultBinder
。- Kubeconfig 文件有效(
/Users/liyinlong/istioproject/env/88.conf
)。 - RBAC 权限正确配置。
如果仍有问题,请提供以下信息:
- 修改后的
scheduler-config.yaml
内容。 - 运行
kubectl --kubeconfig=/Users/liyinlong/istioproject/env/88.conf cluster-info
的输出。 /Users/liyinlong/istioproject/env/88.conf
的内容(敏感信息可隐藏)。