Service-LB broken out of the box: manager never injects vco-lb-credential (+ undocumented CRS apply, :latest image pin)
Following the getting-started "Expose it to the internet" step, a Service type=LoadBalancer never gets an external IP. Three stacked problems; the middle one is a real provider bug.
1. Docs gap — the service-lb add-on CRS apply is undocumented
docs/guides/load-balancing.md explains the two modes and "Using it" but never tells you to apply the service-lb add-on to the management cluster (no CRS apply, no mention of the management cluster) — the same omission the CNI step avoids in install-provider. So the vcolb controller is never delivered. Applying it manually fixes that part:
kubectl --context <mgmt> apply -f https://gitlab.whitesky.cloud/api/v4/projects/730/packages/generic/capvco/<version>/service-lb.yaml
2. Bug: the manager never injects vco-lb-credential (the blocker)
Even with the CRS applied and the Cluster correctly labeled capvco.infrastructure.cluster.x-k8s.io/service-lb: vco, vcolb crash-loops:
Error: secret "vco-lb-credential" not found (x8)
vcolb reads VCO_PORTAL_URL/VCO_IAM_REFRESH_URL/VCO_CUSTOMER_ID/VCO_JWT from vco-lb-credential via envFrom (cmd/vcolb/main.go), and the manager is supposed to inject that Secret — the code exists and is wired:
-
controllers/service_lb_credential.goreconcileServiceLBCredential(createscapvco-system/vco-lb-credentialwith exactly those keys), - called at
controllers/vcocluster_controller.go:330underif wantsVCOWorkloadCredential(cluster), which returns true forservice-lb: vco.
But on the running v0.2.1 manager it never fires — the manager logs zero service-LB activity (no "Injected service-LB credential", no "Waiting for workload kubeconfig…", no error), while the CSI credential injection in the block immediately above (csi_credential.go, line 322) logs and succeeds on the same cluster. CSI returns a zero result on success, so control flow should reach line 330 — yet the service-LB path is silently skipped. Needs root-causing (why reconcileServiceLBCredential isn't reached/effective when service-lb: vco is set, despite CSI injecting fine).
Net effect: the standalone Service-LB add-on — the documented "recommended default" — does not work out of the box. (The CCM path shares the same injected secret, so it's likely affected too.)
Confirmed workaround (validated live)
Manually create the secret the manager should have injected, then restart vcolb:
kubectl -n capvco-system create secret generic vco-lb-credential \
--from-literal=VCO_PORTAL_URL=<portal> --from-literal=VCO_IAM_REFRESH_URL=<iam> \
--from-literal=VCO_CUSTOMER_ID=<cid> --from-literal=VCO_JWT=<jwt> # (workload cluster)
kubectl -n capvco-system rollout restart deploy/vcolb
→ vcolb logged Created service LB … ip 185.69.165.31, the Service got its EXTERNAL-IP, and curl http://185.69.165.31/hostname returned the serving pod. So everything downstream works once the credential exists.
3. Minor: the add-on bundle pins vcolb to :latest
config/addons/service-lb/service-lb.yaml (and ccm) reference ghub.gig.tech/whitesky-oss/cluster-api-provider-vco:**latest**, not the release tag. make release-manifests rewrites the manager image to the release tag but not the add-on images → a v0.2.1 release's vcolb pulls :latest (mutable, non-reproducible). Pin add-on images to the release tag too.
Acceptance
Following the load-balancing guide (with a documented one-time CRS apply): a Service type=LoadBalancer gets an external IP with no manual secret creation — the manager injects vco-lb-credential for the service-lb: vco (and ccm) path — and add-on images are pinned to the release tag.
Related: #14 (closed) (addon delivery/docs), #21 (closed) (CSI credential injection — the pattern that does work), #17 (closed) (the getting-started e2e must cover this optional step).