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

Add support for returning IPv6 node addresses #230

Merged
merged 1 commit into from Jul 19, 2021

Conversation

hakman
Copy link
Member

@hakman hakman commented Jun 5, 2021

What type of PR is this?
/kind feature
/priority important-longterm

What this PR does / why we need it:
IPv6 support has been around for some time now both in AWS and Kubernetes. Dual-Stack is also one of the major themes in Kubernetes 1.21.
I am trying to add IPv6 support for kOps and bumping into various issues because the IPv6 addresses are not returned by the cloud provider implementation.
xRef: kubernetes/kops#8432

I am not sure if there was any reason for not implementing this until now, but this PR should be a good conversation starter.

Which issue(s) this PR fixes:
n/a

Special notes for your reviewer:
I added the IPv6 addresses to the internal address list as it seems to be the convention in the related feature docs.
I also considered that adding the IPv6 addresses after all internal IPv4 would best preserve current behavior.

Does this PR introduce a user-facing change?:

Added support for returning IPv6 node addresses

/cc @nckturner @wongma7 @justinsb @aojea

@k8s-ci-robot k8s-ci-robot added kind/feature Categorizes issue or PR as related to a new feature. priority/important-longterm Important over the long term, but may not be staffed and/or may need multiple releases to complete. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Jun 5, 2021
pkg/providers/v1/aws.go Outdated Show resolved Hide resolved
pkg/providers/v1/aws.go Outdated Show resolved Hide resolved
pkg/providers/v1/aws.go Outdated Show resolved Hide resolved
continue
}

for _, internalIPv6 := range strings.Split(internalIPv6s, "\n") {
Copy link
Member

Choose a reason for hiding this comment

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

I think we should add only the 'first' address (from each ENI).

In IPv4, AWS has a strong distinction between 'primary' IPv4 and all the 'secondary' addresses (per ENI). In IPv6, the AWS API does not make a distinction, and it's just a single list of all IPv6 addresses (per ENI).

So if/when we want to add multiple IPv6 addresses to an ENI, eg so we have VPC addresses for pods, then they will all turn up in this ipv6s list. I think we need to be less greedy here :) and only use the first address, so the 'rest' can be left for other purposes. From my testing ordering is preserved, so first means naive ipv6s[0].

Copy link
Member Author

Choose a reason for hiding this comment

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

Sounds good to me. Done, also added a test for this case.

if internalIPv6 == "" {
continue
}
addresses = append(addresses, v1.NodeAddress{Type: v1.NodeInternalIP, Address: internalIPv6})
Copy link
Member

Choose a reason for hiding this comment

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

Should we should use it only if ip.IsGlobalUnicast()

Fwiw, I think we should use whatever address(es?) are reported by VPC (in metadata). If VPC is giving us ULA addresses (for example), then there's a very good reason, and the code here should trust the VPC address is relevant and use it.

I have no reason to believe this will ever happen to be clear! but if VPC is reporting something 'weird', then I think there's a very good chance that VPC is correct for that situation and our if IsGlobalUnicast() logic is going to be incorrect.

Copy link
Member

Choose a reason for hiding this comment

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

ULA are IsGlobalUnicast() , this just removes link-local, multicast and loopback
But agreed, this validation shouldn't be here and VPC is the source of truth

@hakman
Copy link
Member Author

hakman commented Jun 12, 2021

Thanks for the review @anguslees. I think I addressed all the comments.

Copy link
Member

@anguslees anguslees left a comment

Choose a reason for hiding this comment

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

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Jun 22, 2021
@hakman
Copy link
Member Author

hakman commented Jun 28, 2021

Good news! I built a custom image to test this change and managed to get Conformance tests passing using an IPv6-only cluster created with kOps:
https://testgrid.k8s.io/kops-ipv6#kops-grid-scenario-ipv6-conformance

@hakman
Copy link
Member Author

hakman commented Jun 29, 2021

/assign @nckturner

@nckturner
Copy link
Contributor

Sorry for the delay, I was on vacation. This looks good to me.
/approve

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: anguslees, hakman, nckturner

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

The pull request process is described here

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 Jul 9, 2021
@hakman
Copy link
Member Author

hakman commented Jul 9, 2021

