EvacuationController主要处理 darin 以及 migrate。大体来说会计算出该节点目前的migration创建上限,对于该节点上需要并且可以驱逐的vmi 创建相应migration。informer 有vmiInformer、vmiPodInformer、migrationInformer以及nodeInformer。将obj相关的node加入处理队列。

图1 evacuationController 总体流程
逻辑入口在pkg/virt-controller/watch/drain/evacuation/evacuation.go execute
首先确定节点存在以及其上的 migration 已经处理完成。
1
2
3
4
5
6
7
8
|
if !exists {
c.migrationExpectations.DeleteExpectations(key)
return nil
}
if !c.migrationExpectations.SatisfiedExpectations(key) {
return nil
}
|
接着列出节点上的 vmi 以及还没有完成的 migration,然后进入sync流程
1
2
3
4
5
6
7
8
|
vmis, err := c.listVMIsOnNode(node.Name)
if err != nil {
return fmt.Errorf("failed to list VMIs on node: %v", err)
}
migrations := migrationutils.ListUnfinishedMigrations(c.migrationInformer)
return c.sync(node, vmis, migrations)
|
首先vmisToMigrate
找出需要迁移的 vmi,如果 node 包含 taint 则节点上所有 vmi 都需要迁移,否则 vmi 被 Evacuation 且还未开始迁移。
1
|
vmi.IsMarkedForEviction() && !hasMigratedOnEviction(vmi) && !migrationutils.IsMigrating(vmi)
|
接着filterRunningNonMigratingVMIs
找到 vmi Pod 都停掉,spec 设置了 LiveMigrate 以及 LiveMigratable 为 true 且暂时没有 migrate 的 vmi。将 需要迁移的vmi 分成可迁移和不可迁移的两类;
接着算出source vmi 在此节点上的 migration 的数目;
以及集群中的最大节点并行migtation 数目,以及集群中的最大migration 并行数;
首先计算集群集群中的最大migration 并行数 - 现在active的 migration数freeSpotsPerCluster
;
其次算出最大节点并行migtation 数目 - source vmi 在此节点上的 migration 的数目 freeSpotsPerThisSourceNode
;
取两数中较小的作为上限freeSpots
;
1
2
3
4
5
6
7
8
|
migrationCandidates, nonMigrateable := c.filterRunningNonMigratingVMIs(vmisToMigrate, activeMigrations)
activeMigrationsFromThisSourceNode := c.numOfVMIMForThisSourceNode(vmisOnNode, activeMigrations)
maxParallelMigrationsPerOutboundNode :=
int(*c.clusterConfig.GetMigrationConfiguration().ParallelOutboundMigrationsPerNode)
maxParallelMigrations := int(*c.clusterConfig.GetMigrationConfiguration().ParallelMigrationsPerCluster)
freeSpotsPerCluster := maxParallelMigrations - len(activeMigrations)
freeSpotsPerThisSourceNode := maxParallelMigrationsPerOutboundNode - activeMigrationsFromThisSourceNode
freeSpots := int(math.Min(float64(freeSpotsPerCluster), float64(freeSpotsPerThisSourceNode)))
|
diff
为 freeSpots
和 可迁移vmi 数中的较小值;
remaining
为还富余的 migration 数目;
1
2
3
|
diff := int(math.Min(float64(freeSpots), float64(len(migrationCandidates))))
remaining := freeSpots - diff
remainingForNonMigrateableDiff := int(math.Min(float64(remaining), float64(len(nonMigrateable))))
|
如果有富余且有不可迁移 的vmi则对这这两个数字中较小的remainingForNonMigrateableDiff
个 vmi 添加 event 。
VirtualMachineInstance is not migrateable
选出 diff
个可迁移的 vmi,使用&sync.WaitGroup 创建相应的 migration。