diff --git a/pkg/cloudprovider/providers/aws/aws.go b/pkg/cloudprovider/providers/aws/aws.go index c785583b859..8fd1891d04a 100644 --- a/pkg/cloudprovider/providers/aws/aws.go +++ b/pkg/cloudprovider/providers/aws/aws.go @@ -420,6 +420,11 @@ type CloudConfig struct { //local VPC subnet (so load balancers can access it). E.g. 10.82.0.0/16 30000-32000. DisableSecurityGroupIngress bool + //AWS has a hard limit of 500 security groups. For large clusters creating a security group for each ELB + //can cause the max number of security groups to be reached. If this is set instead of creating a new + //Security group for each ELB this security group will be used instead. + ElbSecurityGroup string + //During the instantiation of an new AWS cloud provider, the detected region //is validated against a known set of regions. // @@ -2764,48 +2769,54 @@ func (c *Cloud) EnsureLoadBalancer(clusterName string, apiService *v1.Service, n // Create a security group for the load balancer var securityGroupID string { - sgName := "k8s-elb-" + loadBalancerName - sgDescription := fmt.Sprintf("Security group for Kubernetes ELB %s (%v)", loadBalancerName, serviceName) - securityGroupID, err = c.ensureSecurityGroup(sgName, sgDescription) - if err != nil { - glog.Error("Error creating load balancer security group: ", err) - return nil, err - } + if c.cfg.Global.ElbSecurityGroup != "" { + securityGroupID = c.cfg.Global.ElbSecurityGroup - ec2SourceRanges := []*ec2.IpRange{} - for _, sourceRange := range sourceRanges.StringSlice() { - ec2SourceRanges = append(ec2SourceRanges, &ec2.IpRange{CidrIp: aws.String(sourceRange)}) - } + } else { - permissions := NewIPPermissionSet() - for _, port := range apiService.Spec.Ports { - portInt64 := int64(port.Port) - protocol := strings.ToLower(string(port.Protocol)) - - permission := &ec2.IpPermission{} - permission.FromPort = &portInt64 - permission.ToPort = &portInt64 - permission.IpRanges = ec2SourceRanges - permission.IpProtocol = &protocol - - permissions.Insert(permission) - } - - // Allow ICMP fragmentation packets, important for MTU discovery - { - permission := &ec2.IpPermission{ - IpProtocol: aws.String("icmp"), - FromPort: aws.Int64(3), - ToPort: aws.Int64(4), - IpRanges: []*ec2.IpRange{{CidrIp: aws.String("0.0.0.0/0")}}, + sgName := "k8s-elb-" + loadBalancerName + sgDescription := fmt.Sprintf("Security group for Kubernetes ELB %s (%v)", loadBalancerName, serviceName) + securityGroupID, err = c.ensureSecurityGroup(sgName, sgDescription) + if err != nil { + glog.Error("Error creating load balancer security group: ", err) + return nil, err } - permissions.Insert(permission) - } + ec2SourceRanges := []*ec2.IpRange{} + for _, sourceRange := range sourceRanges.StringSlice() { + ec2SourceRanges = append(ec2SourceRanges, &ec2.IpRange{CidrIp: aws.String(sourceRange)}) + } - _, err = c.setSecurityGroupIngress(securityGroupID, permissions) - if err != nil { - return nil, err + permissions := NewIPPermissionSet() + for _, port := range apiService.Spec.Ports { + portInt64 := int64(port.Port) + protocol := strings.ToLower(string(port.Protocol)) + + permission := &ec2.IpPermission{} + permission.FromPort = &portInt64 + permission.ToPort = &portInt64 + permission.IpRanges = ec2SourceRanges + permission.IpProtocol = &protocol + + permissions.Insert(permission) + } + + // Allow ICMP fragmentation packets, important for MTU discovery + { + permission := &ec2.IpPermission{ + IpProtocol: aws.String("icmp"), + FromPort: aws.Int64(3), + ToPort: aws.Int64(4), + IpRanges: []*ec2.IpRange{{CidrIp: aws.String("0.0.0.0/0")}}, + } + + permissions.Insert(permission) + } + + _, err = c.setSecurityGroupIngress(securityGroupID, permissions) + if err != nil { + return nil, err + } } } securityGroupIDs := []string{securityGroupID} @@ -3143,6 +3154,10 @@ func (c *Cloud) EnsureLoadBalancerDeleted(clusterName string, service *v1.Servic // Collect the security groups to delete securityGroupIDs := map[string]struct{}{} for _, securityGroupID := range lb.SecurityGroups { + if *securityGroupID == c.cfg.Global.ElbSecurityGroup { + //We don't want to delete a security group that was defined in the Cloud Configurationn. + continue + } if isNilOrEmpty(securityGroupID) { glog.Warning("Ignoring empty security group in ", service.Name) continue