func (s *Scheduler) scheduleOne() { pod := s.config.NextPod() if s.config.BindPodsRateLimiter != nil { s.config.BindPodsRateLimiter.Accept() } glog.V(3).Infof("Attempting to schedule: %v", pod) start := time.Now() defer func() { metrics.E2eSchedulingLatency.Observe(metrics.SinceInMicroseconds(start)) }() dest, err := s.config.Algorithm.Schedule(pod, s.config.MinionLister) metrics.SchedulingAlgorithmLatency.Observe(metrics.SinceInMicroseconds(start)) if err != nil { glog.V(1).Infof("Failed to schedule: %v", pod) s.config.Recorder.Eventf(pod, "failedScheduling", "Error scheduling: %v", err) s.config.Error(pod, err) return } b := &api.Binding{ ObjectMeta: api.ObjectMeta{Namespace: pod.Namespace, Name: pod.Name}, Target: api.ObjectReference{ Kind: "Node", Name: dest, }, } // We want to add the pod to the model iff the bind succeeds, but we don't want to race // with any deletions, which happen asynchronously. s.config.Modeler.LockedAction(func() { bindingStart := time.Now() err := s.config.Binder.Bind(b) metrics.BindingLatency.Observe(metrics.SinceInMicroseconds(bindingStart)) if err != nil { glog.V(1).Infof("Failed to bind pod: %v", err) s.config.Recorder.Eventf(pod, "failedScheduling", "Binding rejected: %v", err) s.config.Error(pod, err) return } s.config.Recorder.Eventf(pod, "scheduled", "Successfully assigned %v to %v", pod.Name, dest) // tell the model to assume that this binding took effect. assumed := *pod assumed.Spec.NodeName = dest s.config.Modeler.AssumePod(&assumed) }) }
func (s *Scheduler) scheduleOne() { pod := s.config.NextPod() if s.config.BindPodsRateLimiter != nil { s.config.BindPodsRateLimiter.Accept() } glog.V(3).Infof("Attempting to schedule: %v", pod) start := time.Now() defer func() { metrics.E2eSchedulingLatency.Observe(metrics.SinceInMicroseconds(start)) }() dest, err := s.config.Algorithm.Schedule(pod, s.config.MinionLister, s.config.Cloud) metrics.SchedulingAlgorithmLatency.Observe(metrics.SinceInMicroseconds(start)) if err != nil { glog.V(1).Infof("Failed to schedule: %v", pod) s.config.Recorder.Eventf(pod, "failedScheduling", "%v", err) s.config.Error(pod, err) return } b := &api.Binding{ ObjectMeta: api.ObjectMeta{Namespace: pod.Namespace, Name: pod.Name}, Target: api.ObjectReference{ Kind: "Node", Name: dest, }, } if s.config.Cloud != nil { ext, supported := s.config.Cloud.SchedulerExtension() if supported { annotations, err := ext.Bind(pod, dest) if err != nil { glog.V(1).Infof("Failed to bind pod %s with cloud provider, error: %s", pod.Name, err.Error()) s.config.Recorder.Eventf(pod, "failedBind", "Binding rejected by cloud provider: %s", err.Error()) s.config.Error(pod, err) return } // Copy the annotations to the binding, to be copied over to the pod. b.Annotations = make(map[string]string) for k, v := range annotations { b.Annotations[k] = v } } } // We want to add the pod to the model iff the bind succeeds, but we don't want to race // with any deletions, which happen asynchronously. s.config.Modeler.LockedAction(func() { bindingStart := time.Now() err := s.config.Binder.Bind(b) metrics.BindingLatency.Observe(metrics.SinceInMicroseconds(bindingStart)) if err != nil { glog.V(1).Infof("Failed to bind pod: %v", err) s.config.Recorder.Eventf(pod, "failedScheduling", "Binding rejected: %v", err) s.config.Error(pod, err) if s.config.Cloud != nil { ext, supported := s.config.Cloud.SchedulerExtension() if supported { err := ext.Unbind(pod) if err != nil { glog.V(1).Infof("Failed to unbind pod %s with cloud provider, error: %s", pod.Name, err.Error()) s.config.Recorder.Eventf(pod, "failedUnbind", "Unbind failed with cloud provider: %s", err.Error()) } } } return } s.config.Recorder.Eventf(pod, "scheduled", "Successfully assigned %v to %v", pod.Name, dest) // tell the model to assume that this binding took effect. assumed := *pod assumed.Spec.NodeName = dest s.config.Modeler.AssumePod(&assumed) }) }