Skip to content
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

NodePort mode does not fully support dual-stack networking #1535

Open
Qwiko opened this issue Sep 5, 2024 · 1 comment · May be fixed by #1536
Open

NodePort mode does not fully support dual-stack networking #1535

Qwiko opened this issue Sep 5, 2024 · 1 comment · May be fixed by #1536
Labels
bug Something isn't working

Comments

@Qwiko
Copy link

Qwiko commented Sep 5, 2024

Describe the bug

Currently there is no full support for full dual-stack in AKO. For ingress-services running in ClusterIP mode it is fully working. Running AKO in NodePort-mode does not currently support dual-stack for backend servers. It does create a vip with both IPv4 and IPv6 where the IPv6 address is unusable without any IPv6 backend servers.

I believe this is due to the logic found in this file: internal/nodes/avi_model_l4_translator.go and functions PopulateServersForNPL, PopulateServersForNodePort and PopulateServers.

In the following code-snippet for PopulateServersForNodePort it will always populate the poolMeta with either an IPv4
or IPv6 address due to using if/else if. It will never return both an IPv4 and IPv6 address that is intended when running in dual-stack mode.

I don't see any reason why it could not be 2 if-statements where both addresses gets appended to the poolMeta. I will try to make a fix myself and try it in a test-cluster if there are any issues with this approach.

avi_model_l4_translator.go #L457

if v4enabled && v4Family && nodeIP != "" {
	v4ServerCount++
	atype = "V4"
	serverIP = avimodels.IPAddr{Type: &atype, Addr: &nodeIP}
} else if v6enabled && v6Family && nodeIP6 != "" {
	v6ServerCount++
	atype = "V6"
	serverIP = avimodels.IPAddr{Type: &atype, Addr: &nodeIP6}
} else {
	continue
}
server := AviPoolMetaServer{Ip: serverIP}
poolMeta = append(poolMeta, server)

Proposed fix:

if v4enabled && v4Family && nodeIP != "" {
	v4ServerCount++
	atype = "V4"
	serverIPV4 = avimodels.IPAddr{Type: &atypeV4, Addr: &nodeIP}
	serverV4 := AviPoolMetaServer{Ip: serverIP}
	poolMeta = append(poolMeta, serverV4)
}
if v6enabled && v6Family && nodeIP6 != "" {
	v6ServerCount++
	atypeV6 = "V6"
	serverIPV6 = avimodels.IPAddr{Type: &atypeV6, Addr: &nodeIP6}
	serverV6 := AviPoolMetaServer{Ip: serverIPV6}
	poolMeta = append(poolMeta, serverV6)
}

Symptoms is that the error: "expected IPv6 servers but found none" will always display even in the cases where there is a valid IPv4 and IPv6 address present on the node.

Reproduction steps

  1. Run AKO(1.12 or later) in a dual-stack cluster with NodePort mode and IP_FAMILY = V4_V6
  2. Deploy any dual-stack LoadBalancer service.
  3. IPv4 and IPv6 addresses get allocated to the VIP but only IPv4 addresses get added to the pool in AVI.

Expected behavior

The expected behavior is that both vip and backend servers are populated with IPv4 and IPv6 addresses from InternalIP of the node.

Additional context

No response

@Qwiko Qwiko added the bug Something isn't working label Sep 5, 2024
@Qwiko
Copy link
Author

Qwiko commented Sep 6, 2024

I have done some small tests and do get dual-stack entries for backend-servers with the following fix.

Code as it is now:

nodeIP, nodeIP6 := lib.GetIPFromNode(node)
var atype string
var serverIP avimodels.IPAddr
if v4enabled && v4Family && nodeIP != "" {
	v4ServerCount++
	atype = "V4"
	serverIP = avimodels.IPAddr{Type: &atype, Addr: &nodeIP}
} else if v6enabled && v6Family && nodeIP6 != "" {
	v6ServerCount++
	atype = "V6"
	serverIP = avimodels.IPAddr{Type: &atype, Addr: &nodeIP6}
} else {
	continue
}
server := AviPoolMetaServer{Ip: serverIP}
poolMeta = append(poolMeta, server)	

Suggestion on how to fix

nodeIP, nodeIP6 := lib.GetIPFromNode(node)

if v4enabled && v4Family && nodeIP != "" {
	v4ServerCount++
	atype := "V4"
	serverIP := avimodels.IPAddr{Type: &atype, Addr: &nodeIP}
	server := AviPoolMetaServer{Ip: serverIP}
	poolMeta = append(poolMeta, server)
}
if v6enabled && v6Family && nodeIP6 != "" {
	v6ServerCount++
	atype := "V6"
	serverIP := avimodels.IPAddr{Type: &atype, Addr: &nodeIP6}
	server := AviPoolMetaServer{Ip: serverIP}
	poolMeta = append(poolMeta, server)
}

@Qwiko Qwiko linked a pull request Sep 11, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant