Repository navigation
Allow scaling a Kubernetes cluster that is in Alert - #14604
bhouse-nexthop wants to merge 2 commits into
Conversation
When any node VM of a running cluster isn't Running, the status scanner
moves the cluster to Alert, and scaleKubernetesCluster then refuses every
request:
Kubernetes cluster <name> is in Alert state and can not be scaled
The cluster-autoscaler scales through the same API, so one stopped node
blocks adding capacity, autoscaling, and removing that node with
nodeids, which is when scaling is most needed.
Allow a size change, or removing nodes by nodeids, in Alert:
- state machine: Alert -> Scaling on ScaleUpRequested and
ScaleDownRequested. Scaling -> Running / -> Alert are unchanged, so the
scanner puts the cluster back in Alert if a node is still down.
- the state check moves to validateKubernetesClusterStateForScale. In
Alert it refuses an offering or autoscaling change, which act on every
node (a different minsize/maxsize counts, as in the worker); a request
that changes neither the size nor the nodes, which would only move the
cluster to Running; removing control, etcd or external nodes; any
request while the first control node VM, which scaling reaches over
SSH, isn't running; any request while the cluster has more or fewer
VMs than nodes, for example VMs left by a failed scale-up, which a
scale-up would only add to; any request while a control or etcd VM is
down, as etcd may have lost quorum and new nodes can't join; and any
request while none of its (non-external) worker VMs is down, as the
cluster is then in Alert for another reason, such as a failed start or
upgrade or a VM on a disconnected host, that scaling won't fix.
Sending the offerings and autoscaling setting the cluster already has
is allowed.
- in Alert the worker gets no offerings, so it only changes the size and
can't apply the cluster offering to another node type. The request is
carried out against the cluster as validated, not a fresh read the
scanner may have changed, and fails if the cluster's state has changed
since it was validated (to Alert, or by another operation starting).
- scale-up waits for the nodes whose VMs aren't down to be Ready, rather
than every node: a stopped node is never Ready, so the scale-up always
timed out. The new nodes must all be Ready, and the count is re-read on
every check, in case a VM is started or stopped meanwhile. Capacity is
planned for the new VMs only, as in Running.
- scale-down by size removes workers whose VMs are down first.
- a node whose VM is down is not drained before it is deleted. The drain
waits for pod deletions that a NotReady node can never confirm, so
removing the stopped node always failed.
- "down" is Stopped, Shutdown, Error, Destroyed or Expunging. Migrating,
Unknown and other states may still be running the VM and are treated
as before.
- the UI shows Scale for a cluster in Alert that doesn't autoscale, with
only the size field.
Signed-off-by: Brad House <bhouse@nexthop.ai>
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## 4.22 #14604 +/- ##
==========================================
Coverage 18.32% 18.32%
- Complexity 16644 16679 +35
==========================================
Files 5939 5939
Lines 537768 537878 +110
Branches 65929 65963 +34
==========================================
+ Hits 98551 98586 +35
- Misses 428008 428082 +74
- Partials 11209 11210 +1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
A scale-up waited until the number of Ready nodes matched the provisioned nodes minus those whose VMs are down. Kubernetes keeps reporting the node of a VM that was just stopped as Ready until node-monitor-grace-period runs out (40-50 s). In that window the stopped node makes up the count before a new node has joined, so the scale-up reported success and detached the binaries ISO while the new node was still waiting for it. That node could then never join, and the next scale-up waited on it until the scale timeout. After the count matches, also wait for each new node to be Ready by name, as the upgrade worker does, within the same scale timeout. The ISO is detached only after that. If a new node isn't Ready by the timeout, the scale-up fails as before and the cluster goes to Alert. Signed-off-by: Brad House <bhouse@nexthop.ai>
Test report: scaling a Kubernetes cluster that is in Alert, on a live clusterSummary: with the second commit ("Wait for each new node by name before a scale-up detaches the ISO"), every scenario passes. That includes the case that failed in my first run: the ready-node count is met by a stopped node that Kubernetes still reports as Ready. The scale-up now holds the binaries ISO until the new node is Ready by name, and then succeeds. Scale-down, Environment
Results
S2: the first run's failure, and what changed
S3, S4, S5 on the new build
Not caused by this PR
Result: pass. The fix closes the failure from my first run. A scale-up whose ready count is met early by a stale node now waits for the new node by name, keeps the ISO attached until the node has joined, and succeeds. No node is left stranded for the next scale-up. Everything else in the PR behaves as in the first run. Not covered
|
Description
A Kubernetes cluster in
Alertcan now change its size, and have worker nodes removed withnodeids. PreviouslyscaleKubernetesClusterrefused any request in Alert. So one stopped node VM blocked scaling, and blocked the CloudStack cluster-autoscaler, which scales through the same API. It also blocked removing that stopped node.Fixes #14603
What changes
KubernetesClusterManagerImpl.validateKubernetesClusterStateForScale, moved out ofvalidateKubernetesClusterScaleParameters). In Alert it accepts a size change, or removing worker nodes bynodeids. It refuses:nodeids. Scaling never acts on external nodes; they are removed withremoveVirtualMachinesFromKubernetesCluster;KubernetesCluster):Alert -> ScalingonScaleUpRequestedandScaleDownRequested.Scaling -> Runningon success andScaling -> Alerton failure are unchanged, so the status scanner puts the cluster back in Alert if a node is still down.KubernetesClusterScaleWorker):KubernetesClusterUtil.validateKubernetesClusterReadyNodesCountoverload; the existing signature behaves as before.isKubernetesClusterNodeReady, as the upgrade worker does), within the same scale timeout, before it detaches the binaries ISO. Kubernetes keeps reporting the node of a VM that was just stopped as Ready for 40-50 s (node-monitor-grace-period), and in that window it can make up the count before a new node has joined. The ISO was then detached and the new node could never join.kubectl drain, and deletes the Kubernetes node object directly.nodeids) for now.Running, Created and Stopped clusters behave as before. The exception is a cluster that is still Running while one of its VMs is already down, before the status scanner has moved it to Alert. There, the down node is now removed first, isn't drained, and isn't expected to become Ready.
Types of changes
Feature/Enhancement Scale or Bug Severity
Bug Severity
How Has This Been Tested?
plugins/integrations/kubernetes-service(mvn -pl plugins/integrations/kubernetes-service -am test -Dtest='KubernetesCluster*Test'), pass. Checkstyle onapiand the plugin is clean.KubernetesClusterManagerImplTest:nodeidsfor a worker; a size change sent with the cluster's current offerings and autoscaling setting;KubernetesClusterScaleWorkerTest: a stopped worker is picked first for a scale-down by size; the down-node count leaves out etcd nodes and newly provisioned VMs; which VM states count as down; after a scale-up, the ready-node count leaves out down nodes, each new node is then waited for by its lower-case name, and the scale-up fails if the count matches while a new node isn't Ready.nodeidsremoval were run against a real CKS cluster in Alert (see the lab report in the comments). The first run found a scale-up reporting success before the new node joined, which the second commit fixes. The UI change was not tested in a browser.How did you try to break this feature and the system with this change?
Other states: for Created, Running and Stopped clusters, the state check, the offering map and the existing ready-node check are unchanged. The only difference is the down-VM handling for a Running cluster with a down VM, as described above.
Restarts during a scale-up: the expected Ready count is read again on every check. A stopped VM that HA or a user starts again is then expected to rejoin, and the scale-up can't report success before the new nodes are Ready.
Hosts disconnected or VMs migrating: Unknown and Migrating don't count as down, so those nodes are still drained, and still expected to be Ready.
Concurrent requests: a second scale request is refused at validation once the first has moved the cluster to Scaling. If both are validated before that, the second now fails when its worker starts, because the state has changed. Before, it ran alongside the first. The check and the transition are still separate steps, so a very narrow window remains.
Not covered here:
nodeidsin Running records the wrong worker count. That is unchanged by this PR, and refused in Alert.removeKubernetesClusterNodeincrements its retry counter twice per pass, so it makes fewer attempts than intended.These are existing issues and are left for separate changes.