Skip to content

Commit 22ef9af

Browse files
committed
📝 docs(README): add instructions for using multiple subnets
- provide examples for specifying multiple subnet IDs and names - update documentation to guide users on using multiple subnets with NodeENI ✨ feat(controller): support multiple subnets for ENI creation - introduce new fields `subnetIDs` and `subnetNames` in CRD - add logic to select a subnet from provided IDs or names - enhance flexibility in ENI creation by allowing multiple subnet options ♻️ refactor(controller): extract subnet ID determination logic - create `determineSubnetID` function for clearer subnet selection process - improve code readability by separating subnet logic from ENI creation 📝 docs(crds): update CRD documentation for subnet enhancements - document new `subnetIDs` and `subnetNames` fields in CRD YAML - clarify usage scenarios for multiple subnets in ENI configuration ✨ feat(samples): add sample configurations for multiple subnets - include new YAML samples demonstrating usage of multiple subnet IDs and names - provide practical examples for users to reference when configuring ENIs
1 parent 073dc4d commit 22ef9af

8 files changed

Lines changed: 207 additions & 13 deletions

File tree

README.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,50 @@ If you prefer to deploy manually:
310310
description: "Multus ENI for secondary network interfaces"
311311
```
312312
313+
### Using Multiple Subnets
314+
315+
You can specify multiple subnets in your NodeENI resource. The controller will select one of the subnets to create the ENI:
316+
317+
```yaml
318+
apiVersion: networking.k8s.aws/v1alpha1
319+
kind: NodeENI
320+
metadata:
321+
name: multi-subnet-eni
322+
spec:
323+
nodeSelector:
324+
ng: multi-eni
325+
# Specify multiple subnet IDs - one will be selected
326+
subnetIDs:
327+
- subnet-0f59b4f14737be9ad # Replace with your subnet ID
328+
- subnet-abcdef1234567890 # Replace with your subnet ID
329+
securityGroupIDs:
330+
- sg-05da196f3314d4af8 # Replace with your security group ID
331+
deviceIndex: 1
332+
deleteOnTermination: true
333+
description: "ENI with multiple subnet options"
334+
```
335+
336+
You can also use subnet names instead of IDs:
337+
338+
```yaml
339+
apiVersion: networking.k8s.aws/v1alpha1
340+
kind: NodeENI
341+
metadata:
342+
name: multi-subnet-name-eni
343+
spec:
344+
nodeSelector:
345+
ng: multi-eni
346+
# Specify multiple subnet names - one will be selected
347+
subnetNames:
348+
- eks-private-subnet-1
349+
- eks-private-subnet-2
350+
securityGroupIDs:
351+
- sg-05da196f3314d4af8 # Replace with your security group ID
352+
deviceIndex: 2
353+
deleteOnTermination: true
354+
description: "ENI with multiple subnet name options"
355+
```
356+
313357
### Automatically Bringing Up Secondary Interfaces
314358
315359
When AWS attaches a secondary ENI to an EC2 instance, the interface is visible to the operating system but typically in a DOWN state. To automatically bring these interfaces up:

charts/aws-multi-eni-controller/README.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,3 +165,47 @@ spec:
165165
deleteOnTermination: true
166166
description: "Example ENI"
167167
```
168+
169+
## Using Multiple Subnets
170+
171+
You can specify multiple subnets to use a single security group across different subnets:
172+
173+
```yaml
174+
apiVersion: networking.k8s.aws/v1alpha1
175+
kind: NodeENI
176+
metadata:
177+
name: multi-subnet-eni
178+
spec:
179+
nodeSelector:
180+
ng: multi-eni
181+
# Specify multiple subnet IDs - one will be selected
182+
subnetIDs:
183+
- subnet-xxxxxxxx
184+
- subnet-yyyyyyyy
185+
securityGroupIDs:
186+
- sg-xxxxxxxx
187+
deviceIndex: 2
188+
deleteOnTermination: true
189+
description: "ENI with multiple subnet options"
190+
```
191+
192+
You can also use multiple subnet names:
193+
194+
```yaml
195+
apiVersion: networking.k8s.aws/v1alpha1
196+
kind: NodeENI
197+
metadata:
198+
name: multi-subnet-name-eni
199+
spec:
200+
nodeSelector:
201+
ng: multi-eni
202+
# Specify multiple subnet names - one will be selected
203+
subnetNames:
204+
- subnet-name-1
205+
- subnet-name-2
206+
securityGroupIDs:
207+
- sg-xxxxxxxx
208+
deviceIndex: 2
209+
deleteOnTermination: true
210+
description: "ENI with multiple subnet name options"
211+
```

