Rancher Waiting for at least one control plane, etcd, and worker node to be registered

I’m using Rancher with rke2r1 on my lab (vsphere) and I’m trying to create new K8s cluster with separated machine pool. In default mode I must select all 3 roles (etcd, control plane, worker) to have working cluster. But to have something for production I decided to have different pool of machine for each role.

  • 1 pool with 3 nodes with role etcd and control plane

  • 1 pool with 3 nodes with role worker

Here yaml file before creating pool of etdc and control plane nodes

apiVersion: provisioning.cattle.io/v1
kind: Cluster
metadata:
  name: test
  annotations:
    {}
    #  key: string
  labels:
    {}
    #  key: string
  namespace: fleet-default
spec:
  cloudCredentialSecretName: cattle-global-data:cc-jncqg
  clusterAgentDeploymentCustomization:
    appendTolerations:
#      - effect: string
#        key: string
#        operator: string
#        tolerationSeconds: int
#        value: string
    overrideAffinity:
#      nodeAffinity:
#        preferredDuringSchedulingIgnoredDuringExecution:
#          - preference:
#              matchExpressions:
#                - key: string
#                  operator: string
#                  values:
#                    - string
#              matchFields:
#                - key: string
#                  operator: string
#                  values:
#                    - string
#            weight: int
#        requiredDuringSchedulingIgnoredDuringExecution:
#          nodeSelectorTerms:
#            - matchExpressions:
#                - key: string
#                  operator: string
#                  values:
#                    - string
#              matchFields:
#                - key: string
#                  operator: string
#                  values:
#                    - string
#      podAffinity:
#        preferredDuringSchedulingIgnoredDuringExecution:
#          - podAffinityTerm:
#              labelSelector:
#                matchExpressions:
#                  - key: string
#                    operator: string
#                    values:
#                      - string
#                matchLabels:  key: string
#              matchLabelKeys:
#                - string
#              mismatchLabelKeys:
#                - string
#              namespaceSelector:
#                matchExpressions:
#                  - key: string
#                    operator: string
#                    values:
#                      - string
#                matchLabels:  key: string
#              namespaces:
#                - string
#              topologyKey: string
#            weight: int
#        requiredDuringSchedulingIgnoredDuringExecution:
#          - labelSelector:
#              matchExpressions:
#                - key: string
#                  operator: string
#                  values:
#                    - string
#              matchLabels:  key: string
#            matchLabelKeys:
#              - string
#            mismatchLabelKeys:
#              - string
#            namespaceSelector:
#              matchExpressions:
#                - key: string
#                  operator: string
#                  values:
#                    - string
#              matchLabels:  key: string
#            namespaces:
#              - string
#            topologyKey: string
#      podAntiAffinity:
#        preferredDuringSchedulingIgnoredDuringExecution:
#          - podAffinityTerm:
#              labelSelector:
#                matchExpressions:
#                  - key: string
#                    operator: string
#                    values:
#                      - string
#                matchLabels:  key: string
#              matchLabelKeys:
#                - string
#              mismatchLabelKeys:
#                - string
#              namespaceSelector:
#                matchExpressions:
#                  - key: string
#                    operator: string
#                    values:
#                      - string
#                matchLabels:  key: string
#              namespaces:
#                - string
#              topologyKey: string
#            weight: int
#        requiredDuringSchedulingIgnoredDuringExecution:
#          - labelSelector:
#              matchExpressions:
#                - key: string
#                  operator: string
#                  values:
#                    - string
#              matchLabels:  key: string
#            matchLabelKeys:
#              - string
#            mismatchLabelKeys:
#              - string
#            namespaceSelector:
#              matchExpressions:
#                - key: string
#                  operator: string
#                  values:
#                    - string
#              matchLabels:  key: string
#            namespaces:
#              - string
#            topologyKey: string
    overrideResourceRequirements:
#      claims:
#        - name: string
#          request: string
#      limits:  key: string
#      requests:  key: string
#    schedulingCustomization:
#      podDisruptionBudget:
#        maxUnavailable: string
#        minAvailable: string
#      priorityClass:
#        preemptionPolicy: string
#        value: int
  defaultPodSecurityAdmissionConfigurationTemplateName: ''
  fleetAgentDeploymentCustomization:
    appendTolerations:
#      - effect: string
#        key: string
#        operator: string
#        tolerationSeconds: int
#        value: string
    overrideAffinity:
