在 Huawei Cloud Stack 上创建集群

本文介绍如何在 Huawei Cloud Stack 平台上创建 Kubernetes 集群。可通过 Cluster API 清单使用基于 YAML 的方式创建集群。如果已安装 Fleet Essentials 1.0.2 或更高版本,还可以通过引导式 Web UI 创建集群。

INFO

Web UI 提供内置验证的引导式工作流,而 YAML 则具有更高的自动化灵活性。

前提条件

创建集群前,请确保满足以下所有前提条件:

1. 安装所需插件

在 Huawei Cloud Stack 上创建第一个业务集群之前,请先将以下插件上传并安装到 的 global 集群上。无论 global 集群本身运行在哪个 IaaS 平台上,都需要执行此操作:

  • Alauda Container Platform Cluster Bootstrap Provider
  • Alauda Container Platform Infrastructure Provider for Huawei Cloud Stack

操作步骤请参阅安装 Provider。

2. 准备 HCS 基础设施输入

编写本文中的任何 YAML 之前,请准备好所有 HCS 特定输入:

  • HCS 凭证 Secret 的值
  • Provider 可识别的计算值,例如 imageName、flavorName 和 availabilityZone
  • 集群网络清单,包括集群使用的子网和可用 IP 地址范围
  • 控制平面 ELB 地址规划,包括 vipAddress、vipSubnetName 以及固定的 L4 和 L7 IP
  • 控制平面和工作节点的静态 IP 池规划

完整的检查清单、来源信息和限制条件,请参阅华为云 Stack 的基础设施资源。

3. 注册 OS 版本

此先决条件仅适用于 Web UI 工作流。基于 YAML 的创建方式会直接设置 OS 映像和组件版本,因此无需执行此操作。

Web UI 不会要求你输入 OS 映像及其 Kubernetes 和组件版本,而是从 OS-release ConfigMap 中读取这些信息。每个 Alauda OS 映像都需要注册一个此类 ConfigMap。向导会从 global 集群解析平台 Distribution 版本,查找 supportedACPVersions 包含该 Distribution 的已注册 OS 映像,并据此确定节点映像和控制平面组件版本。

如果没有已注册的 OS 映像与当前 Distribution 匹配,向导会阻止创建,并显示类似以下错误:

当前平台 Distribution v4.3.2 未注册 OS。请先注册 OS-release ConfigMap。

打开向导之前,请先在 global 集群上注册 OS 映像:

apiVersion: v1
kind: ConfigMap
metadata:
  # Any DNS-1123 name. The name is not a lookup key.
  # Do not copy the image version verbatim: it contains "_" (for example, x86_64), which is invalid in a ConfigMap name.
  name: alaudaos-43-m55-x86-64
  namespace: cpaas-system
  labels:
    cpaas.io/os-release: ""
data:
  osImageVersion: "alaudaos-43.m55.202606251459-0.x86_64"
  supportedACPVersions: "v4.3.2"
  osVariant: "m55"
  architecture: "x86_64"
  osBuild: "202606251459-0"
  kubernetesVersion: "v1.34.5-3"
  containerdVersion: "2.2.1-5"
  coreDNSImageTag: "1.14.2-v4.3.11"
  etcdImageTag: "v3.5.28-260625"
  pauseImageTag: "3.10"

使用 kubectl apply -f os-release.yaml 应用该配置。

字段来源:

字段值来源
cpaas.io/os-release 标签值为空的固定标记。向导通过此标签发现 ConfigMap。
osImageVersion上传到 HCS 平台的 Alauda OS 映像的确切名称。Provider 使用此名称查找 ECS 映像,并将其设为节点池默认映像。对于标准版本,该名称与为相应 ACP 版本发布的 Alauda OS 映像上传时使用的名称一致。请参阅下载 Alauda OS。
supportedACPVersions此 OS 映像适用的 ACP Distribution 版本,以逗号分隔(例如 v4.3.2 或 v4.3.0,v4.3.1)。向导会将 global 集群的 Distribution 与此列表进行匹配。
architecturex86_64 或 aarch64。必须与计划使用的节点规格的架构一致。
osVariant、osBuild用于参考说明的字段;不用于匹配。
kubernetesVersion、containerdVersion、coreDNSImageTag、etcdImageTag、pauseImageTag此 OS 映像的组件版本,取自 OS 支持矩阵中匹配的行。向导会将这些版本注入新集群的控制平面,因此它们必须存在于你的隔离网络注册表中。
INFO

请勿向此 ConfigMap 添加 Kube-OVN 版本。向导会从 global 集群的 Kube-OVN 配置中读取 Kube-OVN 版本,而不是从 OS 映像中读取。

osImageVersion 必须指定 HCS 平台上已存在的映像。若要读取已有集群的环境中使用的确切名称,请列出现有的机器模板:

kubectl -n cpaas-system get hcsmachinetemplate \
  -o custom-columns=NAME:.metadata.name,IMAGE:.spec.template.spec.imageName

4. 业务集群映像注册表

确定此集群从哪个注册表拉取平台组件——Kube-OVN 以及 Alauda Container Platform 安装在集群上的平台模块。此选择不会影响 kubeadm 管理的映像,这些映像来自 KubeadmControlPlane.spec.kubeadmConfigSpec.clusterConfiguration.imageRepository。

选项配置内容适用场景
global 集群的注册表无需配置。集群会继承该注册表,向导会自动填写其地址。业务节点能够以可接受的吞吐量访问 global 集群使用的注册表。
专用注册表cpaas-system 中的 RegistryCredential Secret,由 cpaas.io/registry-reference 标签在 Cluster 中引用。业务节点位于不同地域或网络段,应从距离较近的注册表拉取映像。

无论采用哪种方式,注册表都必须已包含目标版本的 Alauda Container Platform Core,以及计划安装到此集群的每个平台注册插件的软件包;并且每个业务集群节点都必须能够访问该注册表地址。

有关专用注册表的操作步骤和限制条件,请参阅为业务集群选择映像注册表。

WARNING

专用注册表只能通过 YAML 配置。Web UI 向导始终使用 global 集群的注册表:它会从 global 集群读取该地址,并自动将其写入新集群,且不提供供你选择的注册表凭证。如果此集群需要使用自己的注册表,请参阅使用 YAML。

此外,只有在首次创建集群时才会读取绑定。在现有 Cluster 上更改或移除 cpaas.io/registry-reference,不会使该集群切换到其他注册表。

5. 节点标签和污点

若要为某个池中的节点设置专属角色标签和污点,例如为监控、日志记录或入口预留专用池,请按照基础设施节点中的说明,在池的资源上声明标签和污点。请在创建节点池之前进行规划。此要求适用于所有节点池,无论集群是通过 Web UI 创建还是使用 YAML 创建;Web UI 的节点池步骤不会设置标签或污点。

使用 Web UI

要求:此操作流程要求 Fleet Essentials 1.0.2 或更高版本。否则,请使用使用 YAML中所述的 YAML manifests 创建集群。

Web UI 会使用你选择的 Infrastructure Credential,从 HCS 平台加载 VPC、子网、安全组、flavor 和可分配的 IP 地址。开始前,请确保满足上述前提条件,并且 cpaas-system 命名空间中存在 HCS credential Secret。

创建流程

集群创建遵循包含 6 个步骤的向导:

Step 1: Basic Info
  ↓
Step 2: Networking
  ↓
