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

feat: add label to exclude from external loadbalancers #131

Merged
merged 3 commits into from
Sep 4, 2023

Conversation

derbauer97
Copy link
Contributor

@derbauer97 derbauer97 commented Jul 13, 2023

Summary

Not yet i can open one if needed. Problem is that if i have a NodePort to expose for example my nginx ingress controller to an Elastic Loadbalancer. The Loadbalancer is not notified if i terminate one of our Nodes. Therefore, Kubernetes invented the exclude-for-external-loadbalancers label. When i add this label to a node the aws-loadbalancer-controller starts deregistering the Node from their TargetGroup which prevents Connections issue during Rolling Update.

For Reference: https://kubernetes.io/docs/reference/labels-annotations-taints/#node-kubernetes-io-exclude-from-external-load-balancers

Implementation in Karpenter: aws/karpenter-provider-aws#2518

Checklist

  • Tested and/or added tests to validate that the changes work as intended, if applicable.
  • Updated documentation in README.md, if applicable.

Copy link
Owner

@TwiN TwiN left a comment

Choose a reason for hiding this comment

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

Could you make this configuration disabled by default & expose it via an environment variable?

main.go Outdated Show resolved Hide resolved
@derbauer97
Copy link
Contributor Author

Hey,

thanks for reviewing bei PR. Why you want to have this behavior optional in my opinion this has only advantages. If you do not have a loadbalancer controller nothing will happen when adding the lable. If you have one the Loadbalancer will deregister the nodes properly. Also i do not know any implementation in which this is optional.

For the Label value we can go for something else. We call your tool Twin internally because its much shorter than aws-rolling-update-handler. Maybe i got influenced by this ^^ But i think it is a good idea to use something which allows to track which controller added the label. Do you have any ideas. We can go for aws-eks-rolling-update-handler if you want to.

@TwiN
Copy link
Owner

TwiN commented Jul 25, 2023

@derbauer97 I don't blame you for shortening the application name, I regret giving it such a long name sometimes as well 😂

The label's value should probably be true as it seems to be the most commonly used value for this annotation, even in Kubernetes' own documentation: https://kubernetes.io/docs/reference/labels-annotations-taints/#node-kubernetes-io-exclude-from-external-load-balancers

That being said, the main reason why I'd want to make this an opt-in feature rather than an opt-out feature is that making it opt-out would make this a breaking change as it modifies the current behavior of the application, and we don't know how every user's clusters are configured.

Once time has passed and the feature has more users, I may consider enabling this by default, but for now, I'd rather not expose users to unnecessary risks.

@derbauer97
Copy link
Contributor Author

Allright understand i will build it optional.

Do you have any preferences for the implementation:

  1. We can always set the label but if "EXLUDE_FROM_EXTERNAL_LOAD_BALANCERS" not enabled set to false otherwise set to true
  2. do no set the label at all apart from EXLUDE_FROM_EXTERNAL_LOAD_BALANCERS is set to true then we set the label

We can also change the variable name it is a bit long but i do not know a better name :D

@derbauer97
Copy link
Contributor Author

I pushed the second option. Hope for your Feedback!

Copy link
Owner

@TwiN TwiN left a comment

Choose a reason for hiding this comment

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

Awesome!

Now next problem is that there are no tests 😅

The very similar AnnotateNodeByAutoScalingInstance function at

func AnnotateNodeByAutoScalingInstance(client ClientAPI, instance *autoscaling.Instance, key, value string) error {
doesn't have tests directly in util_test.go either, but it is tested here:
if mockClient.Counter["UpdateNode"] != 1 {
t.Error("Node should've been annotated, meaning that UpdateNode should've been called once")
}
oldNode = mockClient.Nodes[oldNode.Name]
if _, ok := oldNode.GetAnnotations()[k8s.AnnotationRollingUpdateStartedTimestamp]; !ok {
t.Error("Node should've been annotated with", k8s.AnnotationRollingUpdateStartedTimestamp)
}
if _, ok := oldNode.GetAnnotations()[k8s.AnnotationRollingUpdateDrainedTimestamp]; ok {
t.Error("Node shouldn't have been drained yet, therefore shouldn't have been annotated with", k8s.AnnotationRollingUpdateDrainedTimestamp)
}
if _, ok := oldNode.GetAnnotations()[k8s.AnnotationRollingUpdateTerminatedTimestamp]; ok {
t.Error("Node shouldn't have been terminated yet, therefore shouldn't have been annotated with", k8s.AnnotationRollingUpdateTerminatedTimestamp)
}

I'd expect a separate test - something like TestHandleRollingUpgrade_withExcludeFromExternalLoadBalancers - to ensure that the label node.kubernetes.io/exclude-from-external-load-balancers has been added successfully if ExcludeFromExternalLoadBalancers is set to true.

This will also require updating

func Set(autoScalingGroupNames []string, ignoreDaemonSets, deleteEmptyDirData, eagerCordoning bool) {
so that a new bool excludeFromExternalLoadBalancers can be set.

config/config.go Outdated Show resolved Hide resolved
@derbauer97
Copy link
Contributor Author

Sure your are right! ;)

I added a test with excludeFromExternalLoadBalancers which succeeds. I did not handle the case that the node has no labels at all which i think is very unlikely especially in aw. Because certain default labels are always added and we are not handling this for annotations either.

Also i put the Label Definition to the k8s module which is cleaner in my opinion and then labels are treated like the annotation you are already adding to the nodes.

Ready for your Feedback :D

@JPfeifer21
Copy link

Any ETA when this feature gets released?
We would need this too.

Thanks in advance!

@derbauer97
Copy link
Contributor Author

Hey @TwiN,

is there anything i can do to get this merged. I adressed all your change requests i think. If there is anything else please let me know. Would be cool to get this feature in upstream.

@TwiN TwiN merged commit c1641aa into TwiN:master Sep 4, 2023
@TwiN
Copy link
Owner

TwiN commented Sep 4, 2023

@derbauer97 Thank you for the contribution!

@TwiN
Copy link
Owner

TwiN commented Sep 4, 2023

@derbauer97 @JPfeifer21 Could you let me know if it works as intended on the latest tag?

Once you've confirmed, I'll go ahead and release it as part of a new version (v1.9.0).

EnvMetricsPort = "METRICS_PORT"
EnvSlowMode = "SLOW_MODE"
EnvEagerCordoning = "EAGER_CORDONING"
EnvExcludeFromExternalLoadBalancers = "EXLUDE_FROM_EXTERNAL_LOAD_BALANCERS"
Copy link
Owner

Choose a reason for hiding this comment

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

I just noticed you made a typo in the environment variable 😂

Copy link
Owner

Choose a reason for hiding this comment

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

Resolved by 3b8647b

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh damn it :D thanks for fixing this!

TwiN added a commit that referenced this pull request Sep 23, 2023
@TwiN TwiN changed the title add label to exclude from external loadbalancers feat: add label to exclude from external loadbalancers Sep 23, 2023
@derbauer97
Copy link
Contributor Author

I tested it seems to work fine. So feel free to release a new version.

@dinesh
Copy link

dinesh commented Nov 2, 2023

@TwiN can you please release a new version having this fix?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants