這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
Docker Swarm manage命令的filter選項用來指定scheduler選擇Docker Engine的過濾項,其變數定義如下(cli/flags.go):
// hack for go vetflFilterValue = cli.StringSlice(filter.List())// DefaultFilterNumber is exportedDefaultFilterNumber = len(flFilterValue)flFilter = cli.StringSliceFlag{ Name: "filter, f", Usage: "filter to use [" + strings.Join(filter.List(), ", ") + "]", Value: &flFilterValue,}
獲得filter值的代碼如下(cli/manage.go):
// see https://github.com/codegangsta/cli/issues/160names := c.StringSlice("filter")if c.IsSet("filter") || c.IsSet("f") { names = names[DefaultFilterNumber:]}fs, err := filter.New(names)if err != nil { log.Fatal(err)}
預設情況下,獲得所有的filter(scheduler/filter/filter.go):
func init() { filters = []Filter{ &HealthFilter{}, &PortFilter{}, &SlotsFilter{}, &DependencyFilter{}, &AffinityFilter{}, &ConstraintFilter{}, }}
而Filter是一個interface(scheduler/filter/filter.go):
// Filter is exportedtype Filter interface { Name() string // Return a subset of nodes that were accepted by the filtering policy. Filter(*cluster.ContainerConfig, []*node.Node, bool) ([]*node.Node, error) // Return a list of constraints/filters provided GetFilters(*cluster.ContainerConfig) ([]string, error)}
其中Filter方法用來過濾合格Docker Engine,而GetFilters則返回一個描述過濾條件的字串。
在scheduler/filter/filter.go中,ApplyFilters用來過濾Docker Engine;listAllFilters返回所有的過濾條件:
// ApplyFilters applies a set of filters in batch.func ApplyFilters(filters []Filter, config *cluster.ContainerConfig, nodes []*node.Node, soft bool) ([]*node.Node, error) { var ( err error candidates = nodes ) for _, filter := range filters { candidates, err = filter.Filter(config, candidates, soft) if err != nil { // special case for when no healthy nodes are found if filter.Name() == "health" { return nil, err } return nil, fmt.Errorf("Unable to find a node that satisfies the following conditions %s", listAllFilters(filters, config, filter.Name())) } } return candidates, nil}// listAllFilters creates a string containing all applied filtersfunc listAllFilters(filters []Filter, config *cluster.ContainerConfig, lastFilter string) string { allFilters := "" for _, filter := range filters { list, err := filter.GetFilters(config) if err == nil && len(list) > 0 { allFilters = fmt.Sprintf("%s\n%v", allFilters, list) } if filter.Name() == lastFilter { return allFilters } } return allFilters}