在 Huawei Cloud Stack 上管理节点

本文档说明如何在 Huawei Cloud Stack 平台上使用 Cluster API Machine 资源管理 worker 节点。

前提条件

WARNING

重要前提条件

  • 在执行节点操作之前,必须先部署控制平面。有关设置说明,请参见 创建集群
  • 确保您对 HCS 平台具有适当的访问权限和所需的权限。

使用本文档中的 YAML 示例时,仅替换 <> 中的值,使其与环境相关。除非集群策略要求不同的值,否则请保留其余字段不变。

概述

worker 节点通过 Cluster API Machine 资源进行管理,从而提供声明式和自动化的节点生命周期管理。部署过程包括:

  1. Machine Configuration Pool - worker 节点的网络设置
  2. Machine Template - VM 规格
  3. Bootstrap Configuration - 节点初始化设置
  4. Machine Deployment - 节点创建和管理编排

worker 节点部署

在准备 worker YAML 之前,请先完成 Huawei Cloud Stack 基础设施资源 中的 HCS 输入检查清单。特别是,要在 HCSCluster.spec.network.subnets 中列出每个 worker 子网,从规划好的空闲 IP 范围中分配 worker IP,并收集 provider 可识别的 flavorNameavailabilityZone API 值。如果您要向现有 Ready 集群添加新的 worker 子网,请使用完整的子网对象更新 HCSCluster.spec.network.subnets,而不是仅添加子网名称。

步骤 1:配置 Machine Configuration Pool

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

WARNING

池大小要求

池中的条目数必须至少与您计划部署的 worker 节点数相同。条目不足将阻止节点部署。

每个 networks[] 条目使用一个子网选择器。对于新的 manifest,请设置 subnetNamesubnetId 其中之一,但不要同时设置两者。现有 manifest 可以保留已弃用的 subenetName 字段;如果您在更新该 manifest 时同时添加 subnetName,其值必须与 subenetName 完全一致。不要在 subenetNamesubnetNamesubnetId 之间提供冲突的值。

如果您为 worker 节点使用 subnetName, 在创建或扩容 worker 池之前,请在父级 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非空的 worker 节点配置列表
.spec.configs[].hostnamestringVM 主机名。使用小写字母、数字、连字符(-)或点(.);值必须以小写字母或数字开头和结尾,且长度不得超过 253 个字符
.spec.configs[].networks[]arrayVM 的非空网络配置列表
.spec.configs[].networks[].subnetNamestring否*新 manifest 推荐使用的子网名称字段
.spec.configs[].networks[].subnetIdstring否*子网 ID。当子网名称不明确时,请使用此字段代替 subnetName
.spec.configs[].networks[].ipAddressstringworker VM 的静态 IP 地址
.spec.configs[].persistentDisks[]array在 HCSMachine delete-recreate 替换后仍然保留的 EVS 磁盘
.spec.configs[].persistentDisks[].slotint是*单个机器配置中的磁盘槽位。对于同一 hostname,槽位必须唯一,且从 0 开始连续
.spec.configs[].persistentDisks[].sizeint是*EVS 磁盘大小,单位为 GB。对于新创建的 EVS 数据盘,请使用 1032768 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

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

当指定 persistentDisks 时,持久化磁盘字段为必填。

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

注意: CRD schema 将 subnetNamesubenetNamesubnetId 列为可选字段,但未表达它们允许的组合。编写 manifest 时,请遵循上述 provider 级别规则。

注意: 当 worker 节点需要多个 NIC 时,networks[] 可以包含多个条目。当前 provider 仅将每个条目用于附加一个带有子网选择器和静态 IP 的 NIC。不支持按 NIC 声明角色、默认网关选择、静态路由、路由度量或按 NIC 的 DNS 设置。

worker 的池管理持久化磁盘

将必须在替换后仍然保留的 worker 节点磁盘声明在匹配的 HCSMachineConfigPool.spec.configs[].persistentDisks[] 条目中。对于 /var/cpaas 以及在滚动替换期间必须保留的任何其他节点本地状态,请使用此模型。

  • 将临时磁盘保留在 HCSMachineTemplate.spec.template.spec.dataVolumes[] 中,这些磁盘可能会随每个 ECS 重新创建。
  • 对于每个 hostname,保持槽位唯一且从 0 开始连续。provider 使用 (hostname, slot) 作为持久化磁盘标识。
  • 在 provider 接受条目后,将 slotsizetypeformatmountPath 视为不可变。
  • 您可以更新 mountOptions。该变更会在 worker 替换后生效。
  • 您可以追加新的 persistentDisks[] 条目。provider 会创建或认领该 EVS 磁盘,但不会在运行中的 ECS 中热挂载该磁盘。在您期望新磁盘在客户机操作系统内完成格式化并挂载之前,请通过 MachineDeployment.spec.strategy.rollingUpdate.maxSurge: 0 触发滚动替换。

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

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

