func(pl *NodeAffinity)Score(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeName string)(int64,*framework.Status){
nodeInfo, err := pl.handle.SnapshotSharedLister().NodeInfos().Get(nodeName)if err != nil {return0, framework.NewStatus(framework.Error, fmt.Sprintf("getting node %q from Snapshot: %v", nodeName, err))}
node := nodeInfo.Node()if node == nil {return0, framework.NewStatus(framework.Error, fmt.Sprintf("getting node %q from Snapshot: %v", nodeName, err))}
affinity := pod.Spec.Affinity
var count int64
// A nil element of PreferredDuringSchedulingIgnoredDuringExecution matches no objects.// An element of PreferredDuringSchedulingIgnoredDuringExecution that refers to an// empty PreferredSchedulingTerm matches all objects.if affinity != nil && affinity.NodeAffinity!= nil && affinity.NodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution!= nil {// Match PreferredDuringSchedulingIgnoredDuringExecution term by term.for i := range affinity.NodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution{
preferredSchedulingTerm :=&affinity.NodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution[i]if preferredSchedulingTerm.Weight==0{continue}// TODO: Avoid computing it for all nodes if this becomes a performance problem.
nodeSelector, err := v1helper.NodeSelectorRequirementsAsSelector(preferredSchedulingTerm.Preference.MatchExpressions)if err != nil {return0, framework.NewStatus(framework.Error, err.Error())}if nodeSelector.Matches(labels.Set(node.Labels)){
count +=int64(preferredSchedulingTerm.Weight)}}}return count, nil
}
最后在通过实现一个 New 函数来提供注册这个扩展的方法,这个 New 函数可以在 main.go 中将其作为 out of tree plugins 注入到 scheduler 中即可:
// New initializes a new plugin and returns it.
func New(_ runtime.Object, h framework.FrameworkHandle)(framework.Plugin, error){return&NodeAffinity{handle: h}, nil
}
#!/bin/sh
set -euo pipefail
VERSION=${1#"v"}if[-z "$VERSION"]; then
echo "Must specify version!"
exit 1
fi
MODS=($(
curl -sS https://raw.githubusercontent.com/kubernetes/kubernetes/v${VERSION}/go.mod|
sed -n 's|.*k8s.io/\(.*\)=>./staging/src/k8s.io/.*|k8s.io/\1|p'
))forMODin"${MODS[@]}";doV=$(
go moddownload-json "${MOD}@kubernetes-${VERSION}"|
sed -n 's|.*"Version":"\(.*\)".*|\1|p'
)
go modedit"-replace=${MOD}=${MOD}@${V}"
done
go get "k8s.io/kubernetes@v${VERSION}"
// NormalizeScore invoked after scoring all nodes.func(pl *NodeAffinity)NormalizeScore(ctx context.Context, state *framework.CycleState, pod *v1.Pod, scores framework.NodeScoreList)*framework.Status{return pluginhelper.DefaultNormalizeScore(framework.MaxNodeScore,false, scores)}// ScoreExtensions of the Score plugin.func(pl *NodeAffinity)ScoreExtensions() framework.ScoreExtensions{return pl
}
而在调度框架中,真正执行的操作的方法也是 NormalizeScore():
func(f *frameworkImpl)runScoreExtension(ctx context.Context, pl framework.ScorePlugin, state *framework.CycleState, pod *v1.Pod, nodeScoreList framework.NodeScoreList)*framework.Status{if!state.ShouldRecordPluginMetrics(){return pl.ScoreExtensions().NormalizeScore(ctx, state, pod, nodeScoreList)}
startTime := time.Now()
status := pl.ScoreExtensions().NormalizeScore(ctx, state, pod, nodeScoreList)
f.metricsRecorder.observePluginDurationAsync(scoreExtensionNormalize, pl.Name(), status, metrics.SinceInSeconds(startTime))return status
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object// NodeLabelArgs holds arguments used to configure the NodeLabel plugin.typeNodeLabelArgsstruct{
metav1.TypeMeta// PresentLabels should be present for the node to be considered a fit for hosting the podPresentLabels[]string
// AbsentLabels should be absent for the node to be considered a fit for hosting the podAbsentLabels[]string
// Nodes that have labels in the list will get a higher score.PresentLabelsPreference[]string
// Nodes that don't have labels in the list will get a higher score.AbsentLabelsPreference[]string
}
最后将其注册到 register 中,整个行为与扩展 APIServer 是类似的:
// addKnownTypes registers known types to the given scheme
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,&KubeSchedulerConfiguration{},&Policy{},&InterPodAffinityArgs{},&NodeLabelArgs{},&NodeResourcesFitArgs{},&PodTopologySpreadArgs{},&RequestedToCapacityRatioArgs{},&ServiceAffinityArgs{},&VolumeBindingArgs{},&NodeResourcesLeastAllocatedArgs{},&NodeResourcesMostAllocatedArgs{},)
scheme.AddKnownTypes(schema.GroupVersion{Group:"",Version: runtime.APIVersionInternal},&Policy{})return nil
}
设置映射路径
在不同的bean中可能会出现相同名字的路径,这样的情况会产生冲突,为了解决这个冲突我们可以设置模块名作为请求路径前缀
Controller
RequestMapping("/book")
public class BookController {//设置当前操作的访问路径RequestMa…
pycharm设置文件和代码(File and Code Templates)模板步骤如下:
1.pycharm工具栏"file"->"Settings"->"Editor"->"Code Style"->"File and Code Templates",点击右侧python …