Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add ipv4 ipam support for alb #4073

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions apis/elbv2/v1beta1/ingressclassparams_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,13 @@ type MinimumLoadBalancerCapacity struct {
CapacityUnits int32 `json:"capacityUnits"`
}

// IPAMConfiguration defines the IPAM configuration for an Ingress.
type IPAMConfiguration struct {
// IPv4IPAMPoolId defines the IPAM pool ID used for IPv4 Addresses on the ALB.
// +optional
IPv4IPAMPoolId *string `json:"ipv4IPAMPoolId,omitempty"`
}

// IngressClassParamsSpec defines the desired state of IngressClassParams
type IngressClassParamsSpec struct {
// CertificateArn specifies the ARN of the certificates for all Ingresses that belong to IngressClass with this IngressClassParams.
Expand Down Expand Up @@ -156,6 +163,10 @@ type IngressClassParamsSpec struct {
// MinimumLoadBalancerCapacity define the capacity reservation for LoadBalancers for all Ingress that belong to IngressClass with this IngressClassParams.
// +optional
MinimumLoadBalancerCapacity *MinimumLoadBalancerCapacity `json:"minimumLoadBalancerCapacity,omitempty"`

// IPAMConfiguration defines the IPAM settings for a Load Balancer.
// +optional
IPAMConfiguration *IPAMConfiguration `json:"ipamConfiguration,omitempty"`
}

// +kubebuilder:object:root=true
Expand Down
25 changes: 25 additions & 0 deletions apis/elbv2/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions config/crd/bases/elbv2.k8s.aws_ingressclassparams.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,15 @@ spec:
- dualstack
- dualstack-without-public-ipv4
type: string
ipamConfiguration:
description: IPAMConfiguration defines the IPAM settings for a Load
Balancer.
properties:
ipv4IPAMPoolId:
description: IPv4IPAMPoolId defines the IPAM pool ID used for
IPv4 Addresses on the ALB.
type: string
type: object
listeners:
description: Listeners define a list of listeners with their protocol,
port and attributes.
Expand Down
110 changes: 62 additions & 48 deletions docs/guide/ingress/annotations.md

Large diffs are not rendered by default.

8 changes: 7 additions & 1 deletion docs/guide/ingress/ingress_class.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,4 +251,10 @@ They may specify `capacityUnits`. If the field is specified, LBC will ignore the

##### spec.minimumLoadBalancerCapacity.capacityUnits

If `capacityUnits` is specified, it must be to valid positive value greater than 0. If set to 0, the LBC will reset the capacity reservation for the load balancer.
If `capacityUnits` is specified, it must be to valid positive value greater than 0. If set to 0, the LBC will reset the capacity reservation for the load balancer.

#### spec.ipv4IPAMPoolId

The IPAM pool you choose will be the preferred source of public IPv4 addresses.
If the pool is depleted, IPv4 addresses will be assigned by AWS.
To remove the IPAM pool from your ALB, remove `spec.ipv4IPAMPoolId` from the IngressClass definition.
3 changes: 2 additions & 1 deletion docs/install/iam_policy.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@
"elasticloadbalancing:DescribeTags",
"elasticloadbalancing:DescribeTrustStores",
"elasticloadbalancing:DescribeListenerAttributes",
"elasticloadbalancing:DescribeCapacityReservation"
"elasticloadbalancing:DescribeCapacityReservation",
"elasticloadbalancing:ModifyIpPools"
],
"Resource": "*"
},
Expand Down
3 changes: 2 additions & 1 deletion docs/install/iam_policy_cn.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@
"elasticloadbalancing:DescribeTags",
"elasticloadbalancing:DescribeTrustStores",
"elasticloadbalancing:DescribeListenerAttributes",
"elasticloadbalancing:DescribeCapacityReservation"
"elasticloadbalancing:DescribeCapacityReservation",
"elasticloadbalancing:ModifyIpPools"
],
"Resource": "*"
},
Expand Down
3 changes: 2 additions & 1 deletion docs/install/iam_policy_iso.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@
"elasticloadbalancing:DescribeTargetGroups",
"elasticloadbalancing:DescribeTargetGroupAttributes",
"elasticloadbalancing:DescribeTargetHealth",
"elasticloadbalancing:DescribeTags"
"elasticloadbalancing:DescribeTags",
"elasticloadbalancing:ModifyIpPools"
],
"Resource": "*"
},
Expand Down
3 changes: 2 additions & 1 deletion docs/install/iam_policy_isob.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@
"elasticloadbalancing:DescribeTargetGroups",
"elasticloadbalancing:DescribeTargetGroupAttributes",
"elasticloadbalancing:DescribeTargetHealth",
"elasticloadbalancing:DescribeTags"
"elasticloadbalancing:DescribeTags",
"elasticloadbalancing:ModifyIpPools"
],
"Resource": "*"
},
Expand Down
3 changes: 2 additions & 1 deletion docs/install/iam_policy_isoe.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@
"elasticloadbalancing:DescribeTargetGroups",
"elasticloadbalancing:DescribeTargetGroupAttributes",
"elasticloadbalancing:DescribeTargetHealth",
"elasticloadbalancing:DescribeTags"
"elasticloadbalancing:DescribeTags",
"elasticloadbalancing:ModifyIpPools"
],
"Resource": "*"
},
Expand Down
3 changes: 2 additions & 1 deletion docs/install/iam_policy_isof.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@
"elasticloadbalancing:DescribeTargetGroups",
"elasticloadbalancing:DescribeTargetGroupAttributes",
"elasticloadbalancing:DescribeTargetHealth",
"elasticloadbalancing:DescribeTags"
"elasticloadbalancing:DescribeTags",
"elasticloadbalancing:ModifyIpPools"
],
"Resource": "*"
},
Expand Down
3 changes: 2 additions & 1 deletion docs/install/iam_policy_us-gov.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@
"elasticloadbalancing:DescribeTags",
"elasticloadbalancing:DescribeTrustStores",
"elasticloadbalancing:DescribeListenerAttributes",
"elasticloadbalancing:DescribeCapacityReservation"
"elasticloadbalancing:DescribeCapacityReservation",
"elasticloadbalancing:ModifyIpPools"
],
"Resource": "*"
},
Expand Down
10 changes: 6 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.23.6

require (
github.com/aws/aws-sdk-go v1.55.5
github.com/aws/aws-sdk-go-v2 v1.32.6
github.com/aws/aws-sdk-go-v2 v1.36.2
github.com/aws/aws-sdk-go-v2/config v1.27.27
github.com/aws/aws-sdk-go-v2/credentials v1.17.27
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11
Expand All @@ -18,7 +18,7 @@ require (
github.com/aws/aws-sdk-go-v2/service/sts v1.30.3
github.com/aws/aws-sdk-go-v2/service/wafregional v1.23.3
github.com/aws/aws-sdk-go-v2/service/wafv2 v1.51.4
github.com/aws/smithy-go v1.22.1
github.com/aws/smithy-go v1.22.2
github.com/evanphx/json-patch v5.7.0+incompatible
github.com/gavv/httpexpect/v2 v2.9.0
github.com/go-logr/logr v1.4.2
Expand Down Expand Up @@ -58,8 +58,8 @@ require (
github.com/ajg/form v1.5.1 // indirect
github.com/andybalholm/brotli v1.0.4 // indirect
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.25 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.33 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.33 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17 // indirect
Expand Down Expand Up @@ -199,3 +199,5 @@ require (
sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
)

replace github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 => ./scripts/aws_sdk_model_override/awsSdkGoV2/service/elasticloadbalancingv2
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU
github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU=
github.com/aws/aws-sdk-go-v2 v1.32.6 h1:7BokKRgRPuGmKkFMhEg/jSul+tB9VvXhcViILtfG8b4=
github.com/aws/aws-sdk-go-v2 v1.32.6/go.mod h1:P5WJBrYqqbWVaOxgH0X/FYYD47/nooaPOZPlQdmiN2U=
github.com/aws/aws-sdk-go-v2 v1.36.2 h1:Ub6I4lq/71+tPb/atswvToaLGVMxKZvjYDVOWEExOcU=
github.com/aws/aws-sdk-go-v2 v1.36.2/go.mod h1:LLXuLpgzEbD766Z5ECcRmi8AzSwfZItDtmABVkRLGzg=
github.com/aws/aws-sdk-go-v2/config v1.27.27 h1:HdqgGt1OAP0HkEDDShEl0oSYa9ZZBSOmKpdpsDMdO90=
github.com/aws/aws-sdk-go-v2/config v1.27.27/go.mod h1:MVYamCg76dFNINkZFu4n4RjDixhVr51HLj4ErWzrVwg=
github.com/aws/aws-sdk-go-v2/credentials v1.17.27 h1:2raNba6gr2IfA0eqqiP2XiQ0UVOpGPgDSi0I9iAP+UI=
Expand All @@ -48,8 +50,12 @@ github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11 h1:KreluoV8FZDEtI6Co2xuNk
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11/go.mod h1:SeSUYBLsMYFoRvHE0Tjvn7kbxaUhl75CJi1sbfhMxkU=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.25 h1:s/fF4+yDQDoElYhfIVvSNyeCydfbuTKzhxSXDXCPasU=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.25/go.mod h1:IgPfDv5jqFIzQSNbUEMoitNooSMXjRSDkhXv8jiROvU=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.33 h1:knLyPMw3r3JsU8MFHWctE4/e2qWbPaxDYLlohPvnY8c=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.33/go.mod h1:EBp2HQ3f+XCB+5J+IoEbGhoV7CpJbnrsd4asNXmTL0A=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25 h1:ZntTCl5EsYnhN/IygQEUugpdwbhdkom9uHcbCftiGgA=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25/go.mod h1:DBdPrgeocww+CSl1C8cEV8PN1mHMBhuCDLpXezyvWkE=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.33 h1:K0+Ne08zqti8J9jwENxZ5NoUyBnaFDTu3apwQJWrwwA=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.33/go.mod h1:K97stwwzaWzmqxO8yLGHhClbVW1tC6VT1pDLk1pGrq4=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY=
github.com/aws/aws-sdk-go-v2/service/acm v1.28.4 h1:wiW1Y6/1lysA0eJZRq0I53YYKuV9MNAzL15z2eZRlEE=
Expand Down Expand Up @@ -82,6 +88,8 @@ github.com/aws/aws-sdk-go-v2/service/wafv2 v1.51.4 h1:1khBA5uryBRJoCb4G2iR5RT06B
github.com/aws/aws-sdk-go-v2/service/wafv2 v1.51.4/go.mod h1:QpFImaPGKNwa+MiZ+oo6LbV1PVQBapc0CnrAMRScoxM=
github.com/aws/smithy-go v1.22.1 h1:/HPHZQ0g7f4eUeK6HKglFz8uwVfZKgoI25rb/J+dnro=
github.com/aws/smithy-go v1.22.1/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg=
github.com/aws/smithy-go v1.22.2 h1:6D9hW43xKFrRx/tXXfAlIZc4JI+yQe6snnWcQyxSyLQ=
github.com/aws/smithy-go v1.22.2/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
Expand Down
1 change: 1 addition & 0 deletions pkg/annotations/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ const (
IngressSuffixlsAttsAnnotationPrefix = "listener-attributes"
IngressLBSuffixMultiClusterTargetGroup = "multi-cluster-target-group"
IngressSuffixLoadBalancerCapacityReservation = "minimum-load-balancer-capacity"
IngressSuffixIPAMIPv4PoolId = "ipam-ipv4-pool-id"

// NLB annotation suffixes
// prefixes service.beta.kubernetes.io, service.kubernetes.io
Expand Down
9 changes: 9 additions & 0 deletions pkg/aws/services/elbv2.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ type ELBV2 interface {
ModifyListenerAttributesWithContext(ctx context.Context, input *elasticloadbalancingv2.ModifyListenerAttributesInput) (*elasticloadbalancingv2.ModifyListenerAttributesOutput, error)
ModifyCapacityReservationWithContext(ctx context.Context, input *elasticloadbalancingv2.ModifyCapacityReservationInput) (*elasticloadbalancingv2.ModifyCapacityReservationOutput, error)
DescribeCapacityReservationWithContext(ctx context.Context, input *elasticloadbalancingv2.DescribeCapacityReservationInput) (*elasticloadbalancingv2.DescribeCapacityReservationOutput, error)
ModifyIPPoolsWithContext(ctx context.Context, input *elasticloadbalancingv2.ModifyIpPoolsInput) (*elasticloadbalancingv2.ModifyIpPoolsOutput, error)
AssumeRole(ctx context.Context, assumeRoleArn string, externalId string) (ELBV2, error)
}

Expand Down Expand Up @@ -476,6 +477,14 @@ func (c *elbv2Client) DescribeCapacityReservationWithContext(ctx context.Context
return client.DescribeCapacityReservation(ctx, input)
}

func (c *elbv2Client) ModifyIPPoolsWithContext(ctx context.Context, input *elasticloadbalancingv2.ModifyIpPoolsInput) (*elasticloadbalancingv2.ModifyIpPoolsOutput, error) {
client, err := c.getClient(ctx, "ModifyIpPools")
if err != nil {
return nil, err
}
return client.ModifyIpPools(ctx, input)
}

func (c *elbv2Client) getClient(ctx context.Context, operation string) (*elasticloadbalancingv2.Client, error) {
if c.staticELBClient != nil {
return c.staticELBClient, nil
Expand Down
15 changes: 15 additions & 0 deletions pkg/aws/services/elbv2_mocks.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

52 changes: 52 additions & 0 deletions pkg/deploy/elbv2/load_balancer_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ func (m *defaultLoadBalancerManager) Create(ctx context.Context, resLB *elbv2mod
}

func (m *defaultLoadBalancerManager) Update(ctx context.Context, resLB *elbv2model.LoadBalancer, sdkLB LoadBalancerWithTags) (elbv2model.LoadBalancerStatus, error) {
// It's important to remove ipam pools first, because we need to remove any ipam pools before changing the IP Address type.
if err := m.removeIPAMPools(ctx, resLB, sdkLB); err != nil {
return elbv2model.LoadBalancerStatus{}, err
}
if err := m.updateSDKLoadBalancerWithTags(ctx, resLB, sdkLB); err != nil {
return elbv2model.LoadBalancerStatus{}, err
}
Expand All @@ -108,6 +112,11 @@ func (m *defaultLoadBalancerManager) Update(ctx context.Context, resLB *elbv2mod
if err := m.checkSDKLoadBalancerWithCOIPv4Pool(ctx, resLB, sdkLB); err != nil {
return elbv2model.LoadBalancerStatus{}, err
}
// We can safely change the IPAM pool here after all other modifications are done.
if err := m.addIPAMPools(ctx, resLB, sdkLB); err != nil {
return elbv2model.LoadBalancerStatus{}, err
}

return buildResLoadBalancerStatus(sdkLB), nil
}

Expand Down Expand Up @@ -278,6 +287,43 @@ func (m *defaultLoadBalancerManager) updateSDKLoadBalancerWithTags(ctx context.C
WithIgnoredTagKeys(m.externalManagedTags))
}

func (m *defaultLoadBalancerManager) removeIPAMPools(ctx context.Context, resLB *elbv2model.LoadBalancer, sdkLB LoadBalancerWithTags) error {
// No IPAM pool to remove or the request is to actually add / change IPAM pool.
if sdkLB.LoadBalancer.IpamPools == nil || resLB.Spec.IPv4IPAMPool != nil {
return nil
}

req := &elbv2sdk.ModifyIpPoolsInput{
RemoveIpamPools: []elbv2types.RemoveIpamPoolEnum{elbv2types.RemoveIpamPoolEnumIpv4},
}

_, err := m.elbv2Client.ModifyIPPoolsWithContext(ctx, req)
return err
}

func (m *defaultLoadBalancerManager) addIPAMPools(ctx context.Context, resLB *elbv2model.LoadBalancer, sdkLB LoadBalancerWithTags) error {
// No IPAM pool to set, this case should be handled by removeIPAMPools
if resLB.Spec.IPv4IPAMPool == nil {
return nil
}

// IPAM pool is already correctly set
if sdkLB.LoadBalancer.IpamPools != nil && sdkLB.LoadBalancer.IpamPools.Ipv4IpamPoolId != nil {
if *sdkLB.LoadBalancer.IpamPools.Ipv4IpamPoolId == *resLB.Spec.IPv4IPAMPool {
return nil
}
}

req := &elbv2sdk.ModifyIpPoolsInput{
IpamPools: &elbv2types.IpamPools{
Ipv4IpamPoolId: resLB.Spec.IPv4IPAMPool,
},
}

_, err := m.elbv2Client.ModifyIPPoolsWithContext(ctx, req)
return err
}

func buildSDKCreateLoadBalancerInput(lbSpec elbv2model.LoadBalancerSpec) (*elbv2sdk.CreateLoadBalancerInput, error) {
sdkObj := &elbv2sdk.CreateLoadBalancerInput{}
sdkObj.Name = awssdk.String(lbSpec.Name)
Expand All @@ -296,6 +342,12 @@ func buildSDKCreateLoadBalancerInput(lbSpec elbv2model.LoadBalancerSpec) (*elbv2
sdkObj.EnablePrefixForIpv6SourceNat = elbv2types.EnablePrefixForIpv6SourceNatEnum(lbSpec.EnablePrefixForIpv6SourceNat)
}

if lbSpec.IPv4IPAMPool != nil && *lbSpec.IPv4IPAMPool != "" {
sdkObj.IpamPools = &elbv2types.IpamPools{
Ipv4IpamPoolId: lbSpec.IPv4IPAMPool,
}
}

sdkObj.CustomerOwnedIpv4Pool = lbSpec.CustomerOwnedIPv4Pool
return sdkObj, nil
}
Expand Down
Loading
Loading