为Docker Swarm添加调度策略(2)

1.添加一个函数,定义一个constraint称为multihostConstraint,意思是同一个service的不同副本要落到不同主机上,与其它强制性的constraint不一样,这个是尽量满足的constraint

//检查某个结点是否已经存在属于同一个service的task
func meetMultihosConstraint(nodeInfo *NodeInfo, serviceID string) bool {
    for _, task := range nodeInfo.Tasks {
        sID = task.ServiceID
        if sID == serviceID {
            return false
        }
    }
    return true
}

2.修改搜索nodeHeap的函数searchHeapToFindMin,加一个参数serviceID

func (nh *nodeHeap) searchHeapToFindMin(
    meetsConstraints func(*NodeInfo) bool,
    serviceID string)
            (*api.Node, int) {
    var bestNode *api.Node  //满足multihostConstraint同时task最少的结点
    var secondBestNode *api.Node //没有满足multihostConstraint的,只能选一个task最少的结点
    minTasks := int(^uint(0) >> 1) // max int
    secondMinTasks := minTasks
 
    if nh == nil || len(nh.heap) == 0 {
        return bestNode, minTasks
    }
 
    // push root to stack for search
    stack := []int{0}
 
    for len(stack) != 0 {
        // pop an element
        idx := stack[len(stack)-1]
        stack = stack[0 : len(stack)-1]
        heapEntry := &nh.heap[idx]
        if len(heapEntry.Tasks) >= minTasks {
            continue
        }
 
        if meetsConstraints(heapEntry) {
 
            //满足强制性constraint,再检查是否满足multihostConstraint
            if meetMultihosConstraint(heapEntry, serviceID) == true {
                bestNode = heapEntry.Node
                minTasks = len(heapEntry.Tasks)
            } else {
                if(len(heapEntry.Tasks) < secondMinTasks) {
                    secondBestNode = heapEntry.Node
                    secondMinTasks = len(heapEntry.Tasks)
                }
            }
        } else {
            // otherwise, push 2 children to stack for further search
            if 2*idx+1 < len(nh.heap) {
                stack = append(stack, 2*idx+1)
            }
            if 2*idx+2 < len(nh.heap) {
                stack = append(stack, 2*idx+2)
            }
        }
    }
 
    if bestNode == nil {
        bestNode = secondBestNode
        minTasks = secondMinTasks
    }
 
    return bestNode, minTasks
 
}

修改代码docker/vendor/src/github.com/docker/swarmkit/manager/scheduler/scheduler.go里的scheduleTask函数

// scheduleTask schedules a single task.
func (s *Scheduler) scheduleTask(ctx context.Context, t *api.Task) *api.Task {
 s.pipeline.SetTask(t)
 //这个函数直接改成searchHeapToFindMin
 //s.scanAllNodes是是否扫描全部结点的标志,直接改成false
 //n, _ := s.nodeHeap.findMin(s.pipeline.Process, s.scanAllNodes)
 n,_  := s.nodeHeap.searchHeapToFindMin(s.pipeline.Process, false, t.ServiceID)

更多Docker相关教程见以下内容

Docker安装应用(CentOS 6.5_x64)

Ubuntu 14.04安装Docker 

Ubuntu使用VNC运行基于Docker的桌面系统 

Docker开发平台的构建 

Ubuntu 15.04下安装Docker 

在Ubuntu Trusty 14.04 (LTS) (64-bit)安装Docker

在 Ubuntu 15.04 上如何安装Docker及基本用法

Ubuntu 16.04上Docker使用手记

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/17c7bdd810fc8f5a254422ede37132fa.html