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
Configure TemplateLB with all host addresses #3557
Configure TemplateLB with all host addresses #3557
Conversation
7d8ff81
to
640496b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
main logic lgtm, some suggestions and questions
test/e2e/e2e.go
Outdated
@@ -2276,18 +2276,26 @@ var _ = ginkgo.Describe("e2e ingress traffic validation", func() { | |||
// This test verifies a NodePort service is reachable on manually added IP addresses. | |||
ginkgo.It("for NodePort services", func() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
e2e tests for services belong in services.go
file (I know we have some older tests lying around in e2e.go but goal is to have newer tests in the specific file created for services tests)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved the test to service.go
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
may I ask why the tests in the first PR didn't catch this? I know @dceara mentioned something to me but not sure I got the full picture...basically how was the logic being done in the first PR versus this one? If we hadn't added templating for multiple nodeIP's how was it passing in the first PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test added in #3328 checks services with ETP=local, that AFAIU is implemented without Templates.
func makeLBNodeIPTemplateName(family corev1.IPFamily) string { | ||
return fmt.Sprintf("%s_%v", LBVipNodeTemplate, family) | ||
func makeLBNodeIPTemplateNamePrefix(family corev1.IPFamily) string { | ||
return fmt.Sprintf("%s_%v_", LBVipNodeTemplate, family) | ||
} | ||
|
||
// isLBNodeIPTemplateName returns true if 'name' is the node IP template name | ||
// for any IP family. | ||
func isLBNodeIPTemplateName(name string) bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should change this to isLBNodeIPTemplateNamePrefix
? and update the function description as well to say we now search for prefix
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated the description. I left the function name as is, as it doesn't check if the input string is a prefix. It returns true if the passed name is the name of a NodeIP template. Does it sound good?
@@ -180,15 +175,15 @@ func svcCreateOrUpdateTemplateVar(nbClient libovsdbclient.Client, templateVars [ | |||
} | |||
|
|||
// makeLBNodeIPTemplateName creates a template name for the node IP (per family) | |||
func makeLBNodeIPTemplateName(family corev1.IPFamily) string { | |||
return fmt.Sprintf("%s_%v", LBVipNodeTemplate, family) | |||
func makeLBNodeIPTemplateNamePrefix(family corev1.IPFamily) string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: update the func description to say we are creating a template prefix name for the nodeIP
type NodeIPsTemplates struct { | ||
ipFamily corev1.IPFamily | ||
templateValues []*chassisTemplateValue | ||
chassisIDtoIPCount map[string]int |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this tracking the number of nodeIPs per chassis?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, going to rename it
type chassisTemplateValue struct { | ||
templateName string | ||
chassisID string | ||
value string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is this value
here within the chassisTemplateValue
? Please add some doc strings for this one, et.too.many.value usages....
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed and documented. Let me know if it's clear
@@ -215,3 +210,72 @@ func getTemplatesFromRulesTargets(rules []LBRule) TemplateMap { | |||
} | |||
return templates | |||
} | |||
|
|||
// NodeIPTemplates maintains templates variables for many IP addresses per node, | |||
// creating template variables in the for NODEIP_IPv4_0, NODEIP_IPv4_1, NODEIP_IPv4_2, ... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// creating template variables in the for NODEIP_IPv4_0, NODEIP_IPv4_1, NODEIP_IPv4_2, ... | |
// creating template variables for NODEIP_IPv4_0, NODEIP_IPv4_1, NODEIP_IPv4_2, ... |
?
c.nodeIPv4Template.Value[node.chassisID] = ipv4.String() | ||
ips, err := util.MatchIPFamily(false, nodeInfo.hostAddresses) | ||
if err != nil { | ||
klog.Warningf("Error while searching for IPv4 host addresses: %v", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should probably include the nodeInfo.name in the warning message to make it easier to map it to the node
c.nodeIPv6Template.Value[node.chassisID] = ipv6.String() | ||
ips, err := util.MatchIPFamily(true, nodeInfo.hostAddresses) | ||
if err != nil { | ||
klog.Warningf("Error while searching for IPv6 host addresses: %v", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto: include nodeName in warning message
@@ -510,6 +510,120 @@ func TestSyncServices(t *testing.T) { | |||
} | |||
} | |||
|
|||
func Test_ETPCluster_NodePort_Service_WithMultipleIPAddresses(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thank you for the tests++ nit: suggestion to swap some into IPV6 addresses to cover those bits as well but I won't hold the PR for that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a commit to convert that test to dualstack:
8a973fa
Test code becomes a little bit more complicated. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am good with this thanks @zeeke !
640496b
to
92da78f
Compare
92da78f
to
3585b2f
Compare
99a1050
to
3626614
Compare
3626614
to
ed9a280
Compare
@@ -0,0 +1,79 @@ | |||
package services |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for adding tests!
// AddIP adds a template variable for the specified chassis and ip address. | ||
func (n *NodeIPsTemplates) AddIP(chassisID string, ip net.IP) { | ||
|
||
var i int = -1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm I see this part of code also changed since I previously did a review, not a fan of the starting with i = -1 just using that variable to get the total number of templates we have for the node a.k.a the nodeIPs..., if like @dceara mentions we can leverage the length and figure that out, let's do that...seems cleaner?
ed9a280
to
a1accc1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks!
test/e2e/service.go
Outdated
framework.Failf("failed to add new Addresses to node %s: %v", node.Name, err) | ||
} | ||
|
||
defer runCommand(containerRuntime, "exec", node.Name, "ip", "addr", "delete", newIP+"/32", "dev", "breth0") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: fail the test id this fails
a385454
to
d6b0d8d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/lgtm
thanks @zeeke
d6b0d8d
to
16d5df1
Compare
TemplateLB variables for node IP addresses have to support multiple IP noda address, hence the variables are in the format of NODE_IPv4_0, NODE_IPv4_1, NODE_IPv4_2, ... Struct `NodeIPsTemplates` manage the template variables for multiple nodes that may have different number of IP addresses each. Add unit and e2e tests on TemplateLBs with multiple IP addresses. Refs: ovn-org#3328 Signed-off-by: Andrea Panattoni <apanatto@redhat.com>
Make `Test_ETPCluster_NodePort_Service_WithMultipleIPAddresses` use v4+v6 IP addresses. Signed-off-by: Andrea Panattoni <apanatto@redhat.com>
The test about NodePort services that are reachable on every host IP address should reside in the Service suite. Signed-off-by: Andrea Panattoni <apanatto@redhat.com>
16d5df1
to
454119c
Compare
Flake: [Fail] Load Balancer Service Tests with MetalLB [It] Should ensure load balancer service works with pmtu https://github.com/ovn-org/ovn-kubernetes/actions/runs/4981960698/jobs/8917595516?pr=3557 |
- What this PR does and why is it needed
This PR makes NodePort services with
ExternalClusterPolicy=Cluster
to be servedon every host address.
It's meant to be a continuation of
- Special notes for reviewers
cc @dceara
- How to verify it
- Description for the changelog