@@ -3,6 +3,8 @@ package drain
33import (
44 "context"
55 "fmt"
6+ "strings"
7+ "time"
68
79 "github.com/sirupsen/logrus"
810 "k8s.io/api/core/v1"
@@ -13,6 +15,11 @@ import (
1315 "k8s.io/client-go/kubernetes"
1416)
1517
18+ const (
19+ // Wait up to this amount of time for pods to be evicted from a node.
20+ drainMaxWait = 300 * time .Second
21+ )
22+
1623// Config configures a Drainer.
1724type Config struct {
1825 Client kubernetes.Interface
@@ -74,6 +81,7 @@ func (d *drainer) Drain(ctx context.Context, node string) error {
7481 return err
7582 }
7683
84+ evictedPods := []string {}
7785 for _ , pod := range pods {
7886 fields ["pod" ] = pod .GetName ()
7987 d .log .WithFields (fields ).Info ("drainer: evicting pod" )
@@ -83,6 +91,43 @@ func (d *drainer) Drain(ctx context.Context, node string) error {
8391 d .log .WithFields (fields ).Errorf ("drainer: error evicting pod: %v" , err )
8492 return err
8593 }
94+ evictedPods = append (evictedPods , pod .GetName ())
95+ }
96+
97+ start := time .Now ()
98+ for len (evictedPods ) > 0 {
99+ podsDescription := ""
100+ if len (evictedPods ) > 5 {
101+ podsDescription = strings .Join (evictedPods [:5 ], ", " ) + " ..."
102+ } else {
103+ podsDescription = strings .Join (evictedPods , ", " )
104+ }
105+ d .log .WithFields (fields ).Infof ("drainer: waiting for %d pods to be evicted: %s" , len (evictedPods ), podsDescription )
106+
107+ if time .Since (start ) > drainMaxWait {
108+ d .log .WithFields (fields ).Infof ("drainer: waited maximum amount of time for evictions, continuing" )
109+ break
110+ }
111+
112+ pods , err := d .getPodsForDeletion (ctx , node )
113+ if err != nil {
114+ d .log .WithFields (fields ).Errorf ("drainer: error getting pods: %v" , err )
115+ return err
116+ }
117+ podsByName := make (map [string ]struct {}, len (pods ))
118+ for _ , pod := range pods {
119+ podsByName [pod .GetName ()] = struct {}{}
120+ }
121+ remainingPods := []string {}
122+ for _ , pod := range evictedPods {
123+ if _ , ok := podsByName [pod ]; ok {
124+ remainingPods = append (remainingPods , pod )
125+ }
126+ }
127+ evictedPods = remainingPods
128+ if len (evictedPods ) > 0 {
129+ time .Sleep (1 * time .Second )
130+ }
86131 }
87132
88133 d .log .WithFields (fields ).Info ("drainer: drained node" )
0 commit comments