Skip to content

Conversation

@zac-nixon
Copy link
Collaborator

@zac-nixon zac-nixon commented Nov 4, 2025

Description

This is a huge PR, I'd recommend to review the individual commits for clarity. I'll also comment through out the PR. This PR adds the ability to connect an ALB Gateway to an NLB Gateway via ALB target of NLB.

Checklist

  • Added tests that cover your change (if possible)
  • Added/modified documentation as required (such as the README.md, or the docs directory)
  • Manually tested
  • Made sure the title of the PR is a good description that can go into the release notes

BONUS POINTS checklist: complete for good vibes and maybe prizes?! 🤯

  • Backfilled missing tests for code in same general area 🎉
  • Refactored something and made the world a better place 🌟

@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label Nov 4, 2025
@k8s-ci-robot k8s-ci-robot requested a review from M00nF1sh November 4, 2025 04:26
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: zac-nixon

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. approved Indicates a PR has been approved by an approver from all required OWNERS files. labels Nov 4, 2025
)

// +kubebuilder:validation:Enum=http;https;tcp
// +kubebuilder:validation:Enum=HTTP;HTTPS;TCP
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This enum validation was incorrect, which made the field unusable as the casing should be all upper case.

}

// TODO - We should probably use an indexer here, we have a task to do this.
if tgconfig.Spec.TargetReference.Kind != nil && *tgconfig.Spec.TargetReference.Kind == "Gateway" && h.tcpRouteEventChan != nil {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is required to support TG config updates that impact ALB typed target groups. We need to find out all TCP Routes that reference the Gateway which the config references it. See the added tests.

if string(beRef.Name) == tgconfig.Spec.TargetReference.Name {

// The route backend ns
var routeNs string
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to support optional namespace, which mandates that when the backend ns is omitted we should use the route namespace.

queue.Add(reconcile.Request{NamespacedName: gw})
}

gateways, err = gatewayutils.GetImpactedGatewaysFromBackendRefs(ctx, h.k8sClient, route.Spec.Rules, route.Namespace, constants.NLBGatewayController)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This implements updates for any Gateways that are attached to by a TCP route.

var secrets []types.NamespacedName
var backendSGRequired bool
var err error
var frontendNlbTargetGroupDesiredState *core.FrontendNlbTargetGroupDesiredState
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I refactored the FE NLB synthesizer to read the FE NLB state from the stack. This means that I don't have to pass a bunch of state around. Instead, the synthesizer just looks within the stack.


if controllerName == ingressController {
if d.enableFrontendNLB {
var desiredFENLBState []*elbv2model.FrontendNlbTargetGroupDesiredState
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This reads the FE NLB state from the stack, I found it easier than passing the state around the Gateway controller.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the change you made. Making it a resource and read it from stack is better. : )

psa.AddToStack(stack, lb.LoadBalancerARN())
}

_ = elbv2model.NewFrontendNlbTargetGroupDesiredState(stack, tgBuilder.getLocalFrontendNlbData())
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This adds the FE NLB state into the stack.

"sigs.k8s.io/aws-load-balancer-controller/pkg/gateway"
"sigs.k8s.io/aws-load-balancer-controller/pkg/gateway/routeutils"
"sigs.k8s.io/aws-load-balancer-controller/pkg/k8s"
"sigs.k8s.io/aws-load-balancer-controller/pkg/model/core"
Copy link
Collaborator Author

@zac-nixon zac-nixon Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I refactored this tg builder to support building target groups from either a gateway or service. the goal was to abstract backend data retrieval so we can use the same tg builder code for service and gateway based targets.

This required moving some functionality to the backend target group configurator I added into the route utils package.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great.

@zac-nixon zac-nixon force-pushed the znixon/gw-api-alb-nlb-try2 branch from e85f2d2 to fd65071 Compare November 4, 2025 16:47
@zac-nixon zac-nixon force-pushed the znixon/gw-api-alb-nlb-try2 branch from fd65071 to 2f550be Compare November 4, 2025 16:47
var desiredFENLBState []*elbv2model.FrontendNlbTargetGroupDesiredState
stack.ListResources(&desiredFENLBState)
var frontendNLBState *elbv2model.FrontendNlbTargetGroupDesiredState
if len(desiredFENLBState) == 1 {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if len(desiredFENLBState) be 0, looks like we are passing nil frontendNLBState. We need make some updates to handle it in NewFrontendNlbTargetSynthesizer

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point, ill add a check to be safe. based off my current read of the code it's not possible but we should be defensive.


func NewFrontendNlbTargetGroupDesiredState(stack core.Stack, stateConfig map[string]*FrontendNlbTargetGroupState) *FrontendNlbTargetGroupDesiredState {
desiredState := &FrontendNlbTargetGroupDesiredState{
ResourceMeta: core.NewResourceMeta(stack, FrontNLBResourceId, FrontNLBResourceId),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the resource type be AWS::ElasticLoadBalancingV2::TargetGroup

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I chose a different resource type because it's not a target group.

TargetGroups map[string]*FrontendNlbTargetGroupState
type FrontendNlbTargetGroupState struct {
	Name string
	ARN  core.StringToken
	// Port -> NLB Listener Port
	Port      int32
	TargetARN core.StringToken
	// TargetPort -> ALB Listener Port
	TargetPort int32
}

It's the struct that you created, to map tg name to the frontend nlb.

@wweiwei-li
Copy link
Collaborator

I think all your changes made to ingress look good to me. I am still reviewing gateway changes.

})

if err != nil {
s.logger.Error(err, "Got this error!")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we log debug error for troubleshooting to know the exact error?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed this because it's an expected error message (when the ALB is still being provisioned)

Name: svc.Name,
Port: networking.ServiceBackendPort{
Number: 80,
/*
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leftover comments. Please uncomment this.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops. done

}
}

if arn == "" {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was wondering what if GetALBARN() fails. We handled when arn is not ready here. Nice

}
}
var err error
if resultSet.Len() > 0 {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be errorSet > 0 ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes 💯 let me add a unit test here to validate this path.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually, while writing the unit tests and your comment below. I realized that this function doesn't do anything. This was detecting changes to the TCP route and trying to enqueue ALB Gateways. ALB Gateways don't need to care about changes to the NLB

queue.Add(reconcile.Request{NamespacedName: gw})
}

gateways, err = gatewayutils.GetImpactedGatewaysFromBackendRefs(ctx, h.k8sClient, route.Spec.Rules, route.Namespace, constants.NLBGatewayController)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be constants.ALBGatewayController ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NLB is correct here because TCP routes attach to the NLB. It's a little confusing because the TCP route ends up pointing to the ALB.

@wweiwei-li
Copy link
Collaborator

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Nov 6, 2025
@k8s-ci-robot k8s-ci-robot merged commit 88f7c1c into kubernetes-sigs:main Nov 6, 2025
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants