Affinity-aware allocation replacement in Nomad rolling updates
0 reputation · 18 Aug 2023, 10:37 UTC
0 reputation · 18 Aug 2023, 10:37 UTC
Migrating a small type = service application across heterogeneous node groups using Nomad's rolling update mechanism requires preserving application-local state without triggering temporary downtime.
When dispatch = rolling replaces old allocations, the interaction between reschedule behavior, node affinity constraints, and min_healthy_percentage evaluation is not explicitly documented for all placement configurations, creating uncertainty about whether replacement tasks inherit the same logical node set as terminated allocations.
Does Nomad evaluate affinity before or after health check success when deciding to terminate old allocations? Can placement stanza expressions combined with soft/hard affinity directives guarantee that replacement allocations land on the same logical node set? What min_healthy_percentage value safely balances replacement pacing against affinity-preserving node selection for a three-node job with max_unscheduled = 1?
31775 reputation · 18 Aug 2023, 17:16 UTC
Nomad evaluates affinity and placement constraints when it creates a replacement allocation during a rolling update. This happens before the new allocation is marked healthy; health checks are only run after the allocation is placed and starts. The old allocation is terminated only after the replacement passes its health check.
affinity { rule = "hard" ... }) must be satisfied for the replacement to be placed; if no node matches, the update stalls until a suitable node appears.placement stanza can combine hard/soft affinity with attribute expressions; guarantees of landing on the exact same node set depend on the node attributes remaining unchanged and the affinity being hard.max_unscheduled = 1, setting min_healthy_percentage = 66 (or 67) ensures at least two allocations stay healthy during the update, allowing one node to be taken out for replacement while preserving service availability.job "example" {
type = "service"
dispatch = { rolling = {} }
update {
max_unscheduled = 1
min_healthy_percentage = 66
}
group "api" {
count = 3
affinity {
rule = "hard"
attribute = "${attr.unique.hostname}"
value = "node-group‑alpha"
}
network { port "http" {}}
service {
name = "api"
port = "http"
check { type = "http", path = "/health", interval = "10s" }
}
task "server" {
driver = "docker"
config { image = "myapp:latest" }
}
}
}nomad job run example.nomad to place the initial three allocations.nomad job update -meta version=2 example.nomad status -verbose example and nomad alloc status <alloc-id> to verify that a new allocation appears on a node satisfying the hard affinity before the oldest allocation is marked unhealthy.If you cannot guarantee that node attributes (such as labels or custom attributes) remain static during the update, please confirm whether any node‑level metadata changes are expected; this determines whether the hard affinity guarantee holds.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.