|
43 | 43 | forceReboot bool |
44 | 44 | drainDelay time.Duration |
45 | 45 | drainTimeout time.Duration |
| 46 | + globalDrainTimeout time.Duration |
46 | 47 | rebootDelay time.Duration |
47 | 48 | rebootMethod string |
48 | 49 | period time.Duration |
@@ -129,6 +130,8 @@ func main() { |
129 | 130 | flag.DurationVar(&drainDelay, "drain-delay", 0, |
130 | 131 | "delay drain for this duration (default: 0, disabled)") |
131 | 132 | flag.DurationVar(&drainTimeout, "drain-timeout", 0, |
| 133 | + "timeout after which an individual drain is aborted if global-drain-timeout is not set this is the full timeout (default: 0, infinite time)") |
| 134 | + flag.DurationVar(&globalDrainTimeout, "global-drain-timeout", 0, |
132 | 135 | "timeout after which the drain is aborted (default: 0, infinite time)") |
133 | 136 | flag.DurationVar(&rebootDelay, "reboot-delay", 0, |
134 | 137 | "delay reboot for this duration (default: 0, disabled)") |
@@ -214,6 +217,9 @@ func main() { |
214 | 217 | log.Fatal("KURED_NODE_ID environment variable required") |
215 | 218 | } |
216 | 219 | log.Infof("Node ID: %s", nodeID) |
| 220 | + if globalDrainTimeout > 0 && drainTimeout == 0 { |
| 221 | + log.Fatal("global-drain-timeout is set, but drain-timeout is not set. Please set drain-timeout to a value greater than 0.") |
| 222 | + } |
217 | 223 |
|
218 | 224 | notifyURL = validateNotificationURL(notifyURL, slackHookURL) |
219 | 225 |
|
@@ -616,6 +622,7 @@ func rebootAsRequired(nodeID string, rebooter reboot.Rebooter, checker checkers. |
616 | 622 |
|
617 | 623 | source = rand.NewSource(time.Now().UnixNano()) |
618 | 624 | tick = delaytick.New(source, period) |
| 625 | +MAIN: |
619 | 626 | for range tick { |
620 | 627 | if !window.Contains(time.Now()) { |
621 | 628 | // Remove taint outside the reboot time window to allow for normal operation. |
@@ -676,18 +683,42 @@ func rebootAsRequired(nodeID string, rebooter reboot.Rebooter, checker checkers. |
676 | 683 | continue |
677 | 684 | } |
678 | 685 | } |
679 | | - |
680 | | - err = drain(client, node) |
681 | | - if err != nil { |
682 | | - if !forceReboot { |
683 | | - log.Errorf("Unable to cordon or drain %s: %v, will release lock and retry cordon and drain before rebooting when lock is next acquired", node.GetName(), err) |
684 | | - err = lock.Release() |
685 | | - if err != nil { |
686 | | - log.Errorf("Error releasing lock: %v", err) |
| 686 | + if globalDrainTimeout == 0 { |
| 687 | + err = drain(client, node) |
| 688 | + if err != nil { |
| 689 | + if !forceReboot { |
| 690 | + log.Errorf("Unable to cordon or drain %s: %v, will release lock and retry cordon and drain before rebooting when lock is next acquired", node.GetName(), err) |
| 691 | + err = lock.Release() |
| 692 | + if err != nil { |
| 693 | + log.Errorf("Error releasing lock: %v", err) |
| 694 | + } |
| 695 | + log.Infof("Performing a best-effort uncordon after failed cordon and drain") |
| 696 | + uncordon(client, node) |
| 697 | + continue |
| 698 | + } |
| 699 | + } |
| 700 | + } else { |
| 701 | + deadline := time.Now().Add(globalDrainTimeout) |
| 702 | + for { |
| 703 | + if time.Now().After(deadline) { |
| 704 | + log.Errorf("Drain timed out after global timeout (%v) for node %s", globalDrainTimeout, node.GetName()) |
| 705 | + if !forceReboot { |
| 706 | + err = lock.Release() |
| 707 | + if err != nil { |
| 708 | + log.Errorf("Error releasing lock: %v", err) |
| 709 | + } |
| 710 | + log.Infof("Performing a best-effort uncordon after failed cordon and drain") |
| 711 | + uncordon(client, node) |
| 712 | + time.Sleep(period * 2) // Wait at least two periods before retrying, giving other nodes a chance to drain instead |
| 713 | + continue MAIN |
| 714 | + } |
| 715 | + break |
| 716 | + } |
| 717 | + err = drain(client, node) |
| 718 | + if err == nil { |
| 719 | + // Drain was successful, break out of the loop |
| 720 | + break |
687 | 721 | } |
688 | | - log.Infof("Performing a best-effort uncordon after failed cordon and drain") |
689 | | - uncordon(client, node) |
690 | | - continue |
691 | 722 | } |
692 | 723 | } |
693 | 724 |
|
|
0 commit comments