Skip to content

Commit 8efee2d

Browse files
committed
resolve VPC ENI for pods with IPv6 addresses
1 parent 5fce176 commit 8efee2d

File tree

2 files changed

+449
-9
lines changed

2 files changed

+449
-9
lines changed

pkg/networking/pod_eni_info_resolver.go

Lines changed: 68 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ func (r *defaultPodENIInfoResolver) resolveViaCascadedLookup(ctx context.Context
144144
r.resolveViaPodENIAnnotation,
145145
r.resolveViaNodeENIs,
146146
r.resolveViaVPCENIs,
147+
r.resolveViaVPCENIsForIPv6,
147148
// TODO, add support for kubenet CNI plugin(kops) by resolve via routeTable.
148149
}
149150

@@ -259,25 +260,26 @@ func (r *defaultPodENIInfoResolver) resolveViaVPCENIs(ctx context.Context, pods
259260
if len(podKeysByIP) == 0 {
260261
return nil, nil
261262
}
262-
263-
podIPs := sets.StringKeySet(podKeysByIP).List()
263+
var podIPs []string
264+
for _, podIP := range sets.StringKeySet(podKeysByIP).List() {
265+
if !strings.Contains(podIP, ":") {
266+
podIPs = append(podIPs, podIP)
267+
}
268+
}
269+
if len(podIPs) == 0 {
270+
return nil, nil
271+
}
264272
podIPChunks := algorithm.ChunkStrings(podIPs, r.describeNetworkInterfacesIPChunkSize)
265273
eniByID := make(map[string]*ec2sdk.NetworkInterface)
266274
for _, podIPChunk := range podIPChunks {
267-
ipAddressTypeFilterKey := "addresses.private-ip-address"
268-
for _, podIP := range podIPChunk {
269-
if strings.Contains(podIP, ":") {
270-
ipAddressTypeFilterKey = "ipv6-addresses.ipv6-address"
271-
}
272-
}
273275
req := &ec2sdk.DescribeNetworkInterfacesInput{
274276
Filters: []*ec2sdk.Filter{
275277
{
276278
Name: awssdk.String("vpc-id"),
277279
Values: awssdk.StringSlice([]string{r.vpcID}),
278280
},
279281
{
280-
Name: awssdk.String(ipAddressTypeFilterKey),
282+
Name: awssdk.String("addresses.private-ip-address"),
281283
Values: awssdk.StringSlice(podIPChunk),
282284
},
283285
},
@@ -305,6 +307,63 @@ func (r *defaultPodENIInfoResolver) resolveViaVPCENIs(ctx context.Context, pods
305307
return eniInfoByPodKey, nil
306308
}
307309

310+
// resolveViaVPCENIsForIPv6 attempts to resolve pod ENI by matching IPv6 podIP against ENIs in vpc.
311+
// With EKS fargate pods, podIP is supported by an ENI in vpc.
312+
func (r *defaultPodENIInfoResolver) resolveViaVPCENIsForIPv6(ctx context.Context, pods []k8s.PodInfo) (map[types.NamespacedName]ENIInfo, error) {
313+
podKeysByIP := make(map[string][]types.NamespacedName, len(pods))
314+
for _, pod := range pods {
315+
podKeysByIP[pod.PodIP] = append(podKeysByIP[pod.PodIP], pod.Key)
316+
}
317+
if len(podKeysByIP) == 0 {
318+
return nil, nil
319+
}
320+
var podIPs []string
321+
for _, podIP := range sets.StringKeySet(podKeysByIP).List() {
322+
if strings.Contains(podIP, ":") {
323+
podIPs = append(podIPs, podIP)
324+
}
325+
}
326+
if len(podIPs) == 0 {
327+
return nil, nil
328+
}
329+
podIPChunks := algorithm.ChunkStrings(podIPs, r.describeNetworkInterfacesIPChunkSize)
330+
eniByID := make(map[string]*ec2sdk.NetworkInterface)
331+
for _, podIPChunk := range podIPChunks {
332+
req := &ec2sdk.DescribeNetworkInterfacesInput{
333+
Filters: []*ec2sdk.Filter{
334+
{
335+
Name: awssdk.String("vpc-id"),
336+
Values: awssdk.StringSlice([]string{r.vpcID}),
337+
},
338+
{
339+
Name: awssdk.String("ipv6-addresses.ipv6-address"),
340+
Values: awssdk.StringSlice(podIPChunk),
341+
},
342+
},
343+
}
344+
enis, err := r.ec2Client.DescribeNetworkInterfacesAsList(ctx, req)
345+
if err != nil {
346+
return nil, err
347+
}
348+
for _, eni := range enis {
349+
eniID := awssdk.StringValue(eni.NetworkInterfaceId)
350+
eniByID[eniID] = eni
351+
}
352+
}
353+
354+
eniInfoByPodKey := make(map[types.NamespacedName]ENIInfo)
355+
for _, eni := range eniByID {
356+
eniInfo := buildENIInfoViaENI(eni)
357+
for _, addr := range eni.Ipv6Addresses {
358+
eniIPv6 := awssdk.StringValue(addr.Ipv6Address)
359+
for _, podKey := range podKeysByIP[eniIPv6] {
360+
eniInfoByPodKey[podKey] = eniInfo
361+
}
362+
}
363+
}
364+
return eniInfoByPodKey, nil
365+
}
366+
308367
// isPodSupportedByNodeENI checks whether pod is supported by specific nodeENI.
309368
func (r *defaultPodENIInfoResolver) isPodSupportedByNodeENI(pod k8s.PodInfo, nodeENI *ec2sdk.InstanceNetworkInterface) bool {
310369
for _, ipv4Address := range nodeENI.PrivateIpAddresses {

0 commit comments

Comments
 (0)