#      nodeAffinity:
#        preferredDuringSchedulingIgnoredDuringExecution:
#          - preference:
#              matchExpressions:
#                - key: string
#                  operator: string
#                  values:
#                    - string
#              matchFields:
#                - key: string
#                  operator: string
#                  values:
#                    - string
#            weight: int
#        requiredDuringSchedulingIgnoredDuringExecution:
#          nodeSelectorTerms:
#            - matchExpressions:
#                - key: string
#                  operator: string
#                  values:
#                    - string
#              matchFields:
#                - key: string
#                  operator: string
#                  values:
#                    - string
#      podAffinity:
#        preferredDuringSchedulingIgnoredDuringExecution:
#          - podAffinityTerm:
#              labelSelector:
#                matchExpressions:
#                  - key: string
#                    operator: string
#                    values:
#                      - string
#                matchLabels:  key: string
#              matchLabelKeys:
#                - string
#              mismatchLabelKeys:
#                - string
#              namespaceSelector:
#                matchExpressions:
#                  - key: string
#                    operator: string
#                    values:
#                      - string
#                matchLabels:  key: string
#              namespaces:
#                - string
#              topologyKey: string
#            weight: int
#        requiredDuringSchedulingIgnoredDuringExecution:
#          - labelSelector:
#              matchExpressions:
#                - key: string
#                  operator: string
#                  values:
#                    - string
#              matchLabels:  key: string
#            matchLabelKeys:
#              - string
#            mismatchLabelKeys:
#              - string
#            namespaceSelector:
#              matchExpressions:
#                - key: string
#                  operator: string
#                  values:
#                    - string
#              matchLabels:  key: string
#            namespaces:
#              - string
#            topologyKey: string
#      podAntiAffinity:
#        preferredDuringSchedulingIgnoredDuringExecution:
#          - podAffinityTerm:
#              labelSelector:
#                matchExpressions:
#                  - key: string
#                    operator: string
#                    values:
#                      - string
#                matchLabels:  key: string
#              matchLabelKeys:
#                - string
#              mismatchLabelKeys:
#                - string
#              namespaceSelector:
#                matchExpressions:
#                  - key: string
#                    operator: string
#                    values:
#                      - string
#                matchLabels:  key: string
#              namespaces:
#                - string
#              topologyKey: string
#            weight: int
#        requiredDuringSchedulingIgnoredDuringExecution:
#          - labelSelector:
#              matchExpressions:
#                - key: string
#                  operator: string
#                  values:
#                    - string
#              matchLabels:  key: string
#            matchLabelKeys:
#              - string
#            mismatchLabelKeys:
#              - string
#            namespaceSelector:
#              matchExpressions:
#                - key: string
#                  operator: string
#                  values:
#                    - string
#              matchLabels:  key: string
#            namespaces:
#              - string
#            topologyKey: string
    overrideResourceRequirements:
#      claims:
#        - name: string
#          request: string
#      limits:  key: string
#      requests:  key: string
#    schedulingCustomization:
#      podDisruptionBudget:
#        maxUnavailable: string
#        minAvailable: string
#      priorityClass:
#        preemptionPolicy: string
#        value: int
  kubernetesVersion: v1.32.7+rke2r1
  localClusterAuthEndpoint:
    enabled: false
#    caCerts: string
#    fqdn: string
  rkeConfig:
    chartValues:
      rke2-calico: {}
        
    dataDirectories:
      k8sDistro: ''
      provisioning: ''
      systemAgent: ''
    etcd:
      disableSnapshots: false
      snapshotRetention: 5
      snapshotScheduleCron: 0 */5 * * *
#      s3:
#        bucket: string
#        cloudCredentialName: string
#        endpoint: string
#        endpointCA: string
#        folder: string
#        region: string
#        skipSSLVerify: boolean
    machineGlobalConfig:
      cni: calico
      disable-kube-proxy: false
      etcd-expose-metrics: false
        
    machinePools:
      - name: pool1
        etcdRole: true
        controlPlaneRole: true
        workerRole: false
        hostnamePrefix: ''
        quantity: 3
        unhealthyNodeTimeout: 0m
        machineConfigRef:
          kind: VmwarevsphereConfig
          name: nc-test-pool1-wwccb
        drainBeforeDelete: true
        machineOS: linux
        labels: {}
#      - cloudCredentialSecretName: string
#        controlPlaneRole: boolean
#        displayName: string
#        drainBeforeDelete: boolean
#        drainBeforeDeleteTimeout: string
#        dynamicSchemaSpec: string
#        etcdRole: boolean
#        hostnameLengthLimit: int
#        labels:  key: string
#        machineConfigRef:
#          apiVersion: string
#          fieldPath: string
#          kind: string
#          name: string
#          namespace: string
#          resourceVersion: string
#          uid: string
#        machineDeploymentAnnotations:  key: string
#        machineDeploymentLabels:  key: string
#        machineOS: string
#        maxUnhealthy: string
#        name: string
#        nodeStartupTimeout: string
#        paused: boolean
#        quantity: int
#        rollingUpdate:
#          maxSurge: 
#          maxUnavailable:
#        taints:
#          - effect: string
#            key: string
#            timeAdded: string
#            value: string
#        unhealthyNodeTimeout: string
#        unhealthyRange: string
#        workerRole: boolean
    machineSelectorConfig:
      - config:
          protect-kernel-defaults: false
