Skip to content

Commit c2c6e75

Browse files
authored
Merge pull request kubernetes#92224 from M00nF1sh/sg_order
refine aws loadbalancer worker node SG rule logic
2 parents e24cbc9 + 549f9f3 commit c2c6e75

File tree

2 files changed

+98
-16
lines changed

2 files changed

+98
-16
lines changed

staging/src/k8s.io/legacy-cloud-providers/aws/aws.go

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3603,6 +3603,37 @@ func (c *Cloud) buildELBSecurityGroupList(serviceName types.NamespacedName, load
36033603
return sgList, setupSg, nil
36043604
}
36053605

3606+
// sortELBSecurityGroupList returns a list of sorted securityGroupIDs based on the original order
3607+
// from buildELBSecurityGroupList. The logic is:
3608+
// * securityGroups specified by ServiceAnnotationLoadBalancerSecurityGroups appears first in order
3609+
// * securityGroups specified by ServiceAnnotationLoadBalancerExtraSecurityGroups appears last in order
3610+
func (c *Cloud) sortELBSecurityGroupList(securityGroupIDs []string, annotations map[string]string) {
3611+
annotatedSGList := getSGListFromAnnotation(annotations[ServiceAnnotationLoadBalancerSecurityGroups])
3612+
annotatedExtraSGList := getSGListFromAnnotation(annotations[ServiceAnnotationLoadBalancerExtraSecurityGroups])
3613+
annotatedSGIndex := make(map[string]int, len(annotatedSGList))
3614+
annotatedExtraSGIndex := make(map[string]int, len(annotatedExtraSGList))
3615+
3616+
for i, sgID := range annotatedSGList {
3617+
annotatedSGIndex[sgID] = i
3618+
}
3619+
for i, sgID := range annotatedExtraSGList {
3620+
annotatedExtraSGIndex[sgID] = i
3621+
}
3622+
sgOrderMapping := make(map[string]int, len(securityGroupIDs))
3623+
for _, sgID := range securityGroupIDs {
3624+
if i, ok := annotatedSGIndex[sgID]; ok {
3625+
sgOrderMapping[sgID] = i
3626+
} else if j, ok := annotatedExtraSGIndex[sgID]; ok {
3627+
sgOrderMapping[sgID] = len(annotatedSGIndex) + 1 + j
3628+
} else {
3629+
sgOrderMapping[sgID] = len(annotatedSGIndex)
3630+
}
3631+
}
3632+
sort.Slice(securityGroupIDs, func(i, j int) bool {
3633+
return sgOrderMapping[securityGroupIDs[i]] < sgOrderMapping[securityGroupIDs[j]]
3634+
})
3635+
}
3636+
36063637
// buildListener creates a new listener from the given port, adding an SSL certificate
36073638
// if indicated by the appropriate annotations.
36083639
func buildListener(port v1.ServicePort, annotations map[string]string, sslPorts *portSets) (*elb.Listener, error) {
@@ -4015,7 +4046,7 @@ func (c *Cloud) EnsureLoadBalancer(ctx context.Context, clusterName string, apiS
40154046
}
40164047
}
40174048