步骤 2:配置 Machine Template

HCSMachineTemplate 定义 worker 节点的 VM 规格。

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

在准备 worker 模板时,请使用 provider 可识别的 flavorNameavailabilityZone 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.imageNamestringVM 镜像名称
.spec.template.spec.flavorNamestringFlavor.Name 匹配的 provider 可识别 HCS API 值
.spec.template.spec.availabilityZonestringZoneName 匹配的 provider 可识别 HCS API 值
.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 manifest 中设置运行时标识字段,例如 providerIDserverId。provider 会在创建 HCS 实例时分配这些值。

注意: 租户管理员无法从 HCS UI 中检索 provider 可识别的 flavorNameavailabilityZone 值。在应用 manifest 之前,请从 HCS 管理员处获取确切值。

步骤 3:配置 Bootstrap Template

KubeadmConfigTemplate 定义 worker 节点的引导配置。

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",
              "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/"

HCS controller 在解析 worker cloud-init 数据时会注入 /etc/kubernetes/pki/kubelet.crt/etc/kubernetes/pki/kubelet.key。上面的 kubelet patch 会配置 kubelet 使用这些由 controller 提供的证书文件。

步骤 4:配置 Machine Deployment

MachineDeployment 负责编排 worker 节点的创建和管理。

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.replicasintworker 节点数量
.spec.template.spec.bootstrap.configRefobject对 KubeadmConfigTemplate 的引用
.spec.template.spec.infrastructureRefobject对 HCSMachineTemplate 的引用
.spec.template.spec.versionstringKubernetes 版本
.spec.strategy.rollingUpdate.maxSurgeint更新期间高于期望值的最大节点数
.spec.strategy.rollingUpdate.maxUnavailableint更新期间不可用节点的最大数量

节点管理操作

本节介绍管理 worker 节点的常见操作任务。

扩容 worker 节点

worker 节点扩容允许您根据工作负载需求调整集群容量。

添加 worker 节点

增加 worker 节点数量以处理更高的工作负载。

操作步骤

  1. 检查当前节点状态

    # List all machines in the cluster
    kubectl get machines -n cpaas-system
    
    # List machines for a specific MachineDeployment
    kubectl get machines -n cpaas-system -l cluster.x-k8s.io/deployment-name=<cluster-name>-md-0
  2. 扩展配置池

    为新增节点向池中添加新的机器配置。如果新的 worker 需要保留节点本地状态,例如 /var/cpaas,请在每个新配置中包含匹配的 persistentDisks[] 条目。

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

    修改池以包含新的 IP 条目,然后应用:

    kubectl apply -f <updated-pool-config.yaml>

    编辑池时,请保持所有现有的 configs[] 条目及其已接受的 persistentDisks[] 条目不变,除非您有意追加新的磁盘槽位。

  3. 扩容 MachineDeployment

    replicas 字段更新为所需的节点数量:

    kubectl patch machinedeployment <cluster-name>-md-0 -n cpaas-system \
      --type='json' -p='[{"op": "replace", "path": "/spec/replicas", "value": <new-replica-count>}]'
  4. 监控扩容进度

    # Watch machines being created
    kubectl get machines -n cpaas-system -w
    
    # Check MachineDeployment status
    kubectl get machinedeployment <cluster-name>-md-0 -n cpaas-system

移除 worker 节点

减少 worker 节点数量以降低集群容量。

WARNING

数据丢失警告

缩容会移除 worker 节点及其 ECS 实例。由模板拥有的 dataVolumes[] 不会被保留。在 HCSMachineConfigPool.spec.configs[].persistentDisks[] 中声明的池管理持久化磁盘会继续由池跟踪,并且只要对应的 hostname 条目仍保留在池中,就可以复用。请确保:

  • 工作负载能够通过适当的复制机制容忍节点丢失
  • 没有关键数据仅存储在被移除的节点上
  • 应用程序针对横向扩展进行了设计

