func (frsc *ReplicaSetController) schedule(frs *extensionsv1.ReplicaSet, clusters []*fedv1.Cluster, current map[string]int64, estimatedCapacity map[string]int64) map[string]int64 { // TODO: integrate real scheduler plnr := frsc.defaultPlanner frsPref, err := parseFederationReplicaSetReference(frs) if err != nil { glog.Info("Invalid ReplicaSet specific preference, use default. rs: %v, err: %v", frs, err) } if frsPref != nil { // create a new planner if user specified a preference plnr = planner.NewPlanner(frsPref) } replicas := int64(*frs.Spec.Replicas) var clusterNames []string for _, cluster := range clusters { clusterNames = append(clusterNames, cluster.Name) } scheduleResult, overflow := plnr.Plan(replicas, clusterNames, current, estimatedCapacity, frs.Namespace+"/"+frs.Name) // make sure the return contains clusters need to zero the replicas result := make(map[string]int64) for clusterName := range current { result[clusterName] = 0 } for clusterName, replicas := range scheduleResult { result[clusterName] = replicas } for clusterName, replicas := range overflow { result[clusterName] += replicas } if glog.V(4) { buf := bytes.NewBufferString(fmt.Sprintf("Schedule - ReplicaSet: %s/%s\n", frs.Namespace, frs.Name)) sort.Strings(clusterNames) for _, clusterName := range clusterNames { cur := current[clusterName] target := scheduleResult[clusterName] fmt.Fprintf(buf, "%s: current: %d target: %d", clusterName, cur, target) if over, found := overflow[clusterName]; found { fmt.Fprintf(buf, " overflow: %d", over) } if capacity, found := estimatedCapacity[clusterName]; found { fmt.Fprintf(buf, " capacity: %d", capacity) } fmt.Fprintf(buf, "\n") } glog.V(4).Infof(buf.String()) } return result }
func (fdc *DeploymentController) schedule(fd *extensionsv1.Deployment, clusters []*fedv1.Cluster, current map[string]int64, estimatedCapacity map[string]int64) map[string]int64 { // TODO: integrate real scheduler plannerToBeUsed := fdc.defaultPlanner fdPref, err := parseFederationDeploymentPreference(fd) if err != nil { glog.Info("Invalid Deployment specific preference, use default. deployment: %v, err: %v", fd.Name, err) } if fdPref != nil { // create a new planner if user specified a preference plannerToBeUsed = planner.NewPlanner(fdPref) } replicas := int64(*fd.Spec.Replicas) var clusterNames []string for _, cluster := range clusters { clusterNames = append(clusterNames, cluster.Name) } scheduleResult, overflow := plannerToBeUsed.Plan(replicas, clusterNames, current, estimatedCapacity, fd.Namespace+"/"+fd.Name) // make sure the result contains all clusters that currently have some replicas. result := make(map[string]int64) for clusterName := range current { result[clusterName] = 0 } for clusterName, replicas := range scheduleResult { result[clusterName] = replicas } for clusterName, replicas := range overflow { result[clusterName] += replicas } if glog.V(4) { buf := bytes.NewBufferString(fmt.Sprintf("Schedule - Deployment: %s/%s\n", fd.Namespace, fd.Name)) sort.Strings(clusterNames) for _, clusterName := range clusterNames { cur := current[clusterName] target := scheduleResult[clusterName] fmt.Fprintf(buf, "%s: current: %d target: %d", clusterName, cur, target) if over, found := overflow[clusterName]; found { fmt.Fprintf(buf, " overflow: %d", over) } if capacity, found := estimatedCapacity[clusterName]; found { fmt.Fprintf(buf, " capacity: %d", capacity) } fmt.Fprintf(buf, "\n") } glog.V(4).Infof(buf.String()) } return result }
// NewclusterController returns a new cluster controller func NewReplicaSetController(federationClient fedclientset.Interface) *ReplicaSetController { broadcaster := record.NewBroadcaster() broadcaster.StartRecordingToSink(eventsink.NewFederatedEventSink(federationClient)) recorder := broadcaster.NewRecorder(api.EventSource{Component: "federated-replicaset-controller"}) frsc := &ReplicaSetController{ fedClient: federationClient, replicasetDeliverer: fedutil.NewDelayingDeliverer(), clusterDeliverer: fedutil.NewDelayingDeliverer(), replicasetWorkQueue: workqueue.New(), replicaSetBackoff: flowcontrol.NewBackOff(5*time.Second, time.Minute), defaultPlanner: planner.NewPlanner(&fed.FederatedReplicaSetPreferences{ Clusters: map[string]fed.ClusterReplicaSetPreferences{ "*": {Weight: 1}, }, }), eventRecorder: recorder, } replicaSetFedInformerFactory := func(cluster *fedv1.Cluster, clientset kubeclientset.Interface) (cache.Store, cache.ControllerInterface) { return cache.NewInformer( &cache.ListWatch{ ListFunc: func(options api.ListOptions) (runtime.Object, error) { versionedOptions := fedutil.VersionizeV1ListOptions(options) return clientset.Extensions().ReplicaSets(apiv1.NamespaceAll).List(versionedOptions) }, WatchFunc: func(options api.ListOptions) (watch.Interface, error) { versionedOptions := fedutil.VersionizeV1ListOptions(options) return clientset.Extensions().ReplicaSets(apiv1.NamespaceAll).Watch(versionedOptions) }, }, &extensionsv1.ReplicaSet{}, controller.NoResyncPeriodFunc(), fedutil.NewTriggerOnAllChanges( func(obj runtime.Object) { frsc.deliverLocalReplicaSet(obj, replicaSetReviewDelay) }, ), ) } clusterLifecycle := fedutil.ClusterLifecycleHandlerFuncs{ ClusterAvailable: func(cluster *fedv1.Cluster) { frsc.clusterDeliverer.DeliverAfter(allClustersKey, nil, clusterAvailableDelay) }, ClusterUnavailable: func(cluster *fedv1.Cluster, _ []interface{}) { frsc.clusterDeliverer.DeliverAfter(allClustersKey, nil, clusterUnavailableDelay) }, } frsc.fedReplicaSetInformer = fedutil.NewFederatedInformer(federationClient, replicaSetFedInformerFactory, &clusterLifecycle) podFedInformerFactory := func(cluster *fedv1.Cluster, clientset kubeclientset.Interface) (cache.Store, cache.ControllerInterface) { return cache.NewInformer( &cache.ListWatch{ ListFunc: func(options api.ListOptions) (runtime.Object, error) { versionedOptions := fedutil.VersionizeV1ListOptions(options) return clientset.Core().Pods(apiv1.NamespaceAll).List(versionedOptions) }, WatchFunc: func(options api.ListOptions) (watch.Interface, error) { versionedOptions := fedutil.VersionizeV1ListOptions(options) return clientset.Core().Pods(apiv1.NamespaceAll).Watch(versionedOptions) }, }, &apiv1.Pod{}, controller.NoResyncPeriodFunc(), fedutil.NewTriggerOnAllChanges( func(obj runtime.Object) { frsc.clusterDeliverer.DeliverAfter(allClustersKey, nil, allReplicaSetReviewDelay) }, ), ) } frsc.fedPodInformer = fedutil.NewFederatedInformer(federationClient, podFedInformerFactory, &fedutil.ClusterLifecycleHandlerFuncs{}) frsc.replicaSetStore.Indexer, frsc.replicaSetController = cache.NewIndexerInformer( &cache.ListWatch{ ListFunc: func(options api.ListOptions) (runtime.Object, error) { versionedOptions := fedutil.VersionizeV1ListOptions(options) return frsc.fedClient.Extensions().ReplicaSets(apiv1.NamespaceAll).List(versionedOptions) }, WatchFunc: func(options api.ListOptions) (watch.Interface, error) { versionedOptions := fedutil.VersionizeV1ListOptions(options) return frsc.fedClient.Extensions().ReplicaSets(apiv1.NamespaceAll).Watch(versionedOptions) }, }, &extensionsv1.ReplicaSet{}, controller.NoResyncPeriodFunc(), fedutil.NewTriggerOnMetaAndSpecChanges( func(obj runtime.Object) { frsc.deliverFedReplicaSetObj(obj, replicaSetReviewDelay) }, ), cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, ) frsc.fedUpdater = fedutil.NewFederatedUpdater(frsc.fedReplicaSetInformer, func(client kubeclientset.Interface, obj runtime.Object) error { rs := obj.(*extensionsv1.ReplicaSet) _, err := client.Extensions().ReplicaSets(rs.Namespace).Create(rs) return err }, func(client kubeclientset.Interface, obj runtime.Object) error { rs := obj.(*extensionsv1.ReplicaSet) _, err := client.Extensions().ReplicaSets(rs.Namespace).Update(rs) return err }, func(client kubeclientset.Interface, obj runtime.Object) error { rs := obj.(*extensionsv1.ReplicaSet) err := client.Extensions().ReplicaSets(rs.Namespace).Delete(rs.Name, &apiv1.DeleteOptions{}) return err }) frsc.deletionHelper = deletionhelper.NewDeletionHelper( frsc.hasFinalizerFunc, frsc.removeFinalizerFunc, frsc.addFinalizerFunc, // objNameFunc func(obj runtime.Object) string { replicaset := obj.(*extensionsv1.ReplicaSet) return replicaset.Name }, updateTimeout, frsc.eventRecorder, frsc.fedReplicaSetInformer, frsc.fedUpdater, ) return frsc }