You can define a ClusterTemplate CR with multiple node groups in the hwMgmtDefaults.nodeGroupData[] field when your cluster topology includes multiple groups of nodes, such as control plane and worker nodes. Each node group can define its own role, hardware profile, and resource selectors, to enable the O-Cloud Manager to allocate hardware independently for each group.
A ClusterTemplate CR references ConfigMap resources that contain defaults for cluster installation and Day 2 policy configuration. The ConfigMap CR for cluster installation defaults defines the common configuration across all clusters provisioned with a template, including cluster-level settings and the shared node configuration for each node group.
When a site engineer creates a ProvisioningRequest resource, the O-Cloud Manager merges the site-specific parameters from the request with these defaults to produce the final cluster and policy definitions.
Prerequisites
-
The O-Cloud Manager Operator is installed on the hub cluster.
-
The GitOps repository is configured and synchronized with ArgoCD.
-
Bare-metal servers are onboarded to resource pools with appropriate resource selector labels.
-
If firmware or BIOS management is required, HardwareProfile resources are defined.
Procedure
-
Create a ConfigMap CR that defines the cluster installation defaults for a multi-node topology. The ConfigMap CR must include a nodeGroup entry for each node role. The following example defines master and worker groups with distinct network interface configurations:
apiVersion: v1
kind: ConfigMap
metadata:
name: clusterinstance-defaults-v1
namespace: <template_namespace>
data:
clusterinstance-defaults: |
baseDomain: example.com
extraLabels:
ManagedCluster:
cluster-version: "v4-Y-Z"
std-ran-du-policy: "v1"
clusterType: HighlyAvailable
clusterImageSetNameRef: "4.Y.Z"
pullSecretRef:
name: pull-secret
networkType: OVNKubernetes
clusterNetwork:
- cidr: 203.0.113.0/24
hostPrefix: 25
serviceNetwork:
- cidr: 198.51.100.0/24
additionalNTPSources:
- 1.pool.ntp.org
templateRefs:
- name: ai-cluster-templates-v1
namespace: open-cluster-management
cpuPartitioningMode: AllNodes
extraManifestsRefs:
- name: std-ran-du-extra-manifest-v1
nodeGroups:
- name: master
role: master
bootMode: UEFI
ironicInspect: "disabled"
automatedCleaningMode: disabled
rootDeviceHints:
deviceName: /dev/disk/by-path/pci-0000:01:00.0-nvme-1
nodeNetwork:
interfaces:
- name: ens1f0
label: boot-interface
- name: ens1f1
label: data-interface
config:
routes:
config:
- destination: 0.0.0.0/0
next-hop-interface: ens1f0
table-id: 254
interfaces:
- ipv6:
enabled: false
ipv4:
enabled: true
name: ens1f0
state: up
type: ethernet
templateRefs:
- name: ai-node-templates-v1
namespace: open-cluster-management
- name: worker
role: worker
bootMode: UEFI
ironicInspect: "disabled"
automatedCleaningMode: disabled
rootDeviceHints:
deviceName: /dev/disk/by-path/pci-0000:01:00.0-nvme-1
nodeNetwork:
interfaces:
- name: ens3f0
label: boot-interface
- name: ens3f1
label: data-interface
- name: ens2f0
label: sriov-1
- name: ens2f1
label: sriov-2
config:
routes:
config:
- destination: 0.0.0.0/0
next-hop-interface: ens3f0
table-id: 254
interfaces:
- ipv6:
enabled: false
ipv4:
enabled: true
name: ens3f0
state: up
type: ethernet
templateRefs:
- name: ai-node-templates-v1
namespace: open-cluster-management
extraLabels.ManagedCluster
-
The cluster-version label is mandatory. This label, along with any additional custom labels such as std-ran-du-policy, is used to bind Red Hat Advanced Cluster Management (RHACM) policies for cluster configuration rendered from the PolicyGenerator manifest.
nodeGroups[].name
-
Must match hwMgmtDefaults.nodeGroupData[].name in the ClusterTemplate CR and the MachineConfigPool name on the managed cluster. Define one entry for each hardware node group.
-
Create a ConfigMap CR containing default values for Day 2 configuration policy parameters, such as the following example:
apiVersion: v1
kind: ConfigMap
metadata:
name: policytemplates-defaults-v1
namespace: <template_namespace>
data:
policytemplate-defaults: |
sriov-network-vlan-1: "140"
sriov-network-pfNames-1: '["ens2f0"]'
sriov-network-vlan-2: "150"
sriov-network-pfNames-2: '["ens2f1"]'
cpu-isolated: "0-1,64-65"
cpu-reserved: "2-10"
hugepages-default: "1G"
hugepages-size: "1G"
hugepages-count: "32"
install-plan-approval: "Automatic"
The ConfigMap CR must contain a policytemplate-defaults key. The value is a YAML string defining the default policy parameters. Site-specific values from the ProvisioningRequest CR take precedence over these defaults when both specify the same parameter. All parameters referenced as placeholders in the PolicyGenerator manifest must be declared here or supplied through the ProvisioningRequest CR.
-
Create an RHACM PolicyGenerator manifest, such as the following example, that defines the Day 2 configuration policies for clusters provisioned with this ClusterTemplate CR:
|
|
The PolicyGenerator CR is the mechanism that turns policy defaults into enforceable policies on managed clusters. When a ProvisioningRequest CR is created, the O-Cloud Manager creates a ConfigMap CR named <cluster-name>-pg on the hub cluster, populated by merging the values from the policy defaults ConfigMap with any overrides from the ProvisioningRequest CR.
The PolicyGenerator CR uses templating expressions ({{hub … hub}}) as placeholders that RHACM resolves at runtime by reading values from this <cluster-name>-pg ConfigMap CR. The result is Policy CRs that RHACM enforces on the managed cluster.
|
apiVersion: policy.open-cluster-management.io/v1
kind: PolicyGenerator
metadata:
name: std-ran-du-pg-v4-Y-Z-v1
policyDefaults:
namespace: ztp-<template_namespace>
placement:
labelSelector:
cluster-version: "v4-Y-Z"
std-ran-du-policy: "v1"
policyAnnotations:
clustertemplates.clcm.openshift.io/templates: "std-ran-du.v4-Y-Z-1"
remediationAction: enforce
orderPolicies: true
policies:
- name: v1-subscriptions-policy
manifests:
- path: source-crs/cluster-logging/ClusterLogSubscription.yaml
patches:
- spec:
source: redhat-operators
installPlanApproval:
'{{hub $configMap:=(lookup "v1" "ConfigMap" "" (printf "%s-pg" .ManagedClusterName)) hub}}{{hub dig "data" "install-plan-approval" "Manual" $configMap hub}}'
- name: v1-config-policy
manifests:
- path: source-crs/node-tuning-operator/x86_64/PerformanceProfile-SetSelector.yaml
patches:
- spec:
cpu:
isolated: '{{hub fromConfigMap "" (printf "%s-pg" .ManagedClusterName) "cpu-isolated" hub}}'
reserved: '{{hub fromConfigMap "" (printf "%s-pg" .ManagedClusterName) "cpu-reserved" hub}}'
hugepages:
defaultHugepagesSize: '{{hub fromConfigMap "" (printf "%s-pg" .ManagedClusterName) "hugepages-default" hub}}'
pages:
- size: '{{hub fromConfigMap "" (printf "%s-pg" .ManagedClusterName) "hugepages-size" hub}}'
count: '{{hub fromConfigMap "" (printf "%s-pg" .ManagedClusterName) "hugepages-count" | toInt hub}}'
machineConfigPoolSelector:
pools.operator.machineconfiguration.openshift.io/worker: ""
nodeSelector:
node-role.kubernetes.io/worker: ''
- path: source-crs/sriov-operator/SriovNetwork.yaml
patches:
- metadata:
name: sriov-nw-du-fh
spec:
resourceName: du_fh
vlan: '{{hub fromConfigMap "" (printf "%s-pg" .ManagedClusterName) "sriov-network-vlan-1" | toInt hub}}'
- path: source-crs/sriov-operator/SriovNetworkNodePolicy-SetSelector.yaml
patches:
- metadata:
name: sriov-nnp-du-fh
spec:
deviceType: netdevice
nicSelector:
pfNames: '{{hub fromConfigMap "" (printf "%s-pg" .ManagedClusterName) "sriov-network-pfNames-1" | toLiteral hub}}'
nodeSelector:
node-role.kubernetes.io/worker: ""
resourceName: du_fh
policyDefaults.namespace
-
Must follow the naming convention ztp-<clustertemplate-namespace>. The O-Cloud Manager uses this convention to locate policies associated with a ClusterTemplate namespace.
policyDefaults.placement.labelSelector
-
Must match the extraLabels.ManagedCluster labels defined in the clusterinstance-defaults ConfigMap CR. These labels bind the policies to the correct managed clusters.
policyAnnotations.clustertemplates.clcm.openshift.io/templates
-
A comma-separated list of ClusterTemplate CRs, populated using the metadata.name field, that this PolicyGenerator CR is associated with. This enables the O-Cloud Manager to track policy compliance for provisioning status reporting.
policyDefaults.orderPolicies
-
Set to true to apply the policies in the order you define under the policies field. The O-Cloud Manager does not use the Topology Aware Lifecycle Manager to order policy application, so you must set the order in the PolicyGenerator CR.
source-crs/
-
Contains the base manifests for Day 2 configuration resources such as PerformanceProfile CRs, SriovNetworkNodePolicy CRs, and Operator subscriptions. These CRs must match the target OKD release version.
|
|
All parameters referenced as placeholders, such as cpu-isolated and sriov-network-vlan-1, must be declared in the templateParameterSchema.policyTemplateParameters section of the ClusterTemplate CR and supplied either through the policy defaults ConfigMap CR or the ProvisioningRequest CR.
|
-
Create a ClusterTemplate CR for the multi-node cluster topology, such as the following example that defines distinct hardware for each node group:
apiVersion: clcm.openshift.io/v1alpha1
kind: ClusterTemplate
metadata:
name: std-ran-du.v4-Y-Z-1
namespace: <template_namespace>
spec:
name: std-ran-du
version: v4-Y-Z-1
release: 4.Y.Z
templateDefaults:
hwMgmtDefaults:
hardwareProvisioningTimeout: "120m"
nodeGroupData:
- name: master
role: master
hwProfile: rh-profile-bios-standard
resourceSelector:
server-type: dell-xr8620t
hardwaredata/num_threads;gte: "64"
hardwaredata/ramMebibytes;gte: "131072"
hardwaredata/nics;speedGbps>=25;count>=4: "present"
- name: worker
role: worker
hwProfile: rh-profile-bios-dpdk
resourceSelector:
server-type: dell-xr7620
hardwaredata/num_threads;gte: "128"
hardwaredata/ramMebibytes;gte: "262144"
hardwaredata/nics;speedGbps>=100;count>=2: "present"
hardwaredata/storage;type==NVME;count>=4: "present"
clusterInstanceDefaults: clusterinstance-defaults-v1
policyTemplateDefaults: policytemplates-defaults-v1
templateParameterSchema:
properties:
nodeClusterName:
type: string
oCloudSiteId:
type: string
hwMgmtParameters:
properties:
hardwareProvisioningTimeout:
type: string
nodeGroupData:
type: array
items:
type: object
required:
- name
properties:
name:
type: string
minLength: 1
role:
type: string
enum:
- master
- worker
hwProfile:
type: string
resourcePoolId:
type: string
resourceSelector:
type: object
additionalProperties:
type: string
type: object
policyTemplateParameters:
properties:
sriov-network-vlan-1:
type: string
sriov-network-vlan-2:
type: string
sriov-network-pfNames-1:
type: string
sriov-network-pfNames-2:
type: string
cpu-isolated:
type: string
cpu-reserved:
type: string
hugepages-default:
type: string
hugepages-size:
type: string
hugepages-count:
type: string
install-plan-approval:
type: string
type: object
clusterInstanceParameters:
properties:
additionalNTPSources:
items:
type: string
type: array
apiVIPs:
items:
type: string
maxItems: 2
type: array
baseDomain:
type: string
clusterName:
type: string
extraAnnotations:
additionalProperties:
additionalProperties:
type: string
type: object
type: object
extraLabels:
additionalProperties:
additionalProperties:
type: string
type: object
type: object
ingressVIPs:
items:
type: string
maxItems: 2
type: array
machineNetwork:
items:
properties:
cidr:
type: string
required:
- cidr
type: object
type: array
nodeGroups:
items:
properties:
name:
type: string
minLength: 1
extraAnnotations:
additionalProperties:
additionalProperties:
type: string
type: object
type: object
extraLabels:
additionalProperties:
additionalProperties:
type: string
type: object
type: object
nodeLabels:
additionalProperties:
type: string
type: object
nodeNetwork:
properties:
config:
type: object
x-kubernetes-preserve-unknown-fields: true
type: object
nodes:
items:
properties:
hostName:
type: string
extraAnnotations:
additionalProperties:
additionalProperties:
type: string
type: object
type: object
extraLabels:
additionalProperties:
additionalProperties:
type: string
type: object
type: object
nodeLabels:
additionalProperties:
type: string
type: object
nodeNetwork:
properties:
interfaces:
minItems: 1
items:
properties:
name:
type: string
minLength: 1
addresses:
properties:
ipv4:
items:
type: string
minLength: 1
minItems: 1
type: array
ipv6:
items:
type: string
minLength: 1
minItems: 1
type: array
minProperties: 1
type: object
required:
- name
- addresses
type: object
type: array
required:
- interfaces
type: object
required:
- hostName
- nodeNetwork
type: object
type: array
required:
- name
- nodes
type: object
type: array
serviceNetwork:
items:
properties:
cidr:
type: string
required:
- cidr
type: object
type: array
sshPublicKey:
type: string
required:
- clusterName
- nodeGroups
type: object
required:
- nodeClusterName
- oCloudSiteId
- policyTemplateParameters
- clusterInstanceParameters
type: object
nodeGroupData[].name
-
Must match the MachineConfigPool name on the managed cluster and the corresponding nodeGroups[].name in the clusterinstance-defaults ConfigMap.
nodeGroupData[].role
-
Maps the node group to a cluster node role. Valid values are master for control plane nodes and worker for compute nodes.
nodeGroupData[].hwProfile
-
Specifies the HardwareProfile CR to apply to this node group. Each group can reference a different profile, for example a standard BIOS profile for controllers and a DPDK-optimized profile for workers. The referenced HardwareProfile CRs must exist in the O-Cloud Manager Operator namespace, oran-o2ims.
nodeGroupData[].resourceSelector
-
Defines independent selection criteria for each node group. Each group’s selector is evaluated separately against the pool of available BareMetalHost CRs. The controller and worker groups can target completely different server types and hardware specifications.
templateParameterSchema.hwMgmtParameters
-
Enables site-specific overrides of hardware profiles and resource selectors. Including this in the schema allows site engineers to adjust hardware selection for individual node groups in their ProvisioningRequest CR without modifying the template.
|
|
The templateParameterSchema is identical for both single-node and multi-node topologies. The schema defines which fields are permitted; the number of nodeGroups entries is determined by the deployment.
|
-
Apply the ClusterTemplate CR to the hub cluster, or commit it to the GitOps repository for ArgoCD synchronization.
Verification
-
Verify that the multi-node template passes validation by running the following command:
$ oc get clustertemplates.clcm.openshift.io -n <template_namespace> std-ran-du.v4-Y-Z-1
Example output
NAMESPACE NAME AGE STATE DETAILS
ocloud-templates std-ran-du.v4-Y-Z-1 12s Completed The cluster template validation succeeded
A STATE of Completed confirms that all node group configurations, resource selectors, and the parameter schema are valid. When a ProvisioningRequest CR references this template, the O-Cloud Manager allocates hosts independently for each node group, matching each group’s resourceSelector against available BareMetalHost CRs.