charts/aws-multi-eni-controller/crds/networking.k8s.aws_nodeenis_crd.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,19 @@ spec:
6262
subnetID:
6363
description: AWS Subnet ID where the ENI should be created
6464
type: string
65+
subnetIDs:
66+
description: List of AWS Subnet IDs where the ENI can be created (one will be selected)
67+
items:
68+
type: string
69+
type: array
6570
subnetName:
6671
description: AWS Subnet Name where the ENI should be created (used if subnetID is not provided)
6772
type: string
73+
subnetNames:
74+
description: List of AWS Subnet Names where the ENI can be created (one will be selected)
75+
items:
76+
type: string
77+
type: array
6878
required:
6979
- nodeSelector
7080
type: object

charts/aws-multi-eni-controller/templates/NOTES.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ spec:
1919
ng: multi-eni # Replace with your node selector
2020
subnetID: subnet-xxxxxxxx # Replace with your subnet ID
2121
# OR use subnetName: your-subnet-name
22+
# OR use multiple subnets:
23+
# subnetIDs:
24+
# - subnet-xxxxxxxx
25+
# - subnet-yyyyyyyy
2226
securityGroupIDs:
2327
- sg-xxxxxxxx # Replace with your security group ID
2428
# OR use securityGroupNames:

deploy/crds/networking.k8s.aws_nodeenis_crd.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,19 @@ spec:
6262
subnetID:
6363
description: AWS Subnet ID where the ENI should be created
6464
type: string
65+
subnetIDs:
66+
description: List of AWS Subnet IDs where the ENI can be created (one will be selected)
67+
items:
68+
type: string
69+
type: array
6570
subnetName:
6671
description: AWS Subnet Name where the ENI should be created (used if subnetID is not provided)
6772
type: string
73+
subnetNames:
74+
description: List of AWS Subnet Names where the ENI can be created (one will be selected)
75+
items:
76+
type: string
77+
type: array
6878
required:
6979
- nodeSelector
7080
type: object
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
apiVersion: networking.k8s.aws/v1alpha1
2+
kind: NodeENI
3+
metadata:
4+
name: multi-subnet-eni
5+
spec:
6+
nodeSelector:
7+
ng: multi-eni
8+
# Specify multiple subnet IDs - one will be selected
9+
subnetIDs:
10+
- subnet-0f59b4f14737be9ad # Replace with your subnet ID
11+
- subnet-abcdef1234567890 # Replace with your subnet ID
12+
securityGroupIDs:
13+
- sg-05da196f3314d4af8 # Replace with your security group ID
14+
deviceIndex: 1
15+
deleteOnTermination: true
16+
description: "ENI with multiple subnet options"
17+
---
18+
# Alternative using subnet names
19+
apiVersion: networking.k8s.aws/v1alpha1
20+
kind: NodeENI
21+
metadata:
22+
name: multi-subnet-name-eni
23+
spec:
24+
nodeSelector:
25+
ng: multi-eni
26+
# Specify multiple subnet names - one will be selected
27+
subnetNames:
28+
- eks-private-subnet-1
29+
- eks-private-subnet-2
30+
securityGroupIDs:
31+
- sg-05da196f3314d4af8 # Replace with your security group ID
32+
deviceIndex: 2
33+
deleteOnTermination: true
34+
description: "ENI with multiple subnet name options"

