mirror of https://github.com/docker/docs.git
Initial scheduler implementation.
The scheduler is composed of filters (to apply constraints) and a placement strategy (random, bin packing, ...). Signed-off-by: Andrea Luzzardi <aluzzardi@gmail.com>
This commit is contained in:
parent
23fa208ab9
commit
006f5e7118
|
|
@ -0,0 +1,24 @@
|
||||||
|
package filter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/docker/libcluster"
|
||||||
|
"github.com/samalba/dockerclient"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Filter interface {
|
||||||
|
// Return a subset of nodes that were accepted by the filtering policy.
|
||||||
|
Filter(*dockerclient.ContainerConfig, []*libcluster.Node) ([]*libcluster.Node, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply a set of filters in batch.
|
||||||
|
func ApplyFilters(filters []Filter, config *dockerclient.ContainerConfig, nodes []*libcluster.Node) ([]*libcluster.Node, error) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
for _, filter := range filters {
|
||||||
|
nodes, err = filter.Filter(config, nodes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nodes, nil
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
package scheduler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/docker/libcluster"
|
||||||
|
"github.com/docker/libcluster/scheduler/filter"
|
||||||
|
"github.com/docker/libcluster/scheduler/strategy"
|
||||||
|
"github.com/samalba/dockerclient"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Scheduler struct {
|
||||||
|
sync.Mutex
|
||||||
|
|
||||||
|
cluster *libcluster.Cluster
|
||||||
|
strategy strategy.PlacementStrategy
|
||||||
|
filters []filter.Filter
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewScheduler(cluster *libcluster.Cluster) *Scheduler {
|
||||||
|
return &Scheduler{
|
||||||
|
cluster: cluster,
|
||||||
|
strategy: &strategy.RandomPlacementStrategy{},
|
||||||
|
filters: []filter.Filter{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find a nice home for our container.
|
||||||
|
func (s *Scheduler) selectNodeForContainer(config *dockerclient.ContainerConfig) (*libcluster.Node, error) {
|
||||||
|
candidates := []*libcluster.Node{}
|
||||||
|
for _, node := range s.cluster.Nodes() {
|
||||||
|
candidates = append(candidates, node)
|
||||||
|
}
|
||||||
|
|
||||||
|
accepted, err := filter.ApplyFilters(s.filters, config, candidates)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.strategy.PlaceContainer(config, accepted)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Schedule a brand new container into the cluster.
|
||||||
|
func (s *Scheduler) CreateContainer(config *dockerclient.ContainerConfig, name string) (*libcluster.Container, error) {
|
||||||
|
s.Lock()
|
||||||
|
defer s.Unlock()
|
||||||
|
|
||||||
|
node, err := s.selectNodeForContainer(config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return node.Create(config, name, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove a container from the cluster. Containers should always be destroyed
|
||||||
|
// through the scheduler to guarantee atomicity.
|
||||||
|
func (s *Scheduler) RemoveContainer(container *libcluster.Container, force bool) error {
|
||||||
|
s.Lock()
|
||||||
|
defer s.Unlock()
|
||||||
|
|
||||||
|
return container.Node().Remove(container, force)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
package strategy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/docker/libcluster"
|
||||||
|
"github.com/samalba/dockerclient"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Randomly place the container into the cluster.
|
||||||
|
type RandomPlacementStrategy struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *RandomPlacementStrategy) PlaceContainer(config *dockerclient.ContainerConfig, nodes []*libcluster.Node) (*libcluster.Node, error) {
|
||||||
|
for _, node := range nodes {
|
||||||
|
return node, nil
|
||||||
|
}
|
||||||
|
return nil, errors.New("No nodes running in the cluster")
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
package strategy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/docker/libcluster"
|
||||||
|
"github.com/samalba/dockerclient"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PlacementStrategy interface {
|
||||||
|
// Given a container configuration and a set of nodes, select the target
|
||||||
|
// node where the container should be scheduled.
|
||||||
|
PlaceContainer(config *dockerclient.ContainerConfig, nodes []*libcluster.Node) (*libcluster.Node, error)
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue