Repository navigation
Conversation
… nodes removeSshFirewallRule took the first TCP firewall rule on the source NAT IP that either starts at the node SSH start port or forwards to port 22. Clusters with separate etcd nodes also have single port rules that forward to port 22, and the rules are listed without an order. After a scale up the node SSH rule is recreated, so an etcd rule can come first and be revoked instead. The scale worker then used its end port as the bound for removing SSH port forwards, removing the etcd forwards too and failing to recreate the node rule. Prefer the rule that starts at the node SSH start port and only fall back to the port forwarding match when no such rule exists. Fixes apache#14159
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## 4.22 #14165 +/- ##
=========================================
Coverage 17.94% 17.94%
- Complexity 16147 16151 +4
=========================================
Files 5928 5928
Lines 535188 535192 +4
Branches 65499 65502 +3
=========================================
+ Hits 96020 96034 +14
+ Misses 428240 428228 -12
- Partials 10928 10930 +2
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:
|
|
@blueorangutan package |
|
@kiranchavala a [SL] Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress. |
|
Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 19245 |
|
@kiranchavala , were you planning to test this? |
| } | ||
| if (rule == null) { | ||
| PortForwardingRuleVO pfRule = portForwardingRulesDao.findByNetworkAndPorts(networkId, firewallRule.getSourcePortStart(), firewallRule.getSourcePortEnd()); | ||
| if (Objects.nonNull(pfRule) && pfRule.getDestinationPortStart() == DEFAULT_SSH_PORT) { |
There was a problem hiding this comment.
if the 2222 rule was deleted by hand, can this still pick an etcd rule and wipe the etcd forwarding again? the caller already falls back to a safe range when nothing is found
There was a problem hiding this comment.
Good catch. You are right that with the 2222 range rule gone, the fallback matches the first rule forwarding to 22, and the etcd rules at 50000+ do, so it could grab one and the scale path would then wipe 2222..50000. Since the caller already bounds its cleanup safely on a null return, I capped the fallback below KubernetesEtcdNodeStartPort so it never crosses into the etcd range, with a test for the no-node-rule case. Pushed in 75edb36.
There was a problem hiding this comment.
the cap below the etcd start port in 75edb36 covers it
| } | ||
| } | ||
| } | ||
| if (rule != null) { |
There was a problem hiding this comment.
on destroy in a network the user keeps, should the etcd rules from 50000 up go too? they stay open and the next cluster with etcd nodes would clash on those ports
There was a problem hiding this comment.
Agreed, the etcd firewall rules at 50000+ were not being revoked on destroy and would linger in a network the user keeps, clashing with the next etcd cluster on those ports. Fixed in the same push: the destroy path now revokes the etcd ingress rules alongside the node and API rules, with a test. 75edb36.
There was a problem hiding this comment.
revoking the etcd rules on destroy in 75edb36 covers it
The SSH-rule lookup fell back to any firewall rule forwarding to port 22 when the node range rule (2222) was absent. etcd nodes also forward 50000+ to 22, so with the node rule deleted by hand the fallback could pick an etcd rule and the scale path would then wipe 2222..50000. Bound the fallback below KubernetesEtcdNodeStartPort; the caller already falls back to a safe range when no rule is returned. Also revoke the etcd ingress firewall rules on cluster destroy. They were left open in a network the user keeps, so the next cluster with etcd nodes clashed on those ports.
Damans227
left a comment
There was a problem hiding this comment.
thanks @rootnomad, fix looks right. LGTM
Description
Fixes #14159
When a CKS cluster on an isolated network is scaled,
scaleKubernetesClusterIsolatedNetworkRulesrevokes the SSH firewall rule found byremoveSshFirewallRuleand then removes the SSH port forwarding rules from port 2222 up to that rule's end port, before creating the rules again for the new node count.removeSshFirewallRuletakes the first TCP firewall rule on the source NAT IP that either starts at 2222 or has a port forwarding rule to port 22. Clusters with separate etcd nodes also have single port firewall rules (fromcloud.kubernetes.etcd.node.start.port, 50000 by default) that forward to port 22, and the rules are listed without an order. After a scale up the node rule is created again, so it comes after the etcd rules, and the next scale picks an etcd rule instead. The bound for removing the port forwarding rules then becomes 2222 to 50000, which also removes the etcd node's forwarding rule, the node rule is left in place, and creating the node rule for the new size fails with a conflict, as described in the issue.This makes
removeSshFirewallRuleprefer the rule that starts at 2222, which is always created for the control and worker nodes, and only fall back to the port forwarding match when there is no such rule. The destroy path uses the same method, so it now revokes the node rule there too.Separate etcd nodes came with #9102, so this targets 4.22.
Types of changes
Feature/Enhancement Scale or Bug Severity
Feature/Enhancement Scale
Bug Severity
Screenshots (if appropriate):
N/A
How Has This Been Tested?
Unit tests in
KubernetesClusterResourceModifierActionWorkerTestfor the etcd rule listed before the node rule, the fallback to a port forwarded rule, and no SSH rule at all. The first one fails before the change and passes after it; the kubernetes-service tests pass.Live tested on a KVM zone running a 4.22 build, with the v1.34.7 CKS ISO (it includes etcd) and a cluster with 1 control node, 1 worker node and 1 etcd node on an isolated network,
cloud.kubernetes.etcd.node.start.portleft at 50000. One etcd node is enough to hit it. The TCP firewall rules on the source NAT IP are shown in the order they are listed.Before the change, after creating the cluster:
After scaling to 2 workers the node rule is created again, so it is now listed last:
Scaling back to 1 worker fails:
The etcd rule on 50000 is revoked instead of the node rule, all SSH port forwarding rules are removed, including the etcd node's forward on 50000, 2222-2224 is left in place and the cluster goes to Alert.
With 3 etcd nodes, the layout from the issue, it is the same. After scaling to 2 workers:
Scaling back to 1 worker fails with the same error. The rule on 50000 is revoked, the forwards from 2222 up to 50000 are removed (the control and worker nodes and the first etcd node), the forwards on 50001 and 50002 stay, 2222-2224 is left in place and the cluster goes to Alert.
With the change, on a new cluster with the same layout, the rules after create and after scaling to 2 workers are listed the same way as before, with the node rule after the etcd rule:
Scaling back to 1 worker now works. The node rule is revoked and created again for the new size, and the etcd rule and its forward stay:
The cluster stays Running with 1 control node, 1 worker node and 1 etcd node.
With 3 etcd nodes, scaling 1 to 2 to 1 to 2 to 1 works each time. After every scale up the node rule is listed after the etcd rules, and every scale down revokes the node rule and creates it again for the new size, while the etcd rules and their forwards stay:
The cluster stays Running with 1 control node, 1 worker node and 3 etcd nodes.
How did you try to break this feature and the system with this change?
Scaled up and down twice on the fixed build with the etcd rules listed before the node rule, which is the case that failed before. Deleted the clusters with the change in place, since the delete path also uses
removeSshFirewallRule, and nothing was left behind. Created a cluster without etcd nodes and scaled it 1 to 2 to 1, the node rule went 2222-2223, 2222-2224, 2222-2223 as before. When there is no rule starting at 2222, the port forwarding match from before is still used, which the unit tests cover.