Dynamic Ipv6 Prefix support for MetalLB
This repository has been archived on 2025-10-26. You can view files and clone it, but you cannot make any changes to its state, such as pushing and creating new issues, pull requests or comments.
Find a file
2025-10-19 19:56:40 +02:00
.github Update actions/download-artifact action to v5 (#76) 2025-08-08 16:52:23 +02:00
crates Update Rust crate jsonschema to 0.33.0 2025-08-25 01:11:38 +00:00
.gitignore perform chart-releaser upload manually 2023-09-05 19:40:30 +02:00
.pre-commit-config.yaml Update pre-commit hook pre-commit/pre-commit-hooks to v5 (#62) 2025-01-14 12:23:54 +01:00
Cargo.lock Update Rust crate tokio to v1.48.0 2025-10-15 02:45:56 +00:00
Cargo.toml Update app version to 0.1.2 (#18) 2023-10-24 12:41:54 +02:00
Dockerfile move to just instead of cargo-make (#68) 2025-05-17 22:51:53 +02:00
Dockerfile.multiarch move to just instead of cargo-make (#68) 2025-05-17 22:51:53 +02:00
Justfile update justfile and CI 2025-08-08 16:29:53 +02:00
LICENSE cleanup repository 2023-08-30 01:03:56 +02:00
README.md Update README.md (#82) 2025-10-19 19:56:40 +02:00

metallb-dyn6

NOTE: This project has been archived and will not be developed further. Recommended replacement: Use externalip-manager in combination with NPTv6 and a ULA for MetalLB, then use the "merge" solver to map the ULA to your public prefix.

Dynamic IPv6 Prefix support for MetalLB.

This utility enables MetalLB to manage an IPv6 address pool with a dynamically changing prefix. It synchronizes the network part of an Ipv6 Address Range in a MetalLB IPAddressPool with a dynamically retrieved Ipv6 network. It ensures that the address range in the pool always corresponds to the currently assigned network and automatically reloads MetaLLB when required.

Use Case & Concepts

The main use case for this tool is running an Ipv6-enabled k8s cluster from a residential ISP connection with no static Ipv6 Prefix.

Consider the following situation: You want to host an IPv6-enabled k8s cluster and have gotten an Ipv6 prefix from your ISP, say 2001:db8:aaaa::/48. To make your cluster-hosted services accessible from the internet, you'd assign them addresses from within that prefix (and setup your router, but that's outside the scope of this README). For example, your IPAddressPool could look like this:

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  namespace: metallb-system
spec:
  addresses:
    # Some private IPv4 addresses
    - 10.10.1.10-10.10.1.99
    # A range from within your ISP-assigned Prefix
    - 2001:db8:aaaa::1000-2001:db8:aaaa::1999

This works great, as long as the prefix assigned to you is static - that is, it does not change.

However, many consumer ISPs regularly change the assigned prefix (for example when the connection gets interrupted). This means that after a power outage, your assigned prefix might suddenly be 2001:db8:ffff::/48, resulting in an incorrect MetalLB configuration and thus no internet access.

Unfortunately, as IPAddressPool resources are static, MetalLB has no native way to address this. This is where metallb-dyn6 comes in.

metallb-dyn6 addresses this issue by listening to changes in the prefix, replacing the range in the IPAddressPool with one based on the new prefix whenever a change occurs. It does this by performing the following actions:

  1. First, it queries a source for the IPv6 prefix, which simply tells metallb-dyn6 what prefix to use. Right now, the only available source is my-ip, which queries the MyIP API for your current public IPV6 address.
    • metallb-dyn6s design is modular, so more sources can easily be added in the future.
  2. It then compares the Prefix stored in the IPAddresspool with the one retrieved from the source. If there is a mismatch, it updates the IPAddressPool to match the prefix retrieved from the source.
  3. Finally, it forces MetalLB to accept this new configuration by deleting all of its pods and waiting for them to be recreated (this is the officially recommended way to do this).

Installation

The officially recommanded way to install metallb-dyn6 is through Helm.

First, install the repository like so:

helm repo add spacebird https://charts.spacebird.dev

Then, install the chart:

helm install metallb-dyn6 spacebird/metallb-dyn6 \
  --namespace metallb-system
  --set "metallb.hostRange=::1000-::1999"
  --set "metallb.pool=my-ipaddress-pool-name"

⚠️ IMPORTANT NOTES ⚠️

  • You must install metallb-dyn6 into the same namespace as your metallb installation.
  • The parameters metallb.hostRange and metallb.pool are required.
  • metallb.hostRange must be a dash-separated range - it cannot be a /xx CIDR-style range.
  • To see the minimum supported k8s version, check the k8s-openapi feature flag in crates/cli/Cargo.toml

For a full list of possible values, please see the Helm chart docs

Subnet override

Sometimes, the IPv6 network returned from the source may not have the correct subnet applied. For example, you may have a separate subnet configured for just your k8s cluster services traffic that you'd like MetalLB to use.

In those cases, you can override parts of the returned network with the subnetOverride values. For example, to always override the last 8 bits of the network with cd:, you would supply the following values:

dyn6:
  subnetOverride:
    enabled: true
    prefixLen: 56 # how many of the original network bits to keep
    override: "0:0:0:00cd::" # note the leading zeros - they are required

Development

This tool is built in Rust, using standard cargo tooling. You may want to install the just command runner to run the recipes in the Justfile. cross is used for cross-compilation.

Release Management

Draft Releases are automatically managed through the version-maintenance workflow. Follow the instructions in those drafts to publish a new release.