Skip to content

✨ Support IPv6/dual-stack routable pods with NSX-VPC#1763

Open
silvery1622 wants to merge 1 commit into
kubernetes:masterfrom
silvery1622:ipv6-dualstack-routablepods
Open

✨ Support IPv6/dual-stack routable pods with NSX-VPC#1763
silvery1622 wants to merge 1 commit into
kubernetes:masterfrom
silvery1622:ipv6-dualstack-routablepods

Conversation

@silvery1622

Copy link
Copy Markdown
Collaborator

What this PR does / why we need it:

  • New ipfamily package centralises the four --cluster-ip-family values and their boolean helpers (IPv4Enabled, IPv6Enabled, DualStack, PrimaryIPv4).
  • NSXVPCIPManager creates/deletes one IPAddressAllocation CR per enabled IP family per node (IPv4 keeps the bare node name; IPv6 appends -ipv6). Both CRs carry nodeName and ipfamily labels so downstream consumers never need to parse CR names.
  • ipaddressallocation_controller waits for both partner allocations to be ready, then issues a single atomic PodCIDRs patch ordered by primary family. A resync idempotency guard skips redundant PATCHes when the node already has the correct CIDRs.
  • StaticRoute CRs gain nodeName/ipfamily labels; ListRoutes prefers labels over name-suffix parsing (legacy fallback retained).
  • StartControllers now takes an Options struct to keep the signature stable as new flags are added.

Which issue this PR fixes (optional, in fixes #<issue number>(, fixes #<issue_number>, ...) format, will close that issue when PR gets merged): fixes #

Special notes for your reviewer:

Release note:

Add IPv6 and dual-stack routable pod support for NSX-VPC mode. Set --cluster-ip-family=ipv6, ipv4ipv6, or ipv6ipv4 together with --enable-vpc-mode=true to enable per-family IPAddressAllocation and StaticRoute CRs.

@k8s-ci-robot k8s-ci-robot requested review from chenlin07 and wyike May 18, 2026 06:37
@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label May 18, 2026
@k8s-ci-robot

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: silvery1622

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label May 18, 2026
@silvery1622

Copy link
Copy Markdown
Collaborator Author

/hold

@k8s-ci-robot k8s-ci-robot added size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. labels May 18, 2026
@silvery1622 silvery1622 force-pushed the ipv6-dualstack-routablepods branch from 67393ba to 45e7c24 Compare May 18, 2026 06:47
}

if !c.ipFamily.DualStack() {
if len(node.Spec.PodCIDRs) == 1 && node.Spec.PodCIDRs[0] == thisCIDR {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if len(node.Spec.PodCIDRs) > 1 or node.Spec.PodCIDRs[0] != thisCIDR?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the node has multiple CIDRs or an incorrect CIDR in a single-stack cluster, that if condition evaluates to false. The code then falls through to utils.PatchNodeCIDRWithRetry, which uses a strategic merge patch to completely overwrite both PodCIDR and PodCIDRs with exactly []string{thisCIDR}.

@silvery1622 silvery1622 force-pushed the ipv6-dualstack-routablepods branch 3 times, most recently from e9922fe to 1c90c66 Compare June 3, 2026 05:30
…NSX-VPC

- hack/nsx-operator-apis-fork: local copy of nsx-operator API types with
  updated IPAddressAllocation (multi-family CIDR fields)
- routablepod/core.go: thread ipv4Enabled/ipv6Enabled/primaryIPFamilyIsIPv4
  through to IPAddressAllocation and node controllers
- routablepod/ipaddressallocation: allocate separate IPv4/IPv6 CRs in dual-stack
- nsxipmanager/nsx_vpc.go: reconcile IPv4/IPv6 IPAddressAllocation objects
- routemanager: propagate per-family CIDRs to StaticRoute CRs
- cloud.go: derive IP-family flags from --cluster-ip-family and pass to StartControllers
@silvery1622 silvery1622 force-pushed the ipv6-dualstack-routablepods branch from 1c90c66 to 54c942f Compare June 3, 2026 05:33
// We deliberately do NOT parse the CR name to decide the family: node names
// that themselves end in "-ipv6" would otherwise be misclassified.
func isIPv4Allocation(alloc *vpcapisv1.IPAddressAllocation) bool {
return alloc.Spec.IPAddressType != vpcapisv1.IPAllocationIPAddressTypeIPv6

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to method name, alloc.Spec.IPAddressType == vpcapisv1.IPAllocationIPAddressTypeIPv4 looks better

} else {
// Dual-stack: list all allocations for this node.
// Dual-stack clusters are new and guaranteed to have the nodeName label on their CRs.
selector := labels.SelectorFromSet(labels.Set{helper.LabelKeyNodeName: nodeName})

@DanielXiao DanielXiao Jun 10, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also add label for cluster name or vsphere cluster name? There could be same nodeName in different clusters, for example, below 2 clusters all render node name coffee-worker-beijing
cluster coffee nodepool worker-beijing
cluster coffee-worker nodepool beijing

Namespace: m.svNamespace,
Labels: map[string]string{
helper.LabelKeyNodeName: nodeName,
helper.LabelKeyIPFamily: familyLabel,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The spec.IPAddressType contains ipfamily so I don't think this label is used anywhere. We need to add a label for VSphereCluster

ctx := context.TODO()

for _, ipv4 := range families {
crName := crNameForFamily(node.Name, ipv4)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should use label to get IPAddressAnnotation rather than name.

// deleteIPAddressAllocation deletes the IPAddressAllocation CR for the given node and
// IP family. NotFound is treated as success (idempotent delete).
func (m *NSXVPCIPManager) deleteIPAddressAllocation(ctx context.Context, nodeName string, ipv4 bool) error {
crName := crNameForFamily(nodeName, ipv4)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

// destination is actually IPv6, so an IPv4 route on a node whose
// name happens to end in "-ipv6" is not silently truncated.
nodeName := staticroute.Labels[helper.LabelKeyNodeName]
if nodeName == "" {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Raise an error till label is added by node controller.

}
if podCIDR == "" {
return fmt.Errorf("IPAddressAllocation %v does not get CIDR allocated", ipAddressAllocation.Name)
return helper.StripFamilySuffix(alloc.Name)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not fallback, Raise an error till label is added by node controller.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants