Create a Cluster on Huawei Cloud Stack
This document provides instructions for creating Kubernetes clusters on the Huawei Cloud Stack platform. YAML-based cluster creation is available through Cluster API manifests. If Fleet Essentials 1.0.2 or later is installed, you can also create clusters through a guided web UI.
The web UI provides a guided workflow with built-in validation, while YAML offers more automation flexibility.
TOC
Prerequisites1. Required Plugin Installation2. HCS Infrastructure Input Preparation3. OS Release Registration4. Workload Cluster Image Registry5. Node Labels and TaintsUsing the Web UICreation WorkflowStep 1: Basic InfoStep 2: NetworkingStep 3: InfrastructureStep 4: Control Plane Node PoolMachine Config entryStep 5: Worker Node PoolsStep 6: ReviewUsing YAMLCluster Creation OverviewControl Plane ConfigurationConfigure HCS AuthenticationConfigure Machine Configuration PoolConfigure Machine TemplateConfigure KubeadmControlPlaneConfigure HCSClusterConfigure ClusterDeploy Worker NodesStep 1: Configure Machine Configuration PoolPool-Managed Persistent Disks for WorkersStep 2: Configure Machine TemplateStep 3: Configure Bootstrap TemplateStep 4: Configure Machine DeploymentCluster VerificationUsing kubectlVerify Control Plane HAExpected ResultsManaging NodesUpgrading ClustersTroubleshootingPrerequisites
Before creating clusters, ensure all of the following prerequisites are met:
1. Required Plugin Installation
Before you create the first workload cluster on Huawei Cloud Stack, upload and install the following plugins on the 's global cluster. This applies regardless of the IaaS platform that the global cluster itself runs on:
- Alauda Container Platform Cluster Bootstrap Provider
- Alauda Container Platform Infrastructure Provider for Huawei Cloud Stack
For the procedure, see Install the Provider.
2. HCS Infrastructure Input Preparation
Prepare all HCS-specific inputs before writing any YAML in this document:
- HCS credential Secret values
- Provider-recognized compute values such as
imageName,flavorName, andavailabilityZone - Cluster network inventory, including the subnets and free IP ranges used by the cluster
- Control plane ELB address planning, including
vipAddress,vipSubnetName, and fixed L4 and L7 IPs - Static IP pool planning for control plane and worker nodes
See Infrastructure Resources for Huawei Cloud Stack for the complete checklist, source information, and constraints.
3. OS Release Registration
This prerequisite applies to the web UI workflow only. YAML-based creation sets the OS image and component versions directly and does not need it.
The web UI does not ask you to type the OS image or its Kubernetes and component versions. It reads them from an OS-release ConfigMap that you register once per Alauda OS image. The wizard resolves the platform Distribution version from the global cluster, finds the registered OS image whose supportedACPVersions includes that Distribution, and derives the node image and control plane component versions from it.
If no registered OS image matches the current Distribution, the wizard blocks creation with an error such as:
No OS registered for the current platform Distribution v4.3.2. Register an OS-release ConfigMap first.
Register the OS image on the global cluster before you open the wizard:
Apply it with kubectl apply -f os-release.yaml.
Field sources:
Do not add a Kube-OVN version to this ConfigMap. The wizard reads the Kube-OVN version from the global cluster's Kube-OVN configuration, not from the OS image.
The osImageVersion must name an image that already exists on the HCS platform. To read the exact name used in an environment that already has clusters, list an existing machine template:
4. Workload Cluster Image Registry
Decide which registry this cluster pulls its platform components from — Kube-OVN and the platform modules that Alauda Container Platform installs on the cluster. This choice does not affect the images kubeadm manages, which come from KubeadmControlPlane.spec.kubeadmConfigSpec.clusterConfiguration.imageRepository.
Either way, the registry must already hold Alauda Container Platform Core for the target version plus the packages for every platform plugin you intend to install on this cluster, and every workload cluster node must reach its address.
For the dedicated-registry procedure and its constraints, see Choose the Image Registry for a Workload Cluster.
A dedicated registry is configured through YAML only. The web UI wizard always uses the registry of the global cluster: it reads that address from the global cluster and writes it into the new cluster for you, and it does not offer a registry credential to select. Use Using YAML when this cluster needs its own registry.
The binding is also read only when the cluster is first created. Changing or removing cpaas.io/registry-reference on an existing Cluster does not move that cluster to another registry.
5. Node Labels and Taints
To give the nodes of a pool their own role label and taint — for example to reserve dedicated pools for monitoring, logging, or ingress — declare them on the pool's resources as described in Infra Nodes. Plan them before you create the pools. This applies to every node pool, whether the cluster is created through the web UI or with YAML; the web UI node pool steps do not set labels or taints.
Using the Web UI
Requirement: This workflow requires Fleet Essentials 1.0.2 or later. Without it, create clusters with the YAML manifests described in Using YAML.
The web UI loads VPCs, subnets, security groups, flavors, and assignable IP addresses from the HCS platform using the Infrastructure Credential you select. Make sure the prerequisites above are met before you start, and that an HCS credential Secret exists in the cpaas-system namespace.
Creation Workflow
The cluster creation follows a 6-step wizard:
Navigation: Clusters → Clusters → Create Cluster → Select Huawei Cloud Stack
How IP selection works
Every IP field in this wizard — the control plane ELB addresses in Step 3 and the node IP addresses in Steps 4 and 5 — is a picker, not a free-text box. Select the subnet first, and the picker lists only the assignable IP addresses of that subnet. HCS clusters use static IP addresses, so you must choose an address from the list; manual entry and DHCP are not supported. Changing the subnet clears the address you already picked. An IP address already chosen elsewhere in the same subnet is removed from the list, so the same address is never assigned twice. When a subnet has many free addresses, the list shows the first batch only; type to filter for a specific address.
Step 1: Basic Info
Step 2: Networking
Step 3: Infrastructure
This step has two parts: the HCS infrastructure resources and the control plane load balancer.
Infrastructure resources:
Control Plane Load Balancer: The HCS provider creates an Elastic Load Balance (ELB) for the Kubernetes API server and owns its VIP. Hybrid Load Balancing requires fixed L4 and L7 virtual subnet IPs.
Step 4: Control Plane Node Pool
The control plane node pool is fixed at 3 replicas for high availability.
Machine Config entry
Each entry in Machine Configs describes one node:
- Hostname (required): Lowercase letters, numbers, hyphens, and dots, up to 253 characters (for example,
master-1ormaster-1.example.org). For how a dotted hostname affects the node, see Hostname behavior on the node. - Networks (required): One row per NIC. Each row has an IP Address picker and a Subnet Name. Add rows for multi-NIC nodes.
- Persistent Disks: The platform-required
/var/cpaasdisk is pre-filled; its size is adjustable but the row cannot be removed. Add rows only for extra host-bound data that must survive node rebuild.
Step 5: Worker Node Pools
Click Add Worker Node Pool to open the pool dialog. You can add multiple pools.
Step 6: Review
Review the Basic Info, Infrastructure, Control Plane Load Balancer, Control Plane Node Pool, Worker Node Pools, and Networking sections. Click View YAML to inspect the exact resources that will be created. Click Create to start the cluster creation process.
Using YAML
Cluster Creation Overview
At a high level, you'll create the following Cluster API resources in the 's global cluster to provision infrastructure and bootstrap a functional Kubernetes cluster.
Before you write any YAML in this page, complete the preparation checklist in Infrastructure Resources for Huawei Cloud Stack. This checklist covers the values that the provider expects, where to get them, and which values must be planned before you fill the manifests.
Important Namespace Requirement
To ensure proper integration with the as workload clusters, all resources must be deployed in the cpaas-system namespace. Deploying resources in other namespaces may result in integration issues.
Workload Cluster Naming
The workload cluster-name must not be global. That name is reserved for the global cluster, and reusing it causes the workload cluster's resources to collide with global cluster resources in cpaas-system. The global- prefix is reserved for resources owned by the global cluster's DR workflow; see Common Prerequisites. Do not use global- for workload-cluster resources, because failover operations can select those resources as if they belonged to the global cluster.
As a convention, keep the CAPI Cluster and provider cluster resource (HCSCluster) named exactly <cluster-name>, and prefix non-root CAPI and provider resources (KubeadmControlPlane, KubeadmConfigTemplate, MachineDeployment, machine templates, machine config pools, etc.) with <cluster-name>- — for example, the example manifests use <cluster-name>-kcp. This is a recommendation rather than a controller-enforced rule, but it prevents same-namespace collisions when multiple workload clusters live in cpaas-system and makes resource ownership obvious during operations.
The cluster creation process follows this order:
- Configure HCS authentication (Secret)
- Create machine configuration pool (HCSMachineConfigPool)
- Configure machine template (HCSMachineTemplate)
- Configure KubeadmControlPlane
- Configure HCSCluster
- Create the Cluster
- Deploy worker nodes (
HCSMachineConfigPool,HCSMachineTemplate,KubeadmConfigTemplate, andMachineDeployment). See Deploy Worker Nodes.
Control Plane Configuration
The control plane manages cluster state, scheduling, and the Kubernetes API. This section shows how to configure a highly available control plane.
Configuration Parameter Guidelines
When configuring resources, exercise caution with parameter modifications:
- Replace only values enclosed in
<>with your environment-specific values - Preserve all other parameters as they represent optimized or required configurations
- Modifying non-placeholder parameters may result in cluster instability or integration issues
Configure HCS Authentication
HCS authentication information is stored in a Secret resource in cpaas-system.
Author the credential file with an editor rather than typing the values at a shell prompt. A shell records the whole command, secret key included, in its history; a file written by an editor leaves no such copy.
Restrict the file, create the Secret from it, then remove it:
Write the values in plain text — kubectl base64-encodes them when it creates the Secret, so there is no separate encoding step. Each line is key=value. Do not quote the values: kubectl takes quote characters literally. A value may contain =; only the first = on a line separates the key from the value.
Client-side apply stores the manifest it applied — including the HCS secret key — in the kubectl.kubernetes.io/last-applied-configuration annotation on the Secret itself. kubectl create writes no such annotation. This applies whether the values were written as stringData or as base64 data; base64 is an encoding, not protection.
Existing credential Secrets created without schema continue to work unchanged. Only set schema if your HCS IAM endpoint uses http instead of the default https.
You can reuse an existing HCS credential Secret. Its name does not need to match the cluster name, but HCSCluster.spec.identityRef.name must reference this Secret.
Configure Machine Configuration Pool
The HCSMachineConfigPool defines pre-configured hostnames, static IP addresses, and any pool-managed persistent disks for VMs.
Pool Size Requirement
The configuration pool must include at least as many entries as the number of control plane nodes you plan to deploy.
Use one subnet selector per networks[] entry. For new manifests, set either subnetName or subnetId, but not both. Existing manifests may keep the deprecated subenetName field; if you also add subnetName while updating that manifest, its value must exactly match subenetName. Do not supply conflicting values across subenetName, subnetName, and subnetId.
If you use subnetName in the machine configuration pool, include the same subnet name in HCSCluster.spec.network.subnets.
For the initial cluster create flow, listing an existing subnet by name is enough because the controller resolves subnet metadata before the cluster becomes Ready. If you later add another subnet to an existing Ready HCSCluster, do not append only name. Patch the parent HCSCluster.spec.network.subnets entry with the full subnet object so later machine or ELB operations can reuse the resolved subnet metadata.
*For new manifests, set either subnetName or subnetId. Existing manifests may continue to use subenetName, and may add subnetName only if both fields use the same value. Do not provide conflicting subnet selector values.
Persistent disk fields are required when persistentDisks is specified.
Use persistentDisks[] for node-local state that must survive VM replacement. Do not declare the same mount path in HCSMachineTemplate.spec.template.spec.dataVolumes[].
Note: The CRD schema lists subnetName, subenetName, and subnetId as optional fields and does not express their allowed combinations. Follow the provider-level rules above when writing manifests.
Note: To attach multiple NICs to one node, add multiple networks[] entries. The provider only uses these entries to attach NICs and assign subnet selectors plus static IPs. It does not support declaring per-NIC roles, default gateways, static routes, or per-NIC DNS settings.
Hostname behavior on the node
The provider derives the node's POSIX hostname and FQDN from hostname as follows:
The dotted form is the path to set up applications that depend on FQDN resolution (hostname -f, certificates with SAN entries, log labels). The provider sets prefer_fqdn_over_hostname: false and enables cloud-init manage_etc_hosts only when a dotted hostname is supplied, so POSIX tools continue to see the short name and hostname -f returns the full FQDN.
Invalid hostnames (leading dot, trailing dot, all-dot strings, uppercase letters, or anything that violates the field constraint) are rejected before the VM boots. The error is set on the owning Machine.status and surfaced on the Cluster.status.conditions so it shows up under kubectl describe cluster <name> and kubectl get machines -n cpaas-system -o wide.
Configure Machine Template
The HCSMachineTemplate defines the VM specifications for control plane nodes.
Storage Requirements
The following data disk mount points are recommended for control plane nodes:
/var/lib/etcd- etcd data (10GB+)/var/lib/kubelet- kubelet data (100GB+)/var/lib/containerd- container runtime data (100GB+)
The /var/cpaas path stores platform state and logs. Declare it in HCSMachineConfigPool.spec.configs[].persistentDisks[] when it must survive VM replacement.
*Required when dataVolumes is specified.
dataVolumes[] are recreated with the ECS. Do not use them for /var/cpaas or any other path that must survive rolling replacement. Put those paths in HCSMachineConfigPool.spec.configs[].persistentDisks[].
Note: Do not set runtime identity fields such as providerID or serverId in HCSMachineTemplate manifests. The provider assigns these values when it creates HCS instances.
Note: The ACP web UI loads flavors and availability zones through the selected HCS credential. When you write YAML, get the exact provider-recognized Flavor.Name and ZoneName values from the HCS administrator because the native HCS tenant console might not expose them.
Configure KubeadmControlPlane
The KubeadmControlPlane defines the Kubernetes control plane configuration.
imagePullCredentialsVerificationPolicy: NeverVerify is required only starting with Kubernetes 1.35. Omit this parameter when creating a cluster with Kubernetes 1.34 or earlier.
The HCS controller also injects files while resolving cloud-init data. It writes /etc/kubernetes/pki/kubelet.crt, /etc/kubernetes/pki/kubelet.key, and /etc/kubernetes/encryption-provider.conf for control plane machines. For the first control plane machine, the controller generates the encryption provider configuration. After the control plane is initialized, it tries to reuse the existing kube-apiserver encryption provider configuration. If you include a bootstrap file at /etc/kubernetes/encryption-provider.conf, treat it as a placeholder because the controller-generated or synchronized file takes precedence.
Note: Configure apiServer.extraArgs and apiServer.extraVolumes together. If the volume is not mounted, kube-apiserver cannot read the files written under /etc/kubernetes.
Note: The rolloutStrategy.rollingUpdate.maxSurge: 0 example above is for highly available static-IP control planes. Keep this setting for fixed-size control plane pools with at least three replicas so replacements happen in a scale-down-then-scale-up order. If you create a single-control-plane HCS cluster (spec.replicas: 1), do not copy the rolloutStrategy block into the create manifest. KubeadmControlPlane validation rejects that scale-in style rollout configuration for a single replica.
Note: HCS also supports creating a single-control-plane cluster by setting spec.replicas: 1 and preparing one control plane config entry in the referenced HCSMachineConfigPool. Treat this as a creation-only topology, and leave the rollout strategy unset in that create manifest. A single-control-plane HCS cluster cannot be upgraded.
Use the OS Support Matrix only for the component versions it explicitly lists, such as coredns and etcd image tags for supported Alauda OS images. It is not a complete source for all HCS manifest values. Before you apply this YAML, also use the approved release baseline for values such as imageRepository, DNS image repository, Kube-OVN version, Kube-OVN join CIDR, Pod CIDR, and Service CIDR.
Configure HCSCluster
The HCSCluster resource defines the HCS infrastructure configuration.
The HCS provider creates an Elastic Load Balance (ELB) on the HCS platform for the Kubernetes API server. This ELB must keep Hybrid Load Balancing enabled so cluster nodes can also reach the API server through the ELB address.
For the documented HCS workflow, provide vipAddress, elbVirsubnetL4Ips, and elbVirsubnetL7Ips. Each elbVirsubnetL4Ips[].ips and elbVirsubnetL7Ips[].ips entry must contain two IPs.
Leave vipDomainName unset — cluster access by domain is not supported; see the field table below.
List every cluster subnet in spec.network.subnets before you reference it anywhere else. vipSubnetName, elbVirsubnetL4Ips[].subnetName, elbVirsubnetL7Ips[].subnetName, and the subnetName values used by HCSMachineConfigPool must all exist in spec.network.subnets.
For the initial cluster create flow, the controller can resolve existing subnet metadata from name. For an existing Ready cluster, append a full subnet object instead of only name. Include id, and include neutronSubnetId for any subnet that the control plane ELB will use. Keep cidr, gatewayIp, primaryDNS, and secondaryDNS in the subnet inventory as well.
Do not disable Hybrid Load Balancing on the provider-created ELB after the cluster is created. The cluster depends on that ELB mode so nodes can reach the API server through the ELB address.
Do not include spec.controlPlaneEndpoint in the create manifest. In the HCS create flow, the controller derives and populates this field from spec.controlPlaneLoadBalancer after the HCSCluster is created. Do not set controlPlaneEndpoint manually, and do not add an empty controlPlaneEndpoint object. If controlPlaneEndpoint is explicitly present in the manifest, it must include both host and port.
controlPlaneHA is optional. When you include it, both enabled and policy are required. Use anti-affinity for strict host separation. Use soft-anti-affinity when you prefer host spread but do not want ECS creation to fail only because HCS cannot satisfy the hard placement rule. For planning guidance, including the rolling replacement requirement when enabling the feature on an existing cluster, see Control Plane HA Placement Plan.
Configure Cluster
The Cluster resource in Cluster API declares the cluster and references the control plane and infrastructure resources.
Deploy Worker Nodes
The control plane alone is not a usable cluster. After the control plane is Ready, create the worker resources in the following order.
Before you prepare worker YAML, complete the HCS input checklist in Infrastructure Resources for Huawei Cloud Stack. In particular, list every worker subnet in HCSCluster.spec.network.subnets, allocate worker IPs from planned free IP ranges, and collect the provider-recognized flavorName and availabilityZone API values. If you add a new worker subnet to an existing Ready cluster, patch HCSCluster.spec.network.subnets with the full subnet object instead of adding only the subnet name.
Step 1: Configure Machine Configuration Pool
The HCSMachineConfigPool defines the network configuration and any pool-managed persistent disks for worker node VMs. You must plan and configure the IP addresses, hostnames, persistent disk slots, and other parameters before deployment.
Pool Size Requirement
The pool must include at least as many entries as the number of worker nodes you plan to deploy. Insufficient entries will prevent node deployment.
Use one subnet selector per networks[] entry. For new manifests, set either subnetName or subnetId, but not both. Existing manifests may keep the deprecated subenetName field; if you also add subnetName while updating that manifest, its value must exactly match subenetName. Do not supply conflicting values across subenetName, subnetName, and subnetId.
If you use subnetName for worker nodes, include the same subnet name in the parent HCSCluster.spec.network.subnets list before you create or scale the worker pool. For an existing Ready cluster, append the full subnet object, including the subnet ID, instead of adding only the subnet name.
*For new manifests, set either subnetName or subnetId. Existing manifests may continue to use subenetName, and may add subnetName only if both fields use the same value. Do not provide conflicting subnet selector values.
Persistent disk fields are required when persistentDisks is specified.
Use persistentDisks[] for node-local state that must survive worker replacement. Do not declare the same mount path in HCSMachineTemplate.spec.template.spec.dataVolumes[].
Note: The CRD schema lists subnetName, subenetName, and subnetId as optional fields and does not express their allowed combinations. Follow the provider-level rules above when writing manifests.
Note: networks[] can contain more than one entry when a worker node needs multiple NICs. The current provider only uses each entry to attach a NIC with a subnet selector and static IP. It does not support per-NIC role declarations, default gateway selection, static routes, route metrics, or per-NIC DNS settings.
Pool-Managed Persistent Disks for Workers
Declare worker-node disks that must survive replacement in the matching HCSMachineConfigPool.spec.configs[].persistentDisks[] entry. Use this model for /var/cpaas and for any other node-local state that must be retained during rolling replacement.
- Keep
HCSMachineTemplate.spec.template.spec.dataVolumes[]for temporary disks that may be recreated with each ECS. - Keep slots unique and contiguous from
0for each hostname. The provider uses(hostname, slot)as the persistent-disk identity. - Treat
slot,size,type,format, andmountPathas immutable after the provider accepts the entry. - You can update
mountOptions. The change takes effect after the worker is replaced. - You can append new
persistentDisks[]entries. The provider creates or claims the EVS disk, but it does not hot-mount the disk into the running ECS. Trigger a rolling replacement withMachineDeployment.spec.strategy.rollingUpdate.maxSurge: 0before you expect the new disk to be formatted and mounted inside the guest OS.
To inspect persistent-disk runtime state during worker operations, check the pool status:
Step 2: Configure Machine Template
The HCSMachineTemplate defines the VM specifications for worker nodes.
Configure worker nodes with a system volume and temporary data volumes for paths that may be recreated with each ECS, such as /var/lib/kubelet and /var/lib/containerd. Put /var/cpaas in HCSMachineConfigPool.spec.configs[].persistentDisks[] when platform state must survive worker replacement.
Use the provider-recognized flavorName and availabilityZone API values when you prepare the worker template. These values are not the tenant UI display names.
*Required when dataVolumes is specified.
dataVolumes[] are recreated with the ECS. Do not use them for /var/cpaas or any other path that must survive rolling replacement.
Note: Do not set runtime identity fields such as providerID or serverId in HCSMachineTemplate manifests. The provider assigns these values when it creates HCS instances.
Note: The ACP web UI loads flavors and availability zones through the selected HCS credential. When you write YAML, get the exact provider-recognized Flavor.Name and ZoneName values from the HCS administrator because the native HCS tenant console might not expose them.
Step 3: Configure Bootstrap Template
The KubeadmConfigTemplate defines the bootstrap configuration for worker nodes.
imagePullCredentialsVerificationPolicy: NeverVerify is required only starting with Kubernetes 1.35. Omit this parameter when creating workers with Kubernetes 1.34 or earlier.
The HCS controller injects /etc/kubernetes/pki/kubelet.crt and /etc/kubernetes/pki/kubelet.key while resolving worker cloud-init data. The kubelet patch above configures kubelet to use those controller-provided certificate files.
Step 4: Configure Machine Deployment
The MachineDeployment orchestrates the creation and management of worker nodes.
Cluster Verification
After deploying all cluster resources, verify that the cluster has been created successfully.
Using kubectl
Verify Control Plane HA
If you enabled HCSCluster.spec.controlPlaneHA, inspect the HCSCluster condition first:
Interpret the condition as follows:
Inspect the observed server group and membership snapshot:
For anti-affinity, HCS treats the server group policy as a hard scheduling constraint. If capacity is insufficient, ECS creation can fail and the condition message should be used as the first diagnostic signal. For soft-anti-affinity, HCS tries to spread members but may still place multiple ECS instances on the same host.
Expected Results
A successfully created cluster should show:
- Cluster status: Running or Provisioned
- All control plane machines: Running
- Kubernetes nodes: Ready
- Cluster Module Status: Completed
Managing Nodes
For day-2 node operations such as scaling, template updates, and web UI node pools, refer to Manage Nodes on Huawei Cloud Stack.
Upgrading Clusters
For instructions on upgrading cluster components, refer to Upgrade Kubernetes.
Troubleshooting
If the cluster reaches Provisioned but never becomes Ready — for example, workload nodes stay NotReady because the CNI is not deployed — start with the provider-agnostic Troubleshoot a Workload Cluster Stuck in Provisioned.
For HCS-specific failure patterns (for example, kubeadm init never completes because a dotted HCSMachineConfigPool hostname produced a POSIX hostname containing dots), see Troubleshoot Huawei Cloud Stack Workload Clusters.