4018-
err = c.updateInstanceSecurityGroupsForLoadBalancer(loadBalancer, instances)
4049+
err = c.updateInstanceSecurityGroupsForLoadBalancer(loadBalancer, instances, annotations)
40194050
if err != nil {
40204051
klog.Warningf("Error opening ingress rules for the load balancer to the instances: %q", err)
40214052
return nil, err
@@ -4173,26 +4204,18 @@ func (c *Cloud) getTaggedSecurityGroups() (map[string]*ec2.SecurityGroup, error)
41734204

41744205
// Open security group ingress rules on the instances so that the load balancer can talk to them
41754206
// Will also remove any security groups ingress rules for the load balancer that are _not_ needed for allInstances
4176-
func (c *Cloud) updateInstanceSecurityGroupsForLoadBalancer(lb *elb.LoadBalancerDescription, instances map[InstanceID]*ec2.Instance) error {
4207+
func (c *Cloud) updateInstanceSecurityGroupsForLoadBalancer(lb *elb.LoadBalancerDescription, instances map[InstanceID]*ec2.Instance, annotations map[string]string) error {
41774208
if c.cfg.Global.DisableSecurityGroupIngress {
41784209
return nil
41794210
}
41804211

41814212
// Determine the load balancer security group id
4182-
loadBalancerSecurityGroupID := ""
4183-
for _, securityGroup := range lb.SecurityGroups {
4184-
if aws.StringValue(securityGroup) == "" {
4185-
continue
4186-
}
4187-
if loadBalancerSecurityGroupID != "" {
4188-
// We create LBs with one SG
4189-
klog.Warningf("Multiple security groups for load balancer: %q", aws.StringValue(lb.LoadBalancerName))
4190-
}
4191-
loadBalancerSecurityGroupID = *securityGroup
4192-
}
4193-
if loadBalancerSecurityGroupID == "" {
4213+
lbSecurityGroupIDs := aws.StringValueSlice(lb.SecurityGroups)
4214+
if len(lbSecurityGroupIDs) == 0 {
41944215
return fmt.Errorf("could not determine security group for load balancer: %s", aws.StringValue(lb.LoadBalancerName))
41954216
}
4217+
c.sortELBSecurityGroupList(lbSecurityGroupIDs, annotations)
4218+
loadBalancerSecurityGroupID := lbSecurityGroupIDs[0]
41964219

41974220
// Get the actual list of groups that allow ingress from the load-balancer
41984221
var actualGroups []*ec2.SecurityGroup
@@ -4368,7 +4391,7 @@ func (c *Cloud) EnsureLoadBalancerDeleted(ctx context.Context, clusterName strin
43684391

43694392
{
43704393
// De-authorize the load balancer security group from the instances security group
4371-
err = c.updateInstanceSecurityGroupsForLoadBalancer(lb, nil)
4394+
err = c.updateInstanceSecurityGroupsForLoadBalancer(lb, nil, service.Annotations)
43724395
if err != nil {
43734396
klog.Errorf("Error deregistering load balancer from instance security groups: %q", err)
43744397
return err
@@ -4533,7 +4556,7 @@ func (c *Cloud) UpdateLoadBalancer(ctx context.Context, clusterName string, serv
45334556
return nil
45344557
}
45354558

4536-
err = c.updateInstanceSecurityGroupsForLoadBalancer(lb, instances)
4559+
err = c.updateInstanceSecurityGroupsForLoadBalancer(lb, instances, service.Annotations)
45374560
if err != nil {
45384561
return err
45394562
}

staging/src/k8s.io/legacy-cloud-providers/aws/aws_test.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2554,3 +2554,62 @@ func TestAzToRegion(t *testing.T) {
25542554
assert.Equal(t, testCase.region, result)
25552555
}
25562556
}
2557+
2558+
func TestCloud_sortELBSecurityGroupList(t *testing.T) {
2559+
type args struct {
2560+
securityGroupIDs []string
2561+
annotations map[string]string
2562+
}
2563+
tests := []struct {
2564+
name string
2565+
args args
2566+
wantSecurityGroupIDs []string
2567+
}{
2568+
{
2569+
name: "with no annotation",
2570+
args: args{
2571+
securityGroupIDs: []string{"sg-1"},
2572+
annotations: map[string]string{},
2573+
},
2574+
wantSecurityGroupIDs: []string{"sg-1"},
2575+
},
2576+
{
2577+
name: "with service.beta.kubernetes.io/aws-load-balancer-security-groups",
2578+
args: args{
2579+
securityGroupIDs: []string{"sg-2", "sg-1", "sg-3"},
2580+
annotations: map[string]string{
2581+
"service.beta.kubernetes.io/aws-load-balancer-security-groups": "sg-3,sg-2,sg-1",
2582+
},
2583+
},
2584+
wantSecurityGroupIDs: []string{"sg-3", "sg-2", "sg-1"},
2585+
},
2586+
{
2587+
name: "with service.beta.kubernetes.io/aws-load-balancer-extra-security-groups",
2588+
args: args{
2589+
securityGroupIDs: []string{"sg-2", "sg-1", "sg-3", "sg-4"},
2590+
annotations: map[string]string{
2591+
"service.beta.kubernetes.io/aws-load-balancer-extra-security-groups": "sg-3,sg-2,sg-1",
2592+
},
2593+
},
2594+
wantSecurityGroupIDs: []string{"sg-4", "sg-3", "sg-2", "sg-1"},
2595+
},
2596+
{
2597+
name: "with both annotation",
2598+
args: args{
2599+
securityGroupIDs: []string{"sg-2", "sg-1", "sg-3", "sg-4", "sg-5", "sg-6"},
2600+
annotations: map[string]string{
2601+
"service.beta.kubernetes.io/aws-load-balancer-security-groups": "sg-3,sg-2,sg-1",
2602+
"service.beta.kubernetes.io/aws-load-balancer-extra-security-groups": "sg-6,sg-5",
2603+
},
2604+
},
2605+
wantSecurityGroupIDs: []string{"sg-3", "sg-2", "sg-1", "sg-4", "sg-6", "sg-5"},
2606+
},
2607+
}
2608+
for _, tt := range tests {
2609+
t.Run(tt.name, func(t *testing.T) {
2610+
c := &Cloud{}
2611+
c.sortELBSecurityGroupList(tt.args.securityGroupIDs, tt.args.annotations)
2612+
assert.Equal(t, tt.wantSecurityGroupIDs, tt.args.securityGroupIDs)
2613+
})
2614+
}
2615+
}

0 commit comments

Comments
 (0)