操作步骤

  1. 缩容 MachineDeployment

    kubectl patch machinedeployment <cluster-name>-md-0 -n cpaas-system \
      --type='json' -p='[{"op": "replace", "path": "/spec/replicas", "value": <new-replica-count>}]'
  2. 监控移除进度

    kubectl get machines -n cpaas-system -w

    Cluster API controller 将会:

    • 排空选定节点(如果可能则驱逐 pod)
    • 从 HCS 平台删除底层 VM
    • 删除 machine 资源

升级 Machine 基础设施

要升级 worker machine 规格(CPU、内存、磁盘、VM 镜像),请按以下步骤操作:

注意: worker 基础设施升级依赖 Cluster API 的滚动替换。HCS dataVolumes[] 在替换期间不会被保留。若要保留诸如 /var/cpaas 之类的节点本地状态,请在 rollout 之前将其声明在 HCSMachineConfigPool.spec.configs[].persistentDisks[] 中,并保持 MachineDeployment.spec.strategy.rollingUpdate.maxSurge: 0

  1. 创建新的 Machine Template

    复制现有的 HCSMachineTemplate 并修改所需值:

    • imageName - VM 镜像
    • flavorName - 实例类型
    • rootVolume.size - 系统盘大小
    • dataVolumes - 临时数据盘配置

    如果您需要添加新的池管理持久化磁盘,请先将其追加到 worker HCSMachineConfigPool 中。provider 会创建或认领该 EVS 磁盘,但运行中的 ECS 不会挂载它,直到这次滚动替换创建出替代的 worker。

    kubectl get hcsmachinetemplate <current-template> -n cpaas-system -o yaml > new-template.yaml

    然后在应用前编辑 new-template.yaml

    • metadata.name 更改为 <new-template>
    • 保留运行时标识字段为空,包括 spec.template.spec.providerIDspec.template.spec.serverId
    • 删除由 server 生成的字段,例如:
      • metadata.resourceVersion
      • metadata.uid
      • metadata.creationTimestamp
      • metadata.managedFields
      • status
  2. 部署新的 Template

    kubectl apply -f new-template.yaml -n cpaas-system
  3. 更新 Machine Deployment

    修改 MachineDeployment 以引用新的 template:

    kubectl patch machinedeployment <cluster-name>-md-0 -n cpaas-system \
      --type='merge' -p='{"spec":{"template":{"spec":{"infrastructureRef":{"name":"<new-template>"}}}}}'
  4. 监控滚动更新

    kubectl get machines -n cpaas-system -w

升级 Kubernetes 版本

Kubernetes 版本升级需要同时协调更新 MachineDeployment 和底层 VM template。

注意: 请确保 VM template 的 Kubernetes 版本与 MachineDeployment 中指定的版本一致。版本不匹配会导致节点加入失败。

操作步骤

  1. 更新 Machine Template

    创建一个新的 HCSMachineTemplate,并使用支持目标 Kubernetes 版本的更新后 imageName

  2. 更新 MachineDeployment

    修改以下字段:

    • spec.template.spec.version - 目标 Kubernetes 版本

    • spec.template.spec.infrastructureRef.name - 新的 machine template 名称

      kubectl patch machinedeployment <cluster-name>-md-0 -n cpaas-system \
        --type='merge' -p='{"spec":{"template":{"spec":{"version":"<kubernetes-version>","infrastructureRef":{"name":"<new-template>"}}}}}'
  3. 监控升级

    验证新节点是否以正确的 Kubernetes 版本加入集群:

    kubectl get nodes

验证

部署 worker 节点后,请验证部署结果:

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

# Verify nodes are Ready
kubectl get nodes

# Check MachineDeployment status
kubectl get machinedeployment -n cpaas-system

故障排查

查看 Controller 日志

# View HCS controller logs
kubectl logs -n cpaas-system deployment/hcs-controller-manager

# View machine details
kubectl describe hcsmachine <machine-name> -n cpaas-system

常见问题

节点无法加入集群

  • 验证 VM template 是否与 Kubernetes 版本匹配
  • 检查节点之间的网络连通性
  • 确保配置池中有可用条目

Machine 卡在 provisioning 中

  • 检查 HCS 平台的资源可用性
  • 验证凭据和权限
  • 查看 controller 日志中的错误消息