/hold

@k8s-ci-robot k8s-ci-robot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jul 9, 2021
@hakman
Copy link
Member Author

hakman commented Jul 9, 2021

@nckturner One final Q from me, if you don't mind. While playing with IPv6 clusters I noticed that k8s is picky about the order of the addresses. Would it make sense to move the IPv6 addresses first as they are optional and there is no reason to enable them unless someone wants to use them?

@nckturner
Copy link
Contributor

I do remember that address order being important, would you mind adding some more detail though? Also I see the gce provider adding ipv6 node addresses here and it looks like they are not first.

@hakman
Copy link
Member Author

hakman commented Jul 9, 2021

As the fix is now, conformance tests pass on IPv6 only clusters, so this is not a huge issue.
Kubernetes reports node addresses as an ordered list and kubectl shows node IP as the first address (mostly aesthetic), though pods that run on host network report that address as their main address too.
Not sure if most tools support nodes and pods with multiple IPs so, ideally, there should be some preference.
With kube-controller-manager, kubelet allowed --node-ip=:: to specify family preference, but with external CCM this is no longer possible:
https://github.com/kubernetes/kubernetes/blob/master/pkg/kubelet/nodestatus/setters.go#L148

@nckturner
Copy link
Contributor

Spoke to @justinsb and he thinks it will be less likely to break users if we keep the ipv6 addresses at the end for now, with the potential of adding a configuration to return ipv6 first/only return ipv6. I don't have a good idea of what will happen when we have dual stack configured for nodes, but I'm wondering about this PR:

On nodes with dual-stack node.status.addresses (regardless of how they got them), hostNetwork pods will now have dual-stack pod.status.podIPs, allowing the pod to be the target of either a single-stack IPv4 or single-stack IPv6 Service (or, once dual stack services #91824 merges, a dual-stack Service).

It seems that PR adds pod.status.podIPs, which can be set by the cloud provider node addresses in the case of hostNetwork pods. Am I understanding that correctly?

@aojea
Copy link
Member

aojea commented Jul 12, 2021

It seems that PR adds pod.status.podIPs, which can be set by the cloud provider node addresses in the case of hostNetwork pods. Am I understanding that correctly?

hostNetwork pods use the IPs of the Host, until recently there was only one Node.Status.Address, hence hostNetwork pods always have only one PodIP.
Since that PR, hostNetwork pods in dual-stack clusters, will use one IP of each family from node.Status.Addresses for its PodIPs.
Important, node.status.Addresses order matters and defines the "primary" ip family, i.e., a dual-stack cluster with IPv4,IPv6 has IPv4 as primary ip family.

@hakman
Copy link
Member Author

hakman commented Jul 19, 2021

Sorry for my late reply, last week was pretty hectic for me. I think this is a good start and will get more eyes on IPv6 with AWS. We can adjust how it works in future PRs. Thanks @nckturner & @aojea.
/hold cancel

@k8s-ci-robot k8s-ci-robot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jul 19, 2021
@k8s-ci-robot k8s-ci-robot merged commit 12f2ca9 into kubernetes:master Jul 19, 2021
@hakman hakman deleted the ipv6_node_addresses branch July 19, 2021 09:31
@anguslees
Copy link
Member

anguslees commented Aug 19, 2021

I do remember that address order being important, would you mind adding some more detail though?

Just for the archives, order is extremely important here. Basically this whole Addresses array is not (and never has been) used for anything at all :P Kubernetes only uses the first InternalIP address in this array (modifyable via apiserver --kubelet-preferred-address-types, but it's always only the first of each address type) - so adding the v6 addresses after the v4 address means they're unused in all but a v6-only scenario.

@aojea
Copy link
Member

aojea commented Aug 19, 2021

with dual stack , addresses has a meaning, they define the order of the cluster ipv4 - ipv6 or ipv4 - ipv6

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. kind/feature Categorizes issue or PR as related to a new feature. lgtm "Looks good to me", indicates that a PR is ready to be merged. priority/important-longterm Important over the long term, but may not be staffed and/or may need multiple releases to complete. release-note Denotes a PR that will be considered when it comes time to generate release notes. size/M Denotes a PR that changes 30-99 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants