Skip to content

Conversation

pkazmierczak
Copy link
Contributor

Canaries for system jobs are placed on a tg.update.canary percent of eligible nodes. Some of these nodes may not be feasible, and until now we removed infeasible nodes during placement computation. However, if it happens to be that the first eligible node we picked to place a canary on is infeasible, this will lead to the scheduler halting deployment.

The solution presented here simplifies canary deployments: initially, system jobs that use canary updates get allocations placed on all eligible nodes, but before we start computing actual placements, a method called evictCanaries is called (much like evictAndPlace is for honoring MaxParallel), and performs a feasibility check on each node up to the amount of required canaries per task group. Feasibility checks are expensive, but this way we only check all the nodes in the worst case scenario (with canary=100), otherwise we stop checks once we know we are ready to place enough canaries.

…uting placements

Canaries for system jobs are placed on a tg.update.canary percent of
eligible nodes. Some of these nodes may not be feasible, and until now
we removed infeasible nodes during placement computation. However, if it
happens to be that the first eligible node we picked to place a canary
on is infeasible, this will lead to the scheduler halting deployment.

The solution presented here simplifies canary deployments: initially,
system jobs that use canary updates get allocations placed on all
eligible nodes, but before we start computing actual placements, a
method called `evictCanaries` is called (much like `evictAndPlace` is
for honoring MaxParallel), and performs a feasibility check on each node
up to the amount of required canaries per task group. Feasibility checks
are expensive, but this way we only check all the nodes in the worst
case scenario (with canary=100), otherwise we stop checks once we know
we are ready to place enough canaries.
Comment on lines +608 to +613
// we only now the total amountn of placements once we filter out
// infeasible nodes, so for system jobs we do it backwards a bit: the
// "desired" total is the total we were able to place.
if s.deployment != nil {
s.deployment.TaskGroups[tgName].DesiredTotal += 1
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For system jobs I think we need to make sure we're working from a blank slate dstate for each evaluation. Incrementing this here is adding on top of the desired total from previous evals.

Comment on lines +761 to +766
// ensure everything is healthy
if dstate, ok := s.deployment.TaskGroups[groupName]; ok {
if dstate.HealthyAllocs < dstate.DesiredTotal { // Make sure we have enough healthy allocs
complete = false
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're resetting desired total in computePlacements, it won't be correctly set when we reach isDeploymentComplete, which is called before that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants