Skip to content

Clarify preferred providerID initialization in CAPO clusters #3042

@patrostkowski

Description

@patrostkowski

/kind feature

Describe the solution you'd like

Currently the documentation suggests deploying the OpenStack Cloud Controller Manager after the control plane is ready, which then populates Node.spec.providerID.

However, it is also possible to set the provider ID directly during node bootstrap via kubelet arguments. For example, using instance metadata exposed by OpenStack through cloud-init:

apiVersion: bootstrap.cluster.x-k8s.io/v1beta2
kind: KubeadmConfigTemplate
metadata:
  name: ${CLUSTER_NAME}-md-0
spec:
  template:
    spec:
      joinConfiguration:
        nodeRegistration:
          name: '{{ local_hostname }}'
          kubeletExtraArgs:
            cloud-provider: external
            provider-id: openstack:///'{{ instance_id }}'

With this approach the node registers with Kubernetes with providerID already set, which allows the cluster to start without requiring OCCM during bootstrap.

In practice this also affects Cluster API reconciliation. When provider-id is provided via kubelet arguments, the node registers with spec.providerID already populated and the Machine/MachineSet reconciliation completes successfully.

If provider-id is not set and OCCM is not deployed, the cluster can still create the underlying OpenStack resources (e.g. OpenStackMachine and the VM instance), but reconciliation does not fully complete because the Kubernetes Node never receives a providerID. In this state the cluster remains partially reconciled even though the VM and Kubernetes node exist.

The question is which model CAPO considers the preferred or supported approach:

  1. OCCM-driven initialization
  • kubelet runs with --cloud-provider=external
  • nodes register without providerID
  • OCCM populates Node.spec.providerID
  1. Bootstrap-driven initialization
  • kubelet runs with --cloud-provider=external
  • kubelet receives --provider-id from cloud-init metadata
  • nodes register with providerID already set
  • OCCM may still be deployed later if cloud features (e.g. LoadBalancer services) are required

It would be helpful if the documentation clarified whether pre-populating providerID during bootstrap is a supported pattern, or whether OCCM is expected to always be responsible for setting it.

Anything else you would like to add:

The bootstrap-driven approach can simplify cluster bring-up because it removes the dependency on deploying OCCM just to populate providerID. The cluster can start normally, and OCCM can be installed later if cloud-specific functionality (e.g. Octavia load balancers, node address management, or cloud node lifecycle handling) is needed.

Clarifying the recommended pattern in the CAPO documentation would help operators understand whether both approaches are supported or if OCCM-based initialization is the intended design.

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind/featureCategorizes issue or PR as related to a new feature.

    Type

    No type

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions