Skip to content
44 changes: 44 additions & 0 deletions docs/loadbalancer-annotations.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,50 @@ The possible formats are:
- `<pn-id>`: will attach a single Private Network to the LB.
- `<pn-id>,<pn-id>`: will attach the two Private Networks to the LB.

### `service.beta.kubernetes.io/scw-loadbalancer-pn-names`

> **Feature gate:** This annotation requires the `SCW_ENABLE_LB_PN_NAME_SELECTOR` environment variable
> to be set to `"true"` on the cloud controller manager. When the environment variable is not set or set
> to any other value, this annotation is ignored.

This is the annotation to configure the Private Networks by name instead of ID.
The private network names will be resolved to IDs at runtime. This is useful when
you want to specify private networks without hardcoding their IDs, which can change
when clusters are recreated.

When enabled, IPAM-based node IP resolution is also activated, providing precise IP
lookup for nodes connected to the configured private networks.

**Priority order:**
1. `service.beta.kubernetes.io/scw-loadbalancer-pn-ids` (highest priority)
2. `service.beta.kubernetes.io/scw-loadbalancer-pn-names` (requires `SCW_ENABLE_LB_PN_NAME_SELECTOR=true`)
3. `PN_ID` environment variable (fallback)

If both `pn-ids` and `pn-names` are set, `pn-ids` takes precedence and `pn-names` is ignored.
This annotation is ignored when `service.beta.kubernetes.io/scw-loadbalancer-externally-managed` is enabled.

The format must be `<vpc-name>/<pn-name>` to specify both the VPC and the private network name.
Multiple entries can be comma-separated.

**Examples:**
```yaml
# Single private network
service.beta.kubernetes.io/scw-loadbalancer-pn-names: "default/my-private-network"

# Multiple networks from different VPCs
service.beta.kubernetes.io/scw-loadbalancer-pn-names: "prod-vpc/network-1,staging-vpc/network-2"

# Multiple networks from the same VPC
service.beta.kubernetes.io/scw-loadbalancer-pn-names: "default/network-1,default/network-2"
```

**Error handling:**
- If the format is invalid (missing VPC or PN name), an error is returned.
- If a private network name is not found, an error is returned.
- If multiple private networks have the same name within the VPC, an error is returned.
- If the specified VPC is not found, an error is returned.
- If multiple VPCs have the same name, an error is returned.

### `service.beta.kubernetes.io/scw-loadbalancer-health-check-from-service`

This is the annotation to configure the load balancer backend to use the service's `healthCheckNodePort` for health checks.
Expand Down
2 changes: 1 addition & 1 deletion examples/k8s-scaleway-ccm-latest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ spec:
effect: NoSchedule
containers:
- name: scaleway-cloud-controller-manager
image: scaleway/scaleway-cloud-controller-manager:latest
image: ghcr.io/kommodity-io/scaleway-cloud-controller-manager:v0.36.0-kommodity.11
imagePullPolicy: Always
args:
- --cloud-provider=scaleway
Expand Down
5 changes: 5 additions & 0 deletions scaleway/cloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ const (
loadBalancerDefaultTypeEnv = "LB_DEFAULT_TYPE"

privateNetworkID = "PN_ID"

// enableLBPNNameSelectorEnv enables the selector-style annotation for LB to VPC/PN association.
// When set to "true", the pn-names annotation and IPAM-based node IP resolution are enabled.
// This feature is gated because it can cause issues on the Scaleway backend at scale.
enableLBPNNameSelectorEnv = "SCW_ENABLE_LB_PN_NAME_SELECTOR"
)

type cloud struct {
Expand Down
18 changes: 11 additions & 7 deletions scaleway/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,17 @@ package scaleway
import "errors"

var (
BadProviderID = errors.New("provider ID wrong format: format should be scaleway://product/region/0788e6f4-55b0-42e2-936f-d0c5ecd49a13")
InstanceDuplicated = errors.New("duplicated instance results")
IPAddressNotFound = errors.New("ip address not found")
IPAddressInUse = errors.New("ip address already in use")
LoadBalancerNotFound = errors.New("loadbalancer not found")
LoadBalancerDuplicated = errors.New("loadbalancer duplicated")
LoadBalancerNotReady = errors.New("loadbalancer is not ready")
BadProviderID = errors.New("provider ID wrong format: format should be scaleway://product/region/0788e6f4-55b0-42e2-936f-d0c5ecd49a13")
InstanceDuplicated = errors.New("duplicated instance results")
IPAddressNotFound = errors.New("ip address not found")
IPAddressInUse = errors.New("ip address already in use")
LoadBalancerNotFound = errors.New("loadbalancer not found")
LoadBalancerDuplicated = errors.New("loadbalancer duplicated")
LoadBalancerNotReady = errors.New("loadbalancer is not ready")
PrivateNetworkNotFound = errors.New("private network not found")
PrivateNetworkDuplicated = errors.New("multiple private networks found with same name")
VPCNotFound = errors.New("VPC not found")
VPCDuplicated = errors.New("multiple VPCs found with same name")

errLoadBalancerInvalidAnnotation = errors.New("load balancer invalid annotation")
errLoadBalancerInvalidLoadBalancerID = errors.New("load balancer invalid loadbalancer-id annotation")
Expand Down
Loading