Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add percentage functionality #34

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions chaoskube/chaoskube.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,15 @@ func (c *Chaoskube) Candidates() ([]v1.Pod, error) {
return pods, nil
}

// Returns the number of deletable candidates
func (c *Chaoskube) NumberOfCandidates() (int, error) {
pods, err := c.Candidates()
if err != nil {
return -1, err
}
return len(pods), nil
}

// Victim returns a random pod from the list of Candidates.
func (c *Chaoskube) Victim() (v1.Pod, error) {
pods, err := c.Candidates()
Expand Down
43 changes: 37 additions & 6 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ var (
deploy bool
dryRun bool
debug bool
percentage int
)

func init() {
Expand All @@ -43,16 +44,21 @@ func init() {
kingpin.Flag("namespaces", "A set of namespaces to restrict the list of affected pods. Defaults to everything.").Default(v1.NamespaceAll).StringVar(&nsString)
kingpin.Flag("master", "The address of the Kubernetes cluster to target").StringVar(&master)
kingpin.Flag("kubeconfig", "Path to a kubeconfig file").StringVar(&kubeconfig)
kingpin.Flag("interval", "Interval between Pod terminations").Short('i').Default("10m").DurationVar(&interval)
kingpin.Flag("interval", "Interval between Pod terminations").Short('i').DurationVar(&interval)
kingpin.Flag("deploy", "If true, deploys chaoskube in the current cluster with the provided configuration").Short('d').BoolVar(&deploy)
kingpin.Flag("dry-run", "If true, don't actually do anything.").Default("true").BoolVar(&dryRun)
kingpin.Flag("debug", "Enable debug logging.").BoolVar(&debug)
kingpin.Flag("percentage", "Percentage of pods to be terminated per hour").Short('p').IntVar(&percentage)
}

func main() {
kingpin.Version(version)
kingpin.Parse()

if (interval.Nanoseconds() != 0 && percentage != 0) || (interval.Nanoseconds() == 0 && percentage == 0) {
log.Fatal("Needs exactly one of 'interval' or 'percentage' to be set.")
}

if debug {
log.SetLevel(log.DebugLevel)
}
Expand Down Expand Up @@ -115,15 +121,40 @@ func main() {
}

chaoskube := chaoskube.New(client, labelSelector, annotations, namespaces, log.StandardLogger(), dryRun, time.Now().UTC().UnixNano())

ticker := updatedTicker(chaoskube, percentage)
for {
if err := chaoskube.TerminateVictim(); err != nil {
log.Fatal(err)
select {
case <-ticker.C:
ticker.Stop()
if err := chaoskube.TerminateVictim(); err != nil {
log.Fatal(err)
}
ticker = updatedTicker(chaoskube, percentage)
}
}
}

log.Debugf("Sleeping for %s...", interval)
time.Sleep(interval)
func updatedTicker(chaoskube *chaoskube.Chaoskube, percentage int) *time.Ticker {
oldInterval := interval
if interval.Nanoseconds() == 0 {
interval = calculateInterval(chaoskube, percentage)
}
if interval < 1 {
interval = 0
}
ticker := time.NewTicker(interval)
if interval != oldInterval {
log.Infof("Changing interval to: %s", interval)
}
return ticker
}

func calculateInterval(chaoskube *chaoskube.Chaoskube, percentage int) time.Duration {
num, err := chaoskube.NumberOfCandidates()
if err != nil {
log.Fatal(err)
}
return (time.Millisecond * (time.Duration(int((3600000.0 / float32(num)) * (100.0 / float32(percentage))))))
}

func newClient() (*kubernetes.Clientset, error) {
Expand Down