Skip to content

Commit

Permalink
Only evict via live migration when only a single active pod is runnin…
Browse files Browse the repository at this point in the history
…g for a VMI

Signed-off-by: David Vossel <[email protected]>
  • Loading branch information
davidvossel committed Apr 21, 2021
1 parent 68a236e commit a5a6109
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 5 deletions.
1 change: 1 addition & 0 deletions pkg/virt-controller/watch/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,7 @@ func (vca *VirtControllerApp) initEvacuationController() {
vca.vmiInformer,
vca.migrationInformer,
vca.nodeInformer,
vca.kvPodInformer,
recorder,
vca.clientSet,
vca.clusterConfig,
Expand Down
54 changes: 49 additions & 5 deletions pkg/virt-controller/watch/drain/evacuation/evacuation.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type EvacuationController struct {
clientset kubecli.KubevirtClient
Queue workqueue.RateLimitingInterface
vmiInformer cache.SharedIndexInformer
vmiPodInformer cache.SharedIndexInformer
migrationInformer cache.SharedIndexInformer
recorder record.EventRecorder
migrationExpectations *controller.UIDTrackingControllerExpectations
Expand All @@ -45,6 +46,7 @@ func NewEvacuationController(
vmiInformer cache.SharedIndexInformer,
migrationInformer cache.SharedIndexInformer,
nodeInformer cache.SharedIndexInformer,
vmiPodInformer cache.SharedIndexInformer,
recorder record.EventRecorder,
clientset kubecli.KubevirtClient,
clusterConfig *virtconfig.ClusterConfig,
Expand All @@ -55,6 +57,7 @@ func NewEvacuationController(
vmiInformer: vmiInformer,
migrationInformer: migrationInformer,
nodeInformer: nodeInformer,
vmiPodInformer: vmiPodInformer,
recorder: recorder,
clientset: clientset,
migrationExpectations: controller.NewUIDTrackingControllerExpectations(controller.NewControllerExpectations()),
Expand Down Expand Up @@ -463,13 +466,41 @@ func (c *EvacuationController) listVMIsOnNode(nodeName string) ([]*virtv1.Virtua
return vmis, nil
}

func (c *EvacuationController) numRunningPods(vmi *virtv1.VirtualMachineInstance) int {

objs, err := c.vmiPodInformer.GetIndexer().ByIndex(cache.NamespaceIndex, vmi.Namespace)
if err != nil {
return 0
}

running := 0
for _, obj := range objs {
pod := obj.(*k8sv1.Pod)

if pod.Status.Phase == k8sv1.PodSucceeded || pod.Status.Phase == k8sv1.PodFailed {
// not interested in terminated pods
continue
} else if !controller.IsControlledBy(pod, vmi) {
// not interested pods not associated with the vmi
continue
}
running++
}

return running
}

func (c *EvacuationController) filterRunningNonMigratingVMIs(vmis []*virtv1.VirtualMachineInstance, migrations []*virtv1.VirtualMachineInstanceMigration) (migrateable []*virtv1.VirtualMachineInstance, nonMigrateable []*virtv1.VirtualMachineInstance) {
lookup := map[string]bool{}
for _, migration := range migrations {
lookup[migration.Namespace+"/"+migration.Spec.VMIName] = true
}

for _, vmi := range vmis {
// vmi is shutting down
if vmi.IsFinal() || vmi.DeletionTimestamp != nil {
continue
}

// does not want to migrate
if vmi.Spec.EvictionStrategy == nil || *vmi.Spec.EvictionStrategy != virtv1.EvictionStrategyLiveMigrate {
Expand All @@ -480,12 +511,25 @@ func (c *EvacuationController) filterRunningNonMigratingVMIs(vmis []*virtv1.Virt
nonMigrateable = append(nonMigrateable, vmi)
continue
}
if exists := lookup[vmi.Namespace+"/"+vmi.Name]; !exists &&
!vmi.IsFinal() && vmi.DeletionTimestamp == nil {
// no migration exists,
// the vmi is running,
migrateable = append(migrateable, vmi)

hasMigration := lookup[vmi.Namespace+"/"+vmi.Name]
// already migrating
if hasMigration {
continue
}

if c.numRunningPods(vmi) > 1 {
// waiting on target/source pods from a previous migration to terminate
//
// We only want to create a migration when num pods == 1 or else we run the
// risk of invalidating our pdb which prevents the VMI from being evicted
continue
}

// no migration exists,
// the vmi is running,
// only one pod is currently active for vmi
migrateable = append(migrateable, vmi)
}
return migrateable, nonMigrateable
}
Expand Down

0 comments on commit a5a6109

Please sign in to comment.