Skip to content

Conversation

@M4t7e
Copy link
Contributor

@M4t7e M4t7e commented Oct 20, 2025

This PR introduces additional environment variables for load balancer configuration. These variables are designed to be set globally as defaults and can be overridden using annotations.

The main motivation is to improve support for GatewayAPI, as the Gateway annotation limit of 8 is restrictive and many settings are commonly needed across all load balancers from the same or even differen GatewayAPI providers. Additionally, this change allows environment-specific presets such as the new subnet IP range to be set globally. This removes the need to configure these settings in each service or use templating/patching to use the same service manifest for different environments.

New environment vars:

  • HCLOUD_LOAD_BALANCERS_ALGORITHM_TYPE
  • HCLOUD_LOAD_BALANCERS_DISABLE_PUBLIC_NETWORK
  • HCLOUD_LOAD_BALANCERS_HEALTH_CHECK_INTERVAL
  • HCLOUD_LOAD_BALANCERS_HEALTH_CHECK_RETRIES
  • HCLOUD_LOAD_BALANCERS_HEALTH_CHECK_TIMEOUT
  • HCLOUD_LOAD_BALANCERS_PRIVATE_SUBNET_IP_RANGE
  • HCLOUD_LOAD_BALANCERS_TYPE
  • HCLOUD_LOAD_BALANCERS_USES_PROXYPROTOCOL

@M4t7e M4t7e requested a review from a team as a code owner October 20, 2025 17:25
@apricote
Copy link
Member

Hey @M4t7e,

just to confirm, the "8 Annotations" limit is from the Gateway.spec.infrastructure.annotations field, right?

I found this thread where the limit was discussed and added, it sounds like this is a "soft" limit that can be raised if a reasonable case is made for more than 8 annotations: kubernetes-sigs/gateway-api#1757 (comment)

@M4t7e
Copy link
Contributor Author

M4t7e commented Oct 24, 2025

Hey @apricote,

yes, that's the limit I was referring to. I began researching ways to preset annotations in GatewayAPI, since the concept is not to have a single Gateway (Load Balancer) for everything, like it is often the case for Ingress Controller, but to have the flexibility of creating multiple Gateways. To avoid repeating the same config, I was looking into options setting global annotation setting. That's when I came across this issue: kubernetes-sigs/gateway-api#2734

From what I understand, the annotation limit can only be increased through provider-specific implementations like Istio and Envoy already support. In my case, I’m planning to use Cilium GatewayAPI, which as far as I know doesn’t support adding annotations with their custom config.

Btw, this is the actual issue where we want to add GatewayAPI support: hcloud-k8s/terraform-hcloud-kubernetes#216

@apricote
Copy link
Member

I personally dislike the many annotations, and have often wondered how we could provide a better alternative.

The Gateway API parameterRef looks better, but a Gateway API Provider needs to implement L7 functionality, which our Load Balancer currently do not provide. So I figured that it makes no sense to built our own Gateway API Provider.


@lukasmetzner will be back next week to take a closer look at the MR.

@codecov
Copy link

codecov bot commented Oct 28, 2025

Codecov Report

❌ Patch coverage is 77.96610% with 26 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.98%. Comparing base (4d970c6) to head (4572396).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
internal/config/config.go 65.85% 7 Missing and 7 partials ⚠️
internal/hcops/load_balancer.go 84.41% 10 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1052      +/-   ##
==========================================
- Coverage   68.43%   64.98%   -3.46%     
==========================================
  Files          23       23              
  Lines        2531     2610      +79     
==========================================
- Hits         1732     1696      -36     
- Misses        629      746     +117     
+ Partials      170      168       -2     
Flag Coverage Δ
e2e ?
unit 64.98% <77.96%> (+0.46%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@lukasmetzner
Copy link
Contributor

e2e test not passing is fine here. This is an expected permission issue.

@M4t7e
Copy link
Contributor Author

M4t7e commented Dec 3, 2025

@lukasmetzner I made the changes you suggested. Could you please take another look?

@lukasmetzner
Copy link
Contributor

lukasmetzner commented Dec 5, 2025

@lukasmetzner I made the changes you suggested. Could you please take another look?

@M4t7e The code looks and the e2e tests succeed locally on my machine. They are failing here due to expected permission issues with forks.

The only remaining thing is the Lint / pre-commit job, which should succeed here. Looking at the logs, only golangci-lint is failing with some minor refactors necessary: https://github.com/hetznercloud/hcloud-cloud-controller-manager/actions/runs/19902492646/job/57239368786?pr=1052

Could you please fix them, then we can merge this PR. You can either run golangci-lint run --fix directly or use pre-commit.

@M4t7e
Copy link
Contributor Author

M4t7e commented Dec 5, 2025

@lukasmetzner I updated the code formatting to comply with the latest golangci-lint version 2.7.1. This also required a change in internal/metrics/metrics.go:

❯ golangci-lint run
internal/metrics/metrics.go:24:1: File is not properly formatted (goimports)
        "k8s.io/component-base/metrics/legacyregistry"
^
1 issues:
* goimports: 1

@lukasmetzner
Copy link
Contributor

@lukasmetzner I updated the code formatting to comply with the latest golangci-lint version 2.7.1. This also required a change in internal/metrics/metrics.go:

❯ golangci-lint run
internal/metrics/metrics.go:24:1: File is not properly formatted (goimports)
        "k8s.io/component-base/metrics/legacyregistry"
^
1 issues:
* goimports: 1

golangci-lint seems to behave differently when --fix is added. You can ignore this here.

@lukasmetzner lukasmetzner changed the title Add New Environment Variables for Load Balancer Configuration feat: extend environment variables for default load balancer configuration Dec 15, 2025
@lukasmetzner lukasmetzner merged commit c07966f into hetznercloud:main Dec 15, 2025
4 of 9 checks passed
lukasmetzner pushed a commit that referenced this pull request Dec 18, 2025
 ### Watch-Based Route Reconciliation

Previously, route reconciliation is performed at a fixed interval of
30s. This leads to unnecessary API requests, as a `GET
/v1/networks/{id}` call is triggered every 30s, even when no changes
have occurred.

Upstream, we have contributed an event-driven approach, similar to the
mechanisms used by other controllers such as the Load Balancer
controller. With this new approach, route reconciliation is triggered by
node additions, node deletions, or changes to a node’s `PodCIDRs` or
`Addresses`. Additionally, to ensure consistency, reconciliation still
occurs periodically at a randomized interval between 12 and 24 hours.

#### Enabled by default

This feature is now **enabled by default**.

If you encounter any problems you can disable the feature by setting the
following Helm value:


`args.feature-gates=CloudControllerManagerWatchBasedRoutesReconciliation=false`

### Global Load Balancer Defaults

Configure cluster-wide defaults for Load Balancers via the extended
`HCLOUD_LOAD_BALANCERS_*` env vars. These values automatically apply
during Load Balancer creation and reconciliation whenever annotations
are omitted. Learn more about it in the [reference
documentation](docs/reference/load_balancer_envs.md)

### Features

- extend environment variables for default load balancer configuration
(#1052)
- enable watch based route reconciliation by default (#1112)
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.

3 participants