Step 3: Infrastructure
  ↓
Step 4: Control Plane Node Pool
  ↓
Step 5: Worker Node Pools
  ↓
Step 6: Review

导航路径:集群 → 集群 → 创建集群 → 选择 Huawei Cloud Stack

INFO

IP 地址选择方式

此向导中的每个 IP 字段——第 3 步中的控制平面 ELB 地址,以及第 4 步和第 5 步中的节点 IP 地址——都是选择器,而不是自由文本框。请先选择子网,选择器只会列出该子网中可分配的 IP 地址。HCS 集群使用静态 IP 地址,因此你必须从列表中选择地址;不支持手动输入和 DHCP。更改子网会清除已选择的地址。同一子网中已在其他位置选择的 IP 地址会从列表中移除,因此同一地址不会被分配两次。当子网有大量可用地址时,列表仅显示第一批地址;请输入内容以筛选特定地址。

第 1 步:基本信息

字段类型必填描述
Infrastructure Credential下拉列表是现有的 HCS credential Secret。用于加载 VPC、子网、安全组、flavor 和可分配的 IP 地址。如果下拉列表为空,请在 cpaas-system 命名空间中创建一个带有 capi.cpaas.io/provider=cluster-api-provider-hcs label 的 Secret。
Name文本是唯一的集群标识符(小写字母、数字和连字符),最多 63 个字符。不能为 global。
Display Name文本否用于便于识别的自定义描述,最多 256 个字符。
Distribution Version只读-平台 distribution 版本,继承自 global 集群。
Kubernetes Version只读-由 Distribution Version 确定。
OS Version只读-取自与 Distribution Version 匹配的已注册 OS-release ConfigMap的 Alauda OS 镜像版本。

第 2 步:网络

字段类型必填描述
Kube-OVN Version只读-从 global 集群中检测。
Pod CIDRCIDR是Pod 网络地址范围。
Service CIDRCIDR是Service 网络地址范围。不能与 Pod CIDR 重叠。
Join CIDRCIDR是Kube-OVN join 网络地址范围。

第 3 步:基础设施

此步骤分为两部分:HCS 基础设施资源和控制平面负载均衡器。

基础设施资源:

字段类型必填描述
VPC Name下拉列表是从所选 credential 加载的现有 VPC。
Security Group Name下拉列表是现有安全组。
Subnets下拉列表是一个或多个现有子网。负载均衡器或节点池引用的每个子网都必须添加到此处。

控制平面负载均衡器:HCS provider 会为 Kubernetes API server 创建 Elastic Load Balance(ELB),并负责管理其 VIP。Hybrid Load Balancing 要求固定的 L4 和 L7 虚拟子网 IP。

字段类型必填描述
VIP Subnet Name下拉列表是保存 ELB VIP 的子网。必须是上述已添加的子网之一。
VIP AddressIP 选择器是控制平面 ELB 的固定 VIP。
VIP Domain Name文本否留空。系统不支持通过域访问集群——此字段仅用于回填派生的集群 endpoint,且 API server 证书由集群自己的 CA 签发。
L4 Virtual Subnet Name下拉列表是L4 Hybrid Load Balancing IP 所使用的子网。
L4 Virtual Subnet IP 1 / IP 2IP 选择器是两个固定的 L4 IP 地址。
L7 Virtual Subnet Name下拉列表是L7 Hybrid Load Balancing IP 所使用的子网。
L7 Virtual Subnet IP 1 / IP 2IP 选择器是两个固定的 L7 IP 地址。

第 4 步:控制平面节点池

为实现高可用,控制平面节点池固定为 3 个副本。

字段类型必填描述
Control Plane Node Pool Name文本是节点池名称,会自动添加 <cluster-name>- 前缀。
Flavor下拉列表是HCS flavor;列表会显示每个选项的 vCPU 和内存。
Availability Zone下拉列表否每个控制平面节点的目标可用区。报告为不可用的可用区会被禁用。请参阅可用区放置。
Machine Configs列表是每个控制平面节点对应一个条目。至少需要 3 个条目。请参阅下方的Machine Config 条目。
System Disk数字是根磁盘大小,单位为 GB;类型固定为 SSD。
Data Volumes列表否挂载到池中每个节点的固定数据磁盘;只能调整大小。控制平面会包含 etcd 数据卷。
Replicas只读-固定为 3。
Control Plane High Availability开关否默认启用。通过使用 provider 管理的 HCS server group,将控制平面节点分散到所选可用区内不同的物理主机上。
Placement Policy单选按钮有条件启用 High Availability 时显示。Preferred(软反亲和性)(默认)会尽力将节点分散放置。Required(严格反亲和性) 会强制将每个节点放置到不同主机上;如果主机数量不足,创建将失败。
SSH Authorized Keys列表否用于访问节点的公钥。

Machine Config 条目

Machine Configs 中的每个条目描述一个节点:

  • Hostname(必填):小写字母、数字、连字符和点,最多 253 个字符(例如 master-1 或 master-1.example.org)。有关带点的 hostname 如何影响节点,请参阅节点上的 hostname 行为。
  • Networks(必填):每个 NIC 对应一行。每行包含一个 IP Address 选择器和一个 Subnet Name。对于多 NIC 节点,请添加多个行。
  • Persistent Disks:平台要求的 /var/cpaas 磁盘会预先填充;可以调整其大小,但不能移除该行。仅为必须在节点重建后保留的额外主机绑定数据添加行。

第 5 步:业务节点池

点击 Add Worker Node Pool 打开节点池对话框。你可以添加多个节点池。

字段类型必填描述
Worker Node Pool Name文本是节点池名称,会自动添加 <cluster-name>- 前缀。在集群内必须唯一。
Flavor下拉列表是HCS flavor;列表会显示每个选项的 vCPU 和内存。
Availability Zone下拉列表否此业务节点池中每个节点的目标可用区。不同业务节点池可以选择不同的可用区;报告为不可用的可用区会被禁用。请参阅可用区放置。
Machine Configs列表是每个业务节点对应一个条目。使用与控制平面相同的 Machine Config 条目布局。
System Disk数字是根磁盘大小,单位为 GB;类型固定为 SSD。
Data Volumes列表否挂载到池中每个节点的固定数据磁盘。
Replicas数字是池中节点的数量。不能超过 machine configs 的数量。
Rollout Strategy数字否Max Surge 和 Max Unavailable。当 Max Surge 为 0 时,Max Unavailable 必须 ≥ 1 且 ≤ Replicas。
SSH Authorized Keys列表否用于访问节点的公钥。

第 6 步:审阅

审阅 Basic Info、Infrastructure、Control Plane Load Balancer、Control Plane Node Pool、Worker Node Pools 和 Networking 部分。点击 View YAML 查看将要创建的确切资源。点击 Create 开始创建集群。

使用 YAML

集群创建概览

总体而言,你将在 的 global 集群中创建以下 Cluster API 资源,以配置基础设施并引导一个正常运行的 Kubernetes 集群。

在本页编写任何 YAML 之前,请完成华为云 Stack 基础设施资源中的准备清单。此清单涵盖 provider 所需的值、这些值的获取位置,以及在填写清单文件之前必须规划的值。

WARNING

重要的命名空间要求

为确保与 作为业务集群正确集成,所有资源都必须部署在 cpaas-system 命名空间中。在其他命名空间中部署资源可能会导致集成问题。

WARNING

业务集群命名

业务 cluster-name 不能为 global。该名称已保留给 global 集群,重复使用会导致业务集群的资源与 global 集群在 cpaas-system 中的资源发生冲突。global- 前缀已保留给 global 集群的 DR 工作流所拥有的资源;请参阅通用前提条件。不要将 global- 用于业务集群资源,因为故障转移操作可能会将这些资源选作属于 global 集群的资源。

按照约定,将 CAPI Cluster 和 provider 集群资源(HCSCluster)均准确命名为 <cluster-name>,并为非根 CAPI 和 provider 资源(KubeadmControlPlane、KubeadmConfigTemplate、MachineDeployment、machine template、machine config pool 等)添加 <cluster-name>- 前缀——例如,示例清单使用 <cluster-name>-kcp。这是一项建议,而非控制器强制执行的规则,但它可以防止多个业务集群位于 cpaas-system 时发生同一命名空间内的冲突,并使操作期间的资源归属一目了然。

集群创建过程按以下顺序进行:

  1. 配置 HCS 身份验证(Secret)
  2. 创建 machine configuration pool(HCSMachineConfigPool)
  3. 配置 machine template(HCSMachineTemplate)
  4. 配置 KubeadmControlPlane
  5. 配置 HCSCluster
  6. 创建 Cluster
  7. 部署工作节点(HCSMachineConfigPool、HCSMachineTemplate、KubeadmConfigTemplate 和 MachineDeployment)。请参阅部署工作节点。

控制平面配置

控制平面管理集群状态、调度和 Kubernetes API。本节介绍如何配置高可用控制平面。

WARNING

配置参数指南

配置资源时,请谨慎修改参数:

  • 仅替换 <> 中包含的值,替换为特定于环境的值
  • 保留所有其他参数,因为这些参数代表经过优化或必需的配置
  • 修改非占位符参数可能导致集群不稳定或集成问题

配置 HCS 身份验证

HCS 身份验证信息存储在 cpaas-system 中的 Secret 资源内。

请使用编辑器编写凭证文件,而不是在 shell 提示符下输入值。Shell 会将整条命令(包括 Secret 密钥)记录在历史记录中;使用编辑器写入的文件不会留下此类副本。

hcs-credential.env
accessKey=<access-key>
secretKey=<secret-key>
projectID=<project-id>
region=<region>
externalGlobalDomain=<domain>
schema=https

限制文件权限,从文件创建 Secret,然后删除该文件:

chmod 600 hcs-credential.env

HCS_SECRET_NAME="<credential-secret-name>"

kubectl create secret generic "${HCS_SECRET_NAME}" \
  --namespace cpaas-system \
  --from-env-file=hcs-credential.env

rm -f hcs-credential.env

以纯文本形式写入值——kubectl 在创建 Secret 时会对其进行 base64 编码,因此无需单独的编码步骤。每一行都是 key=value。不要为值加引号:kubectl 会将引号字符按字面值处理。值中可以包含 =;每行中只有第一个 = 用于分隔键和值。

不要使用 kubectl apply 创建凭证 Secret

客户端 apply 会将其应用的清单(包括 HCS Secret 密钥)存储在 Secret 自身的 kubectl.kubernetes.io/last-applied-configuration 注解中。kubectl create 不会写入此类注解。无论值以 stringData 形式还是 base64 data 形式写入,这一点都适用;base64 是一种编码,而不是保护措施。

键描述
accessKeyMy Settings > Access Keys 中的 HCS access key ID
secretKeyMy Settings > Access Keys 中的 HCS secret access key
projectIDMy Settings > Resource Spaces 中的 Resource Space ID
regionprovider 使用的 HCS region API 值。租户管理员无法从 HCS UI 获取此值;请向 HCS 管理员获取
externalGlobalDomainprovider 使用的 HCS platform access domain
schemaHCS IAM endpoint 的可选 API scheme,通常为 https。省略此行即可使用默认值

未设置 schema 创建的现有凭证 Secret 可以继续正常使用。只有当你的 HCS IAM endpoint 使用 http 而不是默认值 https 时,才设置 schema。

你可以重复使用现有的 HCS 凭证 Secret。其名称无需与集群名称匹配,但 HCSCluster.spec.identityRef.name 必须引用此 Secret。

配置 Machine Configuration Pool

HCSMachineConfigPool 定义预配置的主机名、静态 IP 地址,以及由 pool 管理的 VM 持久磁盘。

WARNING

Pool 大小要求

配置 pool 至少必须包含与你计划部署的控制平面节点数量相同的条目。

每个 networks[] 条目使用一个子网选择器。对于新清单,请设置 subnetName 或 subnetId,但不能同时设置两者。现有清单可以保留已弃用的 subenetName 字段;如果在更新该清单时同时添加 subnetName,其值必须与 subenetName 完全匹配。不要在 subenetName、subnetName 和 subnetId 之间提供相互冲突的值。

如果在 machine configuration pool 中使用 subnetName,请在 HCSCluster.spec.network.subnets 中包含相同的子网名称。

对于初始集群创建流程,只需按名称列出现有子网即可,因为控制器会在集群变为 Ready 前解析子网元数据。如果稍后向现有的 Ready HCSCluster 添加另一个子网,请勿仅追加 name。应使用完整的子网对象修补父级 HCSCluster.spec.network.subnets 条目,以便后续 machine 或 ELB 操作可以重复使用已解析的子网元数据。

apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: HCSMachineConfigPool
metadata:
  name: <cluster-name>-cp-pool
  namespace: cpaas-system
  labels:
    cluster.x-k8s.io/cluster-name: <cluster-name>
spec:
  configs:
    - hostname: master-1
      networks:
        - subnetName: <subnet-name>
          ipAddress: 192.168.1.11
      persistentDisks:
        - slot: 0
          size: 100
          type: SSD
          mountPath: /var/cpaas
          format: xfs
    - hostname: master-2
      networks:
        - subnetName: <subnet-name>
          ipAddress: 192.168.1.12
      persistentDisks:
        - slot: 0
          size: 100
          type: SSD
          mountPath: /var/cpaas
          format: xfs
    - hostname: master-3
      networks:
        - subnetName: <subnet-name>
          ipAddress: 192.168.1.13
      persistentDisks:
        - slot: 0
          size: 100
          type: SSD
          mountPath: /var/cpaas
          format: xfs
参数类型必填描述
.spec.configs[]array是非空的 machine configuration 列表
.spec.configs[].hostnamestring是VM 主机名。使用小写字母、数字、连字符(-)或点号(.);值必须以小写字母或数字开头和结尾,且不得超过 253 个字符(遵循 RFC 1035 中的 DNS 名称长度限制)。开头或结尾为点号、全为点号的字符串以及大写字母都会被拒绝,控制器会在所属 Machine 和 Cluster 状态中报告错误。有关值包含点号时 hostname 和 hostname -f 的返回值,请参阅下方的 节点上的主机名行为 小节。
.spec.configs[].networks[]array是VM 的非空网络配置列表
.spec.configs[].networks[].subnetNamestring否*新清单推荐使用的子网名称字段
.spec.configs[].networks[].subnetIdstring否*子网 ID。当子网名称不明确时,使用此字段而不是 subnetName
.spec.configs[].networks[].ipAddressstring是VM 的静态 IP 地址
.spec.configs[].persistentDisks[]array否在 HCSMachine 删除并重新创建替换后仍保留的 EVS 磁盘
.spec.configs[].persistentDisks[].slotint是*一个 machine configuration 中的磁盘插槽。同一主机名的插槽必须从 0 开始保持唯一且连续
.spec.configs[].persistentDisks[].sizeint是*EVS 磁盘大小,单位为 GB。对于新创建的 EVS 数据磁盘,请使用 10 至 32768 GB。现有已声明的磁盘必须与其当前大小匹配
.spec.configs[].persistentDisks[].typestring是*目标可用区中可用的 EVS 磁盘类型名称
.spec.configs[].persistentDisks[].mountPathstring否Guest 挂载路径。对于必须在 VM 替换后保留的平台状态,请使用 /var/cpaas
.spec.configs[].persistentDisks[].formatstring否文件系统格式。如果省略,provider 将使用 xfs
.spec.configs[].persistentDisks[].mountOptionsarray否挂载选项。如果省略,provider 将使用 defaults,noatime

*对于新清单,请设置 subnetName 或 subnetId 中的一个。现有清单可以继续使用 subenetName,并且仅当两个字段使用相同值时才可以添加 subnetName。不要提供相互冲突的子网选择器值。

指定 persistentDisks 时,必须填写持久磁盘字段。

对于必须在 VM 替换后保留的节点本地状态,请使用 persistentDisks[]。不要在 HCSMachineTemplate.spec.template.spec.dataVolumes[] 中声明相同的挂载路径。

注意:CRD schema 将 subnetName、subenetName 和 subnetId 列为可选字段,但未表达其允许的组合。编写清单时,请遵循上述 provider 级别的规则。

注意:要将多个 NIC 挂载到一个节点,请添加多个 networks[] 条目。provider 仅使用这些条目挂载 NIC,并分配子网选择器和静态 IP。它不支持声明每个 NIC 的角色、默认网关、静态路由或每个 NIC 的 DNS 设置。

节点上的主机名行为

provider 根据 hostname 推导节点的 POSIX 主机名和 FQDN,具体如下:

pool hostname 值节点 hostname节点 hostname -f写入的 /etc/hosts 条目
master-1(无点号)master-1master-1(解析器返回短名称)provider 不添加任何条目
master-1.example.org(包含点号)master-1(短标签,去除点号及其后的所有内容)master-1.example.org<node-ip> master-1.example.org master-1

包含点号的形式用于设置依赖 FQDN 解析的应用(hostname -f、包含 SAN 条目的证书和日志标签)。只有在提供包含点号的主机名时,provider 才会设置 prefer_fqdn_over_hostname: false 并启用 cloud-init manage_etc_hosts,因此 POSIX 工具仍会看到短名称,而 hostname -f 会返回完整的 FQDN。

无效的主机名(开头为点号、结尾为点号、全为点号的字符串、大写字母,或任何违反字段约束的值)会在 VM 启动前被拒绝。错误会设置在所属 Machine.status 上,并显示在 Cluster.status.conditions 中,因此会出现在 kubectl describe cluster <name> 和 kubectl get machines -n cpaas-system -o wide 下。

配置 Machine Template

HCSMachineTemplate 定义控制平面节点的 VM 规格。

WARNING

存储要求

建议为控制平面节点配置以下数据磁盘挂载点:

  • /var/lib/etcd - etcd 数据(10GB+)
  • /var/lib/kubelet - kubelet 数据(100GB+)
  • /var/lib/containerd - 容器运行时数据(100GB+)

/var/cpaas 路径存储平台状态和日志。当这些数据必须在 VM 替换后保留时,请在 HCSMachineConfigPool.spec.configs[].persistentDisks[] 中声明该路径。

apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: HCSMachineTemplate
metadata:
  name: <cluster-name>-control-plane
  namespace: cpaas-system
spec:
  template:
    spec:
      imageName: <vm-image-name>
      flavorName: <instance-flavor>
      availabilityZone: <availability-zone>
      rootVolume:
        type: SSD
        size: 100
      configPoolRef:
        name: <cluster-name>-cp-pool
      dataVolumes:
        - size: 10
          type: SSD
          mountPath: /var/lib/etcd
          format: xfs
        - size: 100
          type: SSD
          mountPath: /var/lib/kubelet
          format: xfs
        - size: 100
          type: SSD
          mountPath: /var/lib/containerd
          format: xfs
参数类型必填说明
.spec.template.spec.imageNamestring是HCS 镜像名称。使用为目标 ACP 版本发布的 Alauda OS 镜像上传时所用的名称;上方清单中以 <alaudaos-version> 作为占位符。该名称会随每个 Alauda OS 版本变化,因此不要在不同版本中硬编码示例值。
.spec.template.spec.flavorNamestring是Provider 可识别的 HCS API 值,与 Flavor.Name 匹配。请勿使用租户 UI 中显示的名称。
.spec.template.spec.availabilityZonestring否Provider 可识别的 HCS API 值,与 ZoneName 匹配。使用此模板创建的每台机器都会使用所选可用区。如果省略,Provider 会选择 HCS 报告为可用的可用区。请参阅可用区放置。
.spec.template.spec.rootVolume.typestring是卷类型(SSD 或 SATA)
.spec.template.spec.rootVolume.sizeint是系统磁盘大小,单位为 GB
.spec.template.spec.configPoolRef.namestring是引用的 HCSMachineConfigPool 名称
.spec.template.spec.dataVolumes[]array否数据卷配置
.spec.template.spec.dataVolumes[].sizeint是*数据磁盘大小,单位为 GB
.spec.template.spec.dataVolumes[].typestring是*卷类型
.spec.template.spec.dataVolumes[].mountPathstring是*挂载路径
.spec.template.spec.dataVolumes[].formatstring是*文件系统格式(xfs 或 ext4)

*指定 dataVolumes 时必填。

dataVolumes[] 会随 ECS 一起重新创建。请勿将其用于 /var/cpaas 或任何其他必须在滚动替换期间保留的路径。请将这些路径放在 HCSMachineConfigPool.spec.configs[].persistentDisks[] 中。

注意:请勿在 HCSMachineTemplate 清单中设置 providerID 或 serverId 等运行时身份字段。Provider 会在创建 HCS 实例时分配这些值。

注意:ACP Web UI 会通过所选 HCS 凭证加载 flavor 和可用区。编写 YAML 时,请向 HCS 管理员获取 Provider 可识别的确切 Flavor.Name 和 ZoneName 值,因为原生 HCS 租户控制台可能不会显示这些值。

配置 KubeadmControlPlane

KubeadmControlPlane 定义 Kubernetes 控制平面配置。

Kubernetes 1.35 kubelet 设置

只有从 Kubernetes 1.35 开始才需要 imagePullCredentialsVerificationPolicy: NeverVerify。使用 Kubernetes 1.34 或更早版本创建集群时,请省略此参数。

apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: KubeadmControlPlane
metadata:
  name: <cluster-name>-kcp
  namespace: cpaas-system
spec:
  replicas: 3
  version: <kubernetes-version>
  rolloutStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 0
  kubeadmConfigSpec:
    files:
      - path: /etc/kubernetes/admission/psa-config.yaml
        owner: root:root
        permissions: "0644"
        content: |
          apiVersion: apiserver.config.k8s.io/v1
          kind: AdmissionConfiguration
          plugins:
          - name: PodSecurity
            configuration:
              apiVersion: pod-security.admission.config.k8s.io/v1
              kind: PodSecurityConfiguration
              defaults:
                enforce: "privileged"
                enforce-version: "latest"
                audit: "baseline"
                audit-version: "latest"
                warn: "baseline"
                warn-version: "latest"
              exemptions:
                usernames: []
                runtimeClasses: []
                namespaces:
                - kube-system
                - cpaas-system
      - path: /etc/kubernetes/patches/kubeletconfiguration0+strategic.json
        owner: root:root
        permissions: "0644"
        content: |
          {
            "apiVersion": "kubelet.config.k8s.io/v1beta1",
            "kind": "KubeletConfiguration",
            "imagePullCredentialsVerificationPolicy": "NeverVerify",
            "protectKernelDefaults": true,
            "tlsCertFile": "/etc/kubernetes/pki/kubelet.crt",
            "tlsPrivateKeyFile": "/etc/kubernetes/pki/kubelet.key",
            "streamingConnectionIdleTimeout": "5m",
            "clientCAFile": "/etc/kubernetes/pki/ca.crt"
          }
      - path: /etc/kubernetes/encryption-provider.conf
        owner: root:root
        permissions: "0600"
        content: |
          apiVersion: apiserver.config.k8s.io/v1
          kind: EncryptionConfiguration
          resources:
          - resources:
            - secrets
            providers:
            - aescbc:
                keys:
                - name: key1
                  secret: bootstrap-placeholder
      - path: /etc/kubernetes/audit/policy.yaml
        owner: root:root
        permissions: "0644"
        content: |
          apiVersion: audit.k8s.io/v1
          kind: Policy
          rules:
          - level: Metadata
    clusterConfiguration:
      imageRepository: <image-repository>
      dns:
        imageTag: <dns-image-tag>
      etcd:
        local:
          imageTag: <etcd-image-tag>
      apiServer:
        extraArgs:
          audit-log-format: json
          audit-log-mode: batch
          audit-log-path: /etc/kubernetes/audit/audit.log
          audit-policy-file: /etc/kubernetes/audit/policy.yaml
          admission-control-config-file: /etc/kubernetes/admission/psa-config.yaml
          encryption-provider-config: /etc/kubernetes/encryption-provider.conf
          kubelet-certificate-authority: /etc/kubernetes/pki/ca.crt
          profiling: "false"
          tls-min-version: VersionTLS12
        extraVolumes:
          - name: vol-dir-0
            hostPath: /etc/kubernetes
            mountPath: /etc/kubernetes
            pathType: Directory
      controllerManager:
        extraArgs:
          bind-address: "::"
          flex-volume-plugin-dir: "/opt/libexec/kubernetes/kubelet-plugins/volume/exec/"
          profiling: "false"
          tls-min-version: VersionTLS12
      scheduler:
        extraArgs:
          bind-address: "::"
          profiling: "false"
          tls-min-version: VersionTLS12
    postKubeadmCommands:
      - chmod 600 /var/lib/kubelet/config.yaml
    initConfiguration:
      patches:
        directory: /etc/kubernetes/patches
      nodeRegistration:
        kubeletExtraArgs:
          node-labels: "kube-ovn/role=master"
          protect-kernel-defaults: "true"
          volume-plugin-dir: "/opt/libexec/kubernetes/kubelet-plugins/volume/exec/"
    joinConfiguration:
      patches:
        directory: /etc/kubernetes/patches
      nodeRegistration:
        kubeletExtraArgs:
          node-labels: "kube-ovn/role=master"
          volume-plugin-dir: "/opt/libexec/kubernetes/kubelet-plugins/volume/exec/"
  machineTemplate:
    nodeDrainTimeout: 1m
    nodeDeletionTimeout: 5m
    infrastructureRef:
      apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
      kind: HCSMachineTemplate
      name: <cluster-name>-control-plane

解析 cloud-init 数据时,HCS 控制器还会注入文件。对于控制平面机器,它会写入 /etc/kubernetes/pki/kubelet.crt、/etc/kubernetes/pki/kubelet.key 和 /etc/kubernetes/encryption-provider.conf。对于第一个控制平面机器,控制器会生成加密提供程序配置。控制平面初始化后,控制器会尝试复用现有的 kube-apiserver 加密提供程序配置。如果在 /etc/kubernetes/encryption-provider.conf 添加了引导文件,请将其视为占位文件,因为控制器生成或同步的文件优先级更高。

注意:请同时配置 apiServer.extraArgs 和 apiServer.extraVolumes。如果未挂载该卷,kube-apiserver 就无法读取写入 /etc/kubernetes 下的文件。

注意:上方的 rolloutStrategy.rollingUpdate.maxSurge: 0 示例适用于高可用静态 IP 控制平面。对于至少有三个副本的固定大小控制平面池,请保留此设置,以确保替换按先缩容再扩容的顺序进行。如果要创建单控制平面 HCS 集群(spec.replicas: 1),请勿将 rolloutStrategy 区块复制到创建清单中。KubeadmControlPlane 校验会拒绝针对单个副本的这种缩容式滚动更新配置。

注意:HCS 还支持通过设置 spec.replicas: 1,并在引用的 HCSMachineConfigPool 中准备一个控制平面配置条目,来创建单控制平面集群。请将其视为仅用于创建的拓扑,并在创建清单中不设置滚动更新策略。单控制平面 HCS 集群无法升级。

仅当OS 支持矩阵明确列出相关组件版本时,才使用其中的信息,例如受支持的 Alauda OS 镜像对应的 coredns 和 etcd 镜像标签。它并非所有 HCS 清单值的完整信息来源。应用此 YAML 前,还应根据已批准的版本基线设置 imageRepository、DNS 镜像仓库、Kube-OVN 版本、Kube-OVN join CIDR、Pod CIDR 和 Service CIDR 等值。

配置 HCSCluster

HCSCluster 资源定义 HCS 基础架构配置。

HCS Provider 会在 HCS 平台上为 Kubernetes API server 创建弹性负载均衡(ELB)。此 ELB 必须启用混合负载均衡,以便集群节点也能通过 ELB 地址访问 API server。

对于文档中介绍的 HCS 工作流,请提供 vipAddress、elbVirsubnetL4Ips 和 elbVirsubnetL7Ips。每个 elbVirsubnetL4Ips[].ips 和 elbVirsubnetL7Ips[].ips 条目都必须包含两个 IP。

请勿设置 vipDomainName——不支持通过域名访问集群;请参阅下方字段表。

请先在 spec.network.subnets 中列出集群的所有子网,再在其他位置引用这些子网。vipSubnetName、elbVirsubnetL4Ips[].subnetName、elbVirsubnetL7Ips[].subnetName 以及 HCSMachineConfigPool 使用的 subnetName 值,都必须存在于 spec.network.subnets 中。

在初始集群创建流程中,控制器可以从 name 解析现有子网元数据。对于已存在的 Ready 集群,请追加完整的子网对象,而不只是 name。请包含 id,并为控制平面 ELB 将使用的任何子网包含 neutronSubnetId。同时将 cidr、gatewayIp、primaryDNS 和 secondaryDNS 保留在子网清单中。

创建集群后,请勿禁用 Provider 创建的 ELB 上的混合负载均衡。集群依赖此 ELB 模式,以便节点能够通过 ELB 地址访问 API server。

apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: HCSCluster
metadata:
  name: <cluster-name>
  namespace: cpaas-system
spec:
  # Optional. Include only when you want provider-managed control-plane ECS placement.
  controlPlaneHA:
    enabled: true
    policy: soft-anti-affinity
  controlPlaneLoadBalancer:
    vipAddress: <control-plane-vip-address>
    vipSubnetName: <vip-subnet-name>
    elbVirsubnetL4Ips:
      - subnetName: <subnet-name>
        ips:
          - <l4-ip-1>
          - <l4-ip-2>
    elbVirsubnetL7Ips:
      - subnetName: <subnet-name>
        ips:
          - <l7-ip-1>
          - <l7-ip-2>
  networkType: kube-ovn
  network:
    vpc:
      name: <vpc-name>
    subnets:
      - name: <subnet-name>
    securityGroup:
      name: <security-group-name>
  identityRef:
    name: <credential-secret-name>
参数类型必填描述
.spec.networkTypestring是网络类型,目前支持 kube-ovn
.spec.network.vpc.namestring是VPC 名称
.spec.network.subnets[].namestring是集群子网清单中的子网名称。集群清单中其他位置引用的每个子网都必须出现在此列表中
.spec.network.subnets[].idstring建议填写子网 ID。对于已存在且处于 Ready 状态的集群,后续追加子网时请包含此值,以便安全地复用子网清单来创建机器
.spec.network.subnets[].neutronSubnetIdstring建议用于 ELB 子网Neutron 子网 ID。对于控制平面 ELB 使用的任何子网,请包含此值
.spec.network.subnets[].cidrstring建议填写保留在集群子网清单中的子网 CIDR
.spec.network.subnets[].gatewayIpstring建议填写保留在集群子网清单中的子网网关
.spec.network.subnets[].primaryDNSstring建议填写保留在集群子网清单中的主 DNS
.spec.network.subnets[].secondaryDNSstring建议填写保留在集群子网清单中的备用 DNS
.spec.network.securityGroup.namestring是安全组名称
.spec.identityRef.namestring是非空凭证 Secret 的名称,由 HCSCluster 引用;此值无需与集群名称匹配
.spec.controlPlaneHA.enabledbool设置 controlPlaneHA 时必填启用由 Provider 管理的服务器组,用于控制平面 ECS 放置
.spec.controlPlaneHA.policystring设置 controlPlaneHA 时必填服务器组放置策略。允许的值为 anti-affinity 和 soft-anti-affinity
.spec.controlPlaneLoadBalancerobject是Provider 创建的控制平面 ELB 的 ELB 设置
.spec.controlPlaneLoadBalancer.vipAddressstring是控制平面 ELB 的固定 VIP
.spec.controlPlaneLoadBalancer.vipSubnetNamestring是包含 ELB VIP 的子网名称。此子网也必须出现在 .spec.network.subnets 中
.spec.controlPlaneLoadBalancer.vipDomainNamestring否留空。Provider 仅使用此字段回填派生字段 controlPlaneEndpoint;不支持通过域名访问集群,且 API server 证书只能由集群自身的 CA 签发
.spec.controlPlaneLoadBalancer.elbVirsubnetL4Ips[]array是混合负载均衡使用的 L4 虚拟子网 IP 组
.spec.controlPlaneLoadBalancer.elbVirsubnetL4Ips[].subnetNamestring是L4 虚拟子网 IP 所在的子网名称。此子网也必须出现在 .spec.network.subnets 中
.spec.controlPlaneLoadBalancer.elbVirsubnetL4Ips[].ips[]string是两个固定的 L4 虚拟子网 IP
.spec.controlPlaneLoadBalancer.elbVirsubnetL7Ips[]array是混合负载均衡使用的 L7 虚拟子网 IP 组
.spec.controlPlaneLoadBalancer.elbVirsubnetL7Ips[].subnetNamestring是L7 虚拟子网 IP 所在的子网名称。此子网也必须出现在 .spec.network.subnets 中
.spec.controlPlaneLoadBalancer.elbVirsubnetL7Ips[].ips[]string是两个固定的 L7 虚拟子网 IP

请勿在创建清单中包含 spec.controlPlaneEndpoint。在 HCS 创建流程中,控制器会在创建 HCSCluster 后,从 spec.controlPlaneLoadBalancer 派生并填充此字段。请勿手动设置 controlPlaneEndpoint,也不要添加空的 controlPlaneEndpoint 对象。如果清单中明确包含 controlPlaneEndpoint,则必须同时包含 host 和 port。

controlPlaneHA 为可选项。如果包含此项,则必须同时设置 enabled 和 policy。严格隔离主机时请使用 anti-affinity。如果希望将主机分散放置,但不希望仅因 HCS 无法满足严格放置规则而导致 ECS 创建失败,请使用 soft-anti-affinity。有关规划指南(包括在现有集群上启用此功能时的滚动替换要求),请参阅 控制平面高可用放置计划。

配置 Cluster

Cluster API 中的 Cluster 资源用于声明集群,并引用控制平面和基础设施资源。

apiVersion: cluster.x-k8s.io/v1beta1
kind: Cluster
metadata:
  name: <cluster-name>
  namespace: cpaas-system
  annotations:
    cpaas.io/sentry-deploy-type: Baremetal
    cpaas.io/alb-address-type: ClusterAddress
    capi.cpaas.io/resource-group-version: infrastructure.cluster.x-k8s.io/v1beta1
    capi.cpaas.io/resource-kind: HCSCluster
    cpaas.io/kube-ovn-join-cidr: <kube-ovn-join-cidr>
    cpaas.io/kube-ovn-version: <kube-ovn-version>
  labels:
    cluster-type: HCS
spec:
  clusterNetwork:
    pods:
      cidrBlocks:
        - <pods-cidr>
    services:
      cidrBlocks:
        - <services-cidr>
  controlPlaneRef:
    apiVersion: controlplane.cluster.x-k8s.io/v1beta1
    kind: KubeadmControlPlane
    name: <cluster-name>-kcp
  infrastructureRef:
    apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
    kind: HCSCluster
    name: <cluster-name>
注解描述
cpaas.io/sentry-deploy-type部署类型,设置为 Baremetal
cpaas.io/alb-address-typeALB 地址类型,设置为 ClusterAddress
capi.cpaas.io/resource-group-version资源组版本
capi.cpaas.io/resource-kind资源类型,设置为 HCSCluster
cpaas.io/kube-ovn-join-cidrKube-OVN join 子网 CIDR
cpaas.io/kube-ovn-versionKube-OVN 版本

部署工作节点

仅有控制平面还不能构成可用的集群。控制平面达到 Ready 状态后,请按以下顺序创建工作节点资源。

准备工作节点 YAML 之前,请完成 Huawei Cloud Stack 的基础设施资源中的 HCS 输入检查清单。具体来说,请在 HCSCluster.spec.network.subnets 中列出每个工作节点子网,从规划的可用 IP 地址范围中分配工作节点 IP,并收集 Provider 认可的 flavorName 和 availabilityZone API 值。如果要向现有且处于 Ready 状态的集群添加新的工作节点子网,请使用完整子网对象更新 HCSCluster.spec.network.subnets,而不只是添加子网名称。

步骤 1:配置 Machine Configuration Pool

HCSMachineConfigPool 定义工作节点 VM 的网络配置以及由池管理的持久磁盘。部署前必须规划并配置 IP 地址、主机名、持久磁盘槽位及其他参数。

WARNING

池大小要求

池中条目的数量至少必须与计划部署的工作节点数量相同。条目不足将导致节点无法部署。

每个 networks[] 条目使用一个子网选择器。对于新清单,请设置 subnetName 或 subnetId,但不能同时设置。现有清单可以继续保留已弃用的 subenetName 字段;如果更新该清单时还添加了 subnetName,其值必须与 subenetName 完全一致。请勿在 subenetName、subnetName 和 subnetId 中提供冲突的值。

如果工作节点使用 subnetName,请在创建或扩容工作节点池之前,将相同的子网名称加入父级 HCSCluster.spec.network.subnets 列表。对于已存在且处于 Ready 状态的集群,请追加包含子网 ID 在内的完整子网对象,而不只是添加子网名称。

apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: HCSMachineConfigPool
metadata:
  name: <cluster-name>-worker-pool
  namespace: cpaas-system
  labels:
    cluster.x-k8s.io/cluster-name: <cluster-name>
spec:
  configs:
    - hostname: <worker-1-hostname>
      networks:
        - subnetName: <subnet-name>
          ipAddress: <worker-1-ip>
      persistentDisks:
        - slot: 0
          size: 100
          type: SSD
          mountPath: /var/cpaas
          format: xfs
    - hostname: <worker-2-hostname>
      networks:
        - subnetName: <subnet-name>
          ipAddress: <worker-2-ip>
      persistentDisks:
        - slot: 0
          size: 100
          type: SSD
          mountPath: /var/cpaas
          format: xfs
    - hostname: <worker-3-hostname>
      networks:
        - subnetName: <subnet-name>
          ipAddress: <worker-3-ip>
      persistentDisks:
        - slot: 0
          size: 100
          type: SSD
          mountPath: /var/cpaas
          format: xfs
参数类型必填描述
.spec.configs[]array是非空的工作节点配置列表
.spec.configs[].hostnamestring是VM 主机名。使用小写字母、数字、连字符(-)或点(.);值必须以小写字母或数字开头和结尾,且长度不得超过 253 个字符
.spec.configs[].networks[]array是VM 的非空网络配置列表
.spec.configs[].networks[].subnetNamestring否*新清单推荐使用的子网名称字段
.spec.configs[].networks[].subnetIdstring否*子网 ID。当子网名称存在歧义时,请使用此字段,而不是 subnetName
.spec.configs[].networks[].ipAddressstring是工作节点 VM 的静态 IP 地址
.spec.configs[].persistentDisks[]array否在 HCSMachine 删除并重新创建以进行替换后仍保留的 EVS 磁盘
.spec.configs[].persistentDisks[].slotint是*单个机器配置中的磁盘槽位。同一主机名下的槽位必须唯一,且从 0 起连续排列
.spec.configs[].persistentDisks[].sizeint是*EVS 磁盘大小,单位为 GB。对于新创建的 EVS 数据磁盘,请使用 10 至 32768 GB。已声明的现有磁盘必须与其当前大小一致
.spec.configs[].persistentDisks[].typestring是*目标可用区中可用的 EVS 磁盘类型名称
.spec.configs[].persistentDisks[].mountPathstring否来宾挂载路径。对于 VM 替换后必须保留的平台状态,请使用 /var/cpaas
.spec.configs[].persistentDisks[].formatstring否文件系统格式。省略时,Provider 使用 xfs
.spec.configs[].persistentDisks[].mountOptionsarray否挂载选项。省略时,Provider 使用 defaults,noatime

*对于新清单,请设置 subnetName 或 subnetId。现有清单可以继续使用 subenetName;只有在两个字段的值相同时,才可以添加 subnetName。请勿提供相互冲突的子网选择器值。

指定 persistentDisks 时,必须填写持久磁盘字段。

对于工作节点替换后必须保留的节点本地状态,请使用 persistentDisks[]。请勿在 HCSMachineTemplate.spec.template.spec.dataVolumes[] 中声明相同的挂载路径。

注意: CRD 架构将 subnetName、subenetName 和 subnetId 列为可选字段,且未说明这些字段允许的组合。编写清单时,请遵循上述 Provider 级别的规则。

注意: 当工作节点需要多个 NIC 时,networks[] 可以包含多个条目。当前 Provider 仅使用每个条目,通过子网选择器和静态 IP 附加 NIC。它不支持按 NIC 声明角色、选择默认网关、配置静态路由、路由度量值或按 NIC 配置 DNS。

工作节点池管理的持久磁盘

在对应的 HCSMachineConfigPool.spec.configs[].persistentDisks[] 条目中声明必须在工作节点替换后保留的磁盘。对于 /var/cpaas 以及其他必须在滚动替换期间保留的节点本地状态,请使用此模式。

  • 将 HCSMachineTemplate.spec.template.spec.dataVolumes[] 用于临时磁盘,这些磁盘可以随每个 ECS 重新创建。
  • 对每个主机名,槽位必须唯一,并从 0 起连续排列。Provider 使用 (hostname, slot) 作为持久磁盘标识。
  • Provider 接受条目后,请将 slot、size、type、format 和 mountPath 视为不可变字段。
  • 可以更新 mountOptions。更改将在工作节点替换后生效。
  • 可以追加新的 persistentDisks[] 条目。Provider 会创建或认领 EVS 磁盘,但不会将磁盘热挂载到正在运行的 ECS 中。请使用 MachineDeployment.spec.strategy.rollingUpdate.maxSurge: 0 触发滚动替换,然后再预期新磁盘已在来宾 OS 内完成格式化和挂载。

要在工作节点操作期间检查持久磁盘的运行时状态,请查看池状态:

kubectl get hcsmachineconfigpool <cluster-name>-worker-pool -n cpaas-system -o yaml

步骤 2:配置机器模板

HCSMachineTemplate 定义工作节点的 VM 规格。

为工作节点配置系统卷和临时数据卷,用于存放可随每个 ECS 重新创建的路径,例如 /var/lib/kubelet 和 /var/lib/containerd。当平台状态必须在工作节点替换后保留时,请将 /var/cpaas 放在 HCSMachineConfigPool.spec.configs[].persistentDisks[] 中。

准备工作节点模板时,请使用 Provider 识别的 flavorName 和 availabilityZone API 值。这些值不是租户 UI 中显示的名称。

apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: HCSMachineTemplate
metadata:
  name: <cluster-name>-worker-template
  namespace: cpaas-system
spec:
  template:
    spec:
      imageName: <vm-image-name>
      flavorName: <instance-flavor>
      availabilityZone: <availability-zone>
      rootVolume:
        type: SSD
        size: 100
      configPoolRef:
        name: <cluster-name>-worker-pool
      dataVolumes:
        - size: 20
          type: SSD
          mountPath: /var/lib/kubelet
          format: xfs
        - size: 20
          type: SSD
          mountPath: /var/lib/containerd
          format: xfs
参数类型必填描述
.spec.template.spec.imageNamestring是VM 镜像名称
.spec.template.spec.flavorNamestring是Provider 识别的 HCS API 值,与 Flavor.Name 匹配
.spec.template.spec.availabilityZonestring否Provider 识别的 HCS API 值,与 ZoneName 匹配。使用此模板创建的每个工作节点都使用所选可用区。如果省略,Provider 会选择 HCS 报告为可用的可用区。请参阅可用区放置
.spec.template.spec.rootVolume.typestring是卷类型
.spec.template.spec.rootVolume.sizeint是系统磁盘大小,单位为 GB
.spec.template.spec.configPoolRef.namestring是引用的 HCSMachineConfigPool 名称
.spec.template.spec.dataVolumes[]array否数据卷配置
.spec.template.spec.dataVolumes[].sizeint是*磁盘大小,单位为 GB
.spec.template.spec.dataVolumes[].typestring是*卷类型
.spec.template.spec.dataVolumes[].mountPathstring是*挂载路径
.spec.template.spec.dataVolumes[].formatstring是*文件系统格式

*指定 dataVolumes 时必填。

dataVolumes[] 会随 ECS 重新创建。请勿将其用于 /var/cpaas 或任何其他必须在滚动替换后保留的路径。

注意: 请勿在 HCSMachineTemplate 清单中设置 providerID 或 serverId 等运行时身份字段。Provider 会在创建 HCS 实例时分配这些值。

注意: ACP Web UI 会通过所选 HCS 凭证加载规格和可用区。编写 YAML 时,请向 HCS 管理员获取 Provider 识别的确切 Flavor.Name 和 ZoneName 值,因为 HCS 原生租户控制台可能不会显示这些值。

步骤 3:配置引导模板

KubeadmConfigTemplate 定义工作节点的引导配置。

只有从 Kubernetes 1.35 开始才需要 imagePullCredentialsVerificationPolicy: NeverVerify。使用 Kubernetes 1.34 或更早版本创建工作节点时,请省略此参数。

apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
kind: KubeadmConfigTemplate
metadata:
  name: <cluster-name>-worker-kct
  namespace: cpaas-system
spec:
  template:
    spec:
      files:
        - path: /etc/kubernetes/patches/kubeletconfiguration0+strategic.json
          owner: root:root
          permissions: "0644"
          content: |
            {
              "apiVersion": "kubelet.config.k8s.io/v1beta1",
              "kind": "KubeletConfiguration",
              "imagePullCredentialsVerificationPolicy": "NeverVerify",
              "protectKernelDefaults": true,
              "staticPodPath": null,
              "tlsCertFile": "/etc/kubernetes/pki/kubelet.crt",
              "tlsPrivateKeyFile": "/etc/kubernetes/pki/kubelet.key",
              "streamingConnectionIdleTimeout": "5m",
              "clientCAFile": "/etc/kubernetes/pki/ca.crt"
            }
      postKubeadmCommands:
        - chmod 600 /var/lib/kubelet/config.yaml
      joinConfiguration:
        patches:
          directory: /etc/kubernetes/patches
        nodeRegistration:
          kubeletExtraArgs:
            volume-plugin-dir: "/opt/libexec/kubernetes/kubelet-plugins/volume/exec/"

解析工作节点 cloud-init 数据时,HCS 控制器会注入 /etc/kubernetes/pki/kubelet.crt 和 /etc/kubernetes/pki/kubelet.key。上面的 kubelet 补丁将 kubelet 配置为使用这些由控制器提供的证书文件。

步骤 4:配置机器部署

MachineDeployment 负责协调工作节点的创建和管理。

apiVersion: cluster.x-k8s.io/v1beta1
kind: MachineDeployment
metadata:
  name: <cluster-name>-md-0
  namespace: cpaas-system
spec:
  clusterName: <cluster-name>
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 0
      maxUnavailable: 1
  template:
    spec:
      clusterName: <cluster-name>
      version: <kubernetes-version>
      nodeDrainTimeout: 1m
      nodeDeletionTimeout: 5m
      bootstrap:
        configRef:
          apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
          kind: KubeadmConfigTemplate
          name: <cluster-name>-worker-kct
      infrastructureRef:
        apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
        kind: HCSMachineTemplate
        name: <cluster-name>-worker-template
参数类型必填描述
.spec.clusterNamestring是目标集群名称
.spec.replicasint是工作节点数量
.spec.template.spec.bootstrap.configRefobject是对 KubeadmConfigTemplate 的引用
.spec.template.spec.infrastructureRefobject是对 HCSMachineTemplate 的引用
.spec.template.spec.versionstring是Kubernetes 版本
.spec.strategy.rollingUpdate.maxSurgeint否更新期间高于期望数量的最大节点数
.spec.strategy.rollingUpdate.maxUnavailableint否更新期间不可用节点的最大数量

集群验证

部署所有集群资源后,验证集群是否已成功创建。

使用 kubectl

# Check cluster status
kubectl get cluster -n cpaas-system <cluster-name>

# Verify control plane nodes
kubectl get kubeadmcontrolplane -n cpaas-system <cluster-name>-kcp

# Check machine status
kubectl get machines -n cpaas-system

# Verify cluster deployment status
kubectl get clustermodule <cluster-name> -o jsonpath='{.status.base.deployStatus}'

验证控制平面 HA

如果启用了 HCSCluster.spec.controlPlaneHA,请先检查 HCSCluster 条件:

kubectl get hcscluster <cluster-name> -n cpaas-system \
  -o jsonpath='{range .status.conditions[?(@.type=="ControlPlaneHAReady")]}{.status}{" "}{.reason}{" "}{.message}{"\n"}{end}'

按以下方式解释该条件:

状态和原因含义后续步骤
True ControlPlaneHAReady提供商管理的服务器组存在,且当前控制平面 ECS 成员已被跟踪。无需执行任何操作。
False ControlPlaneHAPending提供商正在等待可恢复状态,例如 ECS 创建完成或服务器组成员关系收敛。阅读消息,并等待其中引用的控制平面机器或 ECS 操作完成。
False ControlPlaneHAFailed提供商无法创建、验证、更新或清理服务器组,或者 HCS 拒绝按照所选策略进行 ECS 调度。阅读消息,然后根据需要检查 HCS 容量、所选策略和控制器日志。

检查观测到的服务器组和成员关系快照:

kubectl get hcscluster <cluster-name> -n cpaas-system \
  -o jsonpath='serverGroup={.status.controlPlaneHA.name}{" id="}{.status.controlPlaneHA.id}{" policy="}{.status.controlPlaneHA.policy}{"\n"}{range .status.controlPlaneHA.members[*]}{.machineName}{" "}{.serverID}{"\n"}{end}'

对于 anti-affinity,HCS 将服务器组策略视为硬调度约束。如果容量不足,ECS 创建可能会失败,此时应将条件消息作为首要诊断信号。对于 soft-anti-affinity,HCS 会尝试分散成员,但仍可能将多个 ECS 实例放置在同一主机上。

预期结果

成功创建的集群应显示:

  • 集群状态:运行中 或 已置备
  • 所有控制平面机器:运行中
  • Kubernetes 节点:就绪
  • 集群模块状态:已完成

管理节点

有关扩缩容、模板更新和 Web UI 节点池等日常节点操作,请参阅在 Huawei Cloud Stack 上管理节点。

升级集群

有关升级集群组件的说明,请参阅升级 Kubernetes。

故障排除

如果集群达到 Provisioned,但始终未变为就绪状态(例如,由于未部署 CNI,业务节点一直处于 NotReady 状态),请先参阅与提供商无关的排查卡在已置备状态的业务集群。

有关 HCS 特有的故障模式(例如,由于带点号的 HCSMachineConfigPool 主机名生成了包含点号的 POSIX 主机名,导致 kubeadm init 始终无法完成),请参阅排查 Huawei Cloud Stack 业务集群故障。