Skip to content

Commit

Permalink
replace ipv6 prefix with ipv6 address (#7391)
Browse files Browse the repository at this point in the history
  • Loading branch information
haouc authored Nov 16, 2024
1 parent d0c8ed0 commit 317f551
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 65 deletions.
25 changes: 11 additions & 14 deletions pkg/providers/launchtemplate/launchtemplate.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,25 +287,22 @@ func (p *DefaultProvider) generateNetworkInterfaces(options *amifamily.LaunchTem
// with a single EFA network interface, and we should support those use cases. Launch failures with multiple enis should be considered user misconfiguration.
AssociatePublicIpAddress: options.AssociatePublicIPAddress,
PrimaryIpv6: lo.Ternary(p.ClusterIPFamily == corev1.IPv6Protocol, lo.ToPtr(true), nil),
Ipv6PrefixCount: lo.Ternary(p.ClusterIPFamily == corev1.IPv6Protocol, lo.ToPtr(int32(1)), nil),
Ipv6AddressCount: lo.Ternary(p.ClusterIPFamily == corev1.IPv6Protocol, lo.ToPtr(int32(1)), nil),
}
})
}

if options.AssociatePublicIPAddress != nil {
return []ec2types.LaunchTemplateInstanceNetworkInterfaceSpecificationRequest{
{
AssociatePublicIpAddress: options.AssociatePublicIPAddress,
DeviceIndex: aws.Int32(0),
Groups: lo.Map(options.SecurityGroups, func(s v1.SecurityGroup, _ int) string {
return s.ID
}),
PrimaryIpv6: lo.Ternary(p.ClusterIPFamily == corev1.IPv6Protocol, lo.ToPtr(true), nil),
Ipv6PrefixCount: lo.Ternary(p.ClusterIPFamily == corev1.IPv6Protocol, lo.ToPtr(int32(1)), nil),
},
}
return []ec2types.LaunchTemplateInstanceNetworkInterfaceSpecificationRequest{
{
AssociatePublicIpAddress: options.AssociatePublicIPAddress,
DeviceIndex: aws.Int32(0),
Groups: lo.Map(options.SecurityGroups, func(s v1.SecurityGroup, _ int) string {
return s.ID
}),
PrimaryIpv6: lo.Ternary(p.ClusterIPFamily == corev1.IPv6Protocol, lo.ToPtr(true), nil),
Ipv6AddressCount: lo.Ternary(p.ClusterIPFamily == corev1.IPv6Protocol, lo.ToPtr(int32(1)), nil),
},
}
return nil
}

func (p *DefaultProvider) blockDeviceMappings(blockDeviceMappings []*v1.BlockDeviceMapping) []ec2types.LaunchTemplateBlockDeviceMappingRequest {
Expand Down
23 changes: 12 additions & 11 deletions pkg/providers/launchtemplate/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2244,9 +2244,9 @@ essential = true
Entry("DNS has ipv6 address", corev1.IPv6Protocol),
)
})
Context("should provision a v6 prefix and set v6 primary IP as true when running in an ipv6 cluster", func() {
Context("should provision a v6 address and set v6 primary IP as true when running in an ipv6 cluster", func() {
DescribeTable(
"should set Primary IPv6 as true and provision a prefix",
"should set Primary IPv6 as true and provision a IPv6 address",
func(isPublicAddressSet, isPublic, isEFA bool) {
awsEnv.LaunchTemplateProvider.KubeDNSIP = net.ParseIP("fd4b:121b:812b::a")
awsEnv.LaunchTemplateProvider.ClusterIPFamily = corev1.IPv6Protocol
Expand All @@ -2263,17 +2263,18 @@ essential = true
ExpectProvisioned(ctx, env.Client, cluster, cloudProvider, prov, pod)
ExpectScheduled(ctx, env.Client, pod)
input := awsEnv.EC2API.CalledWithCreateLaunchTemplateInput.Pop()
if isPublicAddressSet {
Expect(lo.FromPtr(input.LaunchTemplateData.NetworkInterfaces[0].AssociatePublicIpAddress)).To(Equal(isPublic))
Expect(lo.FromPtr(input.LaunchTemplateData.NetworkInterfaces[0].Ipv6PrefixCount)).To(Equal(int32(1)))
Expect(lo.FromPtr(input.LaunchTemplateData.NetworkInterfaces[0].PrimaryIpv6)).To(BeTrue())
} else if !isEFA {
Expect(input.LaunchTemplateData.NetworkInterfaces).To(HaveLen(0))
} else {

Expect(len(input.LaunchTemplateData.NetworkInterfaces)).To(BeNumerically(">=", 1))
if !isPublicAddressSet && !isEFA {
Expect(input.LaunchTemplateData.NetworkInterfaces[0].AssociatePublicIpAddress).To(BeNil())
}
if isEFA {
Expect(lo.FromPtr(input.LaunchTemplateData.NetworkInterfaces[0].InterfaceType)).To(Equal(string(ec2types.NetworkInterfaceTypeEfa)))
Expect(lo.FromPtr(input.LaunchTemplateData.NetworkInterfaces[0].Ipv6PrefixCount)).To(Equal(int32(1)))
Expect(lo.FromPtr(input.LaunchTemplateData.NetworkInterfaces[0].PrimaryIpv6)).To(BeTrue())
Expect(lo.FromPtr(input.LaunchTemplateData.NetworkInterfaces[0].AssociatePublicIpAddress)).To(Equal(isPublic))
}
Expect(lo.FromPtr(input.LaunchTemplateData.NetworkInterfaces[0].Ipv6AddressCount)).To(Equal(int32(1)))
Expect(lo.FromPtr(input.LaunchTemplateData.NetworkInterfaces[0].PrimaryIpv6)).To(BeTrue())

},
Entry("AssociatePublicIPAddress is not set and EFA is false", false, true, false),
Entry("AssociatePublicIPAddress is not set and EFA is true", false, false, true),
Expand Down
41 changes: 1 addition & 40 deletions test/suites/ipv6/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,7 @@ import (

"github.com/samber/lo"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/util/retry"

"sigs.k8s.io/controller-runtime/pkg/client"
karpv1 "sigs.k8s.io/karpenter/pkg/apis/v1"
coretest "sigs.k8s.io/karpenter/pkg/test"

Expand Down Expand Up @@ -102,53 +99,17 @@ var _ = Describe("IPv6", func() {
It("should provision a static IPv6 prefix with node launch and set IPv6 as primary in the primary network interface", func() {
clusterDNSAddr := env.ExpectIPv6ClusterDNS()
nodeClass.Spec.Kubelet = &v1.KubeletConfiguration{ClusterDNS: []string{clusterDNSAddr}}
Expect(disableVPCCNIProvisioning(true)).To(Succeed())
DeferCleanup(func() {
Expect(disableVPCCNIProvisioning(false)).To(Succeed())
})
pod := coretest.Pod()
env.ExpectCreated(pod, nodeClass, nodePool)
env.EventuallyExpectHealthy(pod)
env.ExpectCreatedNodeCount("==", 1)
node := env.GetNode(pod.Spec.NodeName)
instance := env.GetInstanceByID(env.ExpectParsedProviderID(node.Spec.ProviderID))
Expect(instance.NetworkInterfaces).To(HaveLen(1))
Expect(instance.NetworkInterfaces[0].Ipv6Prefixes).To(HaveLen(1))
Expect(instance.NetworkInterfaces[0].Ipv6Addresses).To(HaveLen(1))
_, hasIPv6Primary := lo.Find(instance.NetworkInterfaces[0].Ipv6Addresses, func(ip types.InstanceIpv6Address) bool {
return lo.FromPtr(ip.IsPrimaryIpv6)
})
Expect(hasIPv6Primary).To(BeTrue())
})
})

// disable VPC CNI provisioning on network interfaces and IPs
func disableVPCCNIProvisioning(disable bool) error {
dsClient := env.KubeClient.AppsV1().DaemonSets("kube-system")
retryErr := retry.OnError(
retry.DefaultRetry,
func(err error) bool {
return true
},
func() error {
awsNode, getErr := dsClient.Get(env.Context, "aws-node", metav1.GetOptions{})
if getErr != nil {
return getErr
}

for i := range awsNode.Spec.Template.Spec.Containers {
if awsNode.Spec.Template.Spec.Containers[i].Name == "aws-node" {
for j := range awsNode.Spec.Template.Spec.Containers[i].Env {
if awsNode.Spec.Template.Spec.Containers[i].Env[j].Name == "DISABLE_NETWORK_RESOURCE_PROVISIONING" {
awsNode.Spec.Template.Spec.Containers[i].Env[j].Value = lo.Ternary(disable, "true", "false")
}
}
}
}

_, updateErr := dsClient.Update(env.Context, awsNode, metav1.UpdateOptions{})
return updateErr
},
)
// ignore AWS VPC CNI is not installed
return client.IgnoreNotFound(retryErr)
}

0 comments on commit 317f551

Please sign in to comment.