pkg/apis/networking/v1alpha1/types.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,16 @@ type NodeENISpec struct {
3737
// +optional
3838
SubnetName string `json:"subnetName,omitempty"`
3939

40+
// SubnetIDs is a list of AWS Subnet IDs where the ENI can be created
41+
// If specified, one subnet will be selected from this list
42+
// +optional
43+
SubnetIDs []string `json:"subnetIDs,omitempty"`
44+
45+
// SubnetNames is a list of AWS Subnet Names where the ENI can be created
46+
// If SubnetIDs is not provided, SubnetNames will be used to look up the subnets
47+
// +optional
48+
SubnetNames []string `json:"subnetNames,omitempty"`
49+
4050
// SecurityGroupIDs are the AWS Security Group IDs to attach to the ENI
4151
// +optional
4252
SecurityGroupIDs []string `json:"securityGroupIDs,omitempty"`

pkg/controller/nodeeni_controller.go

Lines changed: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -466,19 +466,9 @@ func (r *NodeENIReconciler) createENI(ctx context.Context, nodeENI *networkingv1
466466
}
467467

468468
// Determine the subnet ID to use
469-
subnetID := nodeENI.Spec.SubnetID
470-
if subnetID == "" && nodeENI.Spec.SubnetName != "" {
471-
// Look up subnet ID by name
472-
var err error
473-
subnetID, err = r.AWS.GetSubnetIDByName(ctx, nodeENI.Spec.SubnetName)
474-
if err != nil {
475-
return "", fmt.Errorf("failed to get subnet ID from name %s: %v", nodeENI.Spec.SubnetName, err)
476-
}
477-
log.Info("Resolved subnet name to ID", "subnetName", nodeENI.Spec.SubnetName, "subnetID", subnetID)
478-
}
479-
480-
if subnetID == "" {
481-
return "", fmt.Errorf("neither subnetID nor subnetName provided")
469+
subnetID, err := r.determineSubnetID(ctx, nodeENI, log)
470+
if err != nil {
471+
return "", err
482472
}
483473

484474
// Determine the security group IDs to use
@@ -527,6 +517,54 @@ func (r *NodeENIReconciler) createENI(ctx context.Context, nodeENI *networkingv1
527517
return eniID, nil
528518
}
529519

520+
// determineSubnetID determines which subnet ID to use for creating an ENI
521+
func (r *NodeENIReconciler) determineSubnetID(ctx context.Context, nodeENI *networkingv1alpha1.NodeENI, log logr.Logger) (string, error) {
522+
// Priority order:
523+
// 1. Single SubnetID if specified
524+
// 2. Multiple SubnetIDs if specified
525+
// 3. Single SubnetName if specified
526+
// 4. Multiple SubnetNames if specified
527+
528+
// Check for single SubnetID (backward compatibility)
529+
if nodeENI.Spec.SubnetID != "" {
530+
return nodeENI.Spec.SubnetID, nil
531+
}
532+
533+
// Check for multiple SubnetIDs
534+
if len(nodeENI.Spec.SubnetIDs) > 0 {
535+
// For now, simply use the first subnet in the list
536+
// In the future, this could be enhanced with more sophisticated selection logic
537+
subnetID := nodeENI.Spec.SubnetIDs[0]
538+
log.Info("Selected subnet ID from list", "subnetID", subnetID, "totalSubnets", len(nodeENI.Spec.SubnetIDs))
539+
return subnetID, nil
540+
}
541+
542+
// Check for single SubnetName (backward compatibility)
543+
if nodeENI.Spec.SubnetName != "" {
544+
subnetID, err := r.AWS.GetSubnetIDByName(ctx, nodeENI.Spec.SubnetName)
545+
if err != nil {
546+
return "", fmt.Errorf("failed to get subnet ID from name %s: %v", nodeENI.Spec.SubnetName, err)
547+
}
548+
log.Info("Resolved subnet name to ID", "subnetName", nodeENI.Spec.SubnetName, "subnetID", subnetID)
549+
return subnetID, nil
550+
}
551+
552+
// Check for multiple SubnetNames
553+
if len(nodeENI.Spec.SubnetNames) > 0 {
554+
// For now, simply use the first subnet name in the list
555+
subnetName := nodeENI.Spec.SubnetNames[0]
556+
subnetID, err := r.AWS.GetSubnetIDByName(ctx, subnetName)
557+
if err != nil {
558+
return "", fmt.Errorf("failed to get subnet ID from name %s: %v", subnetName, err)
559+
}
560+
log.Info("Resolved subnet name to ID from list", "subnetName", subnetName, "subnetID", subnetID, "totalSubnets", len(nodeENI.Spec.SubnetNames))
561+
return subnetID, nil
562+
}
563+
564+
// No subnet information provided
565+
return "", fmt.Errorf("no subnet information provided (subnetID, subnetIDs, subnetName, or subnetNames)")
566+
}
567+
530568
// attachENI attaches an ENI to an EC2 instance
531569
func (r *NodeENIReconciler) attachENI(ctx context.Context, eniID, instanceID string, deviceIndex int) (string, error) {
532570
// Use default device index if not specified

0 commit comments

Comments
 (0)