Skip to content

feat(lb): prefix default balancer names with an optional cluster name - #68

Open
lexfrei wants to merge 1 commit into
fix/validate-balancer-namefrom
feat/cluster-name-prefix
Open

lexfrei wants to merge 1 commit into
fix/validate-balancer-namefrom
feat/cluster-name-prefix

Conversation

@lexfrei

@lexfrei lexfrei commented Sep 29, 2026

Copy link
Copy Markdown
Collaborator

Two clusters that run robotlb in one Hetzner project give the same default name to balancers of services with the same name and namespace. This adds an optional cluster name that goes in front of the default name, so each cluster gets its own.

The setting is --cluster-name, or ROBOTLB_CLUSTER_NAME. It must be a DNS label: 1 to 63 lowercase letters, digits or -, with a letter or digit at both ends. The operator checks it at startup and stops with an error that names the rule. An empty value, for example ROBOTLB_CLUSTER_NAME: "" in the chart values, is rejected the same way; to go without a cluster name, leave the variable out. With it set, the default name is <cluster>.<service>.<namespace>. Without it nothing changes and the name stays <service>.<namespace>.

Three labels can be up to 191 characters long, and Hetzner takes 128. A longer name is cut to 111 characters and gets - plus a 16-digit hex FNV-1a 64 hash of the whole name, so two long names that share the first part still differ. Balancers are looked up by this name, so the hash has to stay the same between releases. That's why it is a few lines of inline code pinned by test vectors, and not std's hasher, which gives no such promise.

A name from the robotlb/balancer annotation is used as it is, without the prefix or the hash.

Existing balancers are not renamed. find_hcloud_lb looks for a balancer by the robotlb/service-uid label first and only falls back to names when none has it. Every balancer created or adopted by the base branch carries that label. So turning the cluster name on later neither renames nor orphans them. The legacy name of older releases is still tried as before.

Tested with cargo test, cargo clippy --all-targets (no new warnings) and helm lint helm/. The tests pin the name with and without a cluster name, names of exactly 128 and 129 characters, a 63+63+63 name cut to 128 that still passes validate_name, two long names that differ only after the cut, the hash values, an annotated name left alone, and the rejected cluster names: uppercase, a dot, - at either end, underscore, non-ASCII, 64 characters, empty. I broke the code on purpose for each of these and the matching test failed. README and helm/values.yaml document the option.

Stacked on #67.

Closes #63

Two clusters running robotlb in one Hetzner project pick the same
default name for services with the same name and namespace, and the
second one then finds a balancer that is not its own.

The new ROBOTLB_CLUSTER_NAME setting puts the cluster in front of the
default name. It is checked at startup as a DNS label, so it holds no
dot and the full names of different clusters differ. With three
labels the name can pass the 128 characters Hetzner allows; such a
name is cut and ends in a 64-bit FNV-1a hash of the whole name, so
long names that share the kept part still differ. The hash stays the
same across releases, as balancers are looked up by name. Names from
the balancer annotation are used as given. Unset, names stay as they
were.

Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <f@lex.la>
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.

1 participant