#      - config:  
#        machineLabelSelector:
#          matchExpressions:
#            - key: string
#              operator: string
#              values:
#                - string
#          matchLabels:  key: string
    registries:
      configs:
        {}
        #  authConfigSecretName: string
#        caBundle: string
#        insecureSkipVerify: boolean
#        tlsSecretName: string
      mirrors:
        {}
        #  endpoint:
#          - string
#        rewrite:  key: string
    upgradeStrategy:
      controlPlaneConcurrency: '1'
      controlPlaneDrainOptions:
        deleteEmptyDirData: true
        disableEviction: false
        enabled: false
        force: false
        gracePeriod: -1
        ignoreDaemonSets: true
        skipWaitForDeleteTimeoutSeconds: 0
        timeout: 120
#        ignoreErrors: boolean
#        postDrainHooks:
#          - annotation: string
#        preDrainHooks:
#          - annotation: string
      workerConcurrency: '1'
      workerDrainOptions:
        deleteEmptyDirData: true
        disableEviction: false
        enabled: false
        force: false
        gracePeriod: -1
        ignoreDaemonSets: true
        skipWaitForDeleteTimeoutSeconds: 0
        timeout: 120
#        ignoreErrors: boolean
#        postDrainHooks:
#          - annotation: string
#        preDrainHooks:
#          - annotation: string
#    additionalManifest: string
#    etcdSnapshotCreate:
#      generation: int
#    etcdSnapshotRestore:
#      generation: int
#      name: string
#      restoreRKEConfig: string
#    infrastructureRef:
#      apiVersion: string
#      fieldPath: string
#      kind: string
#      name: string
#      namespace: string
#      resourceVersion: string
#      uid: string
#    machinePoolDefaults:
#      hostnameLengthLimit: int
#    machineSelectorFiles:
#      - fileSources:
#          - configMap:
#              defaultPermissions: string
#              items:
#                - dynamic: boolean
#                  hash: string
#                  key: string
#                  path: string
#                  permissions: string
#              name: string
#            secret:
#              defaultPermissions: string
#              items:
#                - dynamic: boolean
#                  hash: string
#                  key: string
#                  path: string
#                  permissions: string
#              name: string
#        machineLabelSelector:
#          matchExpressions:
#            - key: string
#              operator: string
#              values:
#                - string
#          matchLabels:  key: string
#    networking:
#      stackPreference: string
#    provisionGeneration: int
#    rotateCertificates:
#      generation: int
#      services:
#        - string
#    rotateEncryptionKeys:
#      generation: int
  machineSelectorConfig:
    - config: {}
#  agentEnvVars:
#    - name: string
#      value: string
#  clusterAPIConfig:
#    clusterName: string
#  defaultClusterRoleForProjectMembers: string
#  enableNetworkPolicy: boolean
#  redeploySystemAgentGeneration: int
__clone: true

Both of pool are in same state

Waiting for at least one control plane, etcd, and worker node to be registered

Do I forgot something ?

I just added this in my controlplane yaml file before creating my cluster.

  • name: pool2
    etcdRole: false
    controlPlaneRole: false
    workerRole: true
    hostnamePrefix: ‘’
    quantity: 2
    unhealthyNodeTimeout: 0m
    machineConfigRef:
    kind: VmwarevsphereConfig
    name: nc-worker-pool2-2wxps
    drainBeforeDelete: true
    machineOS: linux
    labels: {}

Aye,

The screenshot you sent in the first part of the message shows that you created two separate clusters, not one with two pools.

Now each cluster is waiting for the required number of machines in the appropriate role (etcdRole: true, controlPlaneRole: true, workerRole: false)(etcdRole: false, controlPlaneRole: false, workerRole: true).

You should correct your configuration.

Cheers,
R2

1 Like

Thanks you. Yes i’m newbies do you have some good documentation what I can use to learn about rancher or rke2 ? Official doc don’t speak about this type of configuration, so I passed long time on my issue.

Try starting with this:

I agree, these are not trivial topics.
Try setting up a cluster with a single pool and all roles first, and then expand the configuration with additional dedicated pools.
Then, if you feel like it, you can dive deeper :slight_smile: into cluster templates: https://github.com/r2d2pl/rancher-cluster-templates