在 Huawei DCS 上管理节点

本文档说明如何使用 Cluster API Machine 资源管理 Worker 节点。

前提条件

WARNING

重要前提条件

  • 必须先部署控制平面,然后才能执行节点操作。有关设置说明,请参见 创建集群。
  • 确保你拥有对 DCS 平台的适当访问权限以及所需权限。
INFO

配置指南 在使用本文档中的配置时:

  • 仅修改 <> 括号中的值
  • 将占位符值替换为你的环境特定设置
  • 除非明确要求,否则请保留所有其他默认配置

概述

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

  1. IP-Hostname 池配置 - Worker 节点的网络设置
  2. Machine 模板设置 - 虚拟机规格
  3. Bootstrap 配置 - 节点初始化和加入设置
  4. Machine Deployment - 节点创建和管理的编排

部署 Worker 节点

步骤 1:配置 IP-Hostname 池

IP-Hostname 池定义 Worker 节点虚拟机的网络配置。在部署之前,必须规划并配置 IP 地址、主机名、DNS 服务器、额外 NIC 以及其他网络参数。

在 Huawei DCS 上,IP 池也是声明必须在虚拟机替换后保留的持久磁盘的位置。对平台所需的 /var/cpaas 磁盘,以及在删除-重建操作期间必须保留的任何其他 Worker 节点磁盘,请使用 persistentDisk。此工作流需要 DCS provider v1.0.16 或更高版本。

当节点模板在 /var/lib/containerd 声明专用数据磁盘时,DCS provider 的 bootstrap 配置会将 Pod 日志存储在 /var/lib/containerd/pods 下,并将 /var/log/pods 链接到该路径。如果需要将 Pod 日志数据保留在 containerd 数据磁盘上,请在替换节点时保持该磁盘挂载在 /var/lib/containerd。

WARNING

池大小要求 池中的条目数量必须至少等于计划部署的 Worker 节点数量。条目不足将导致无法部署节点。

示例:

创建一个名为 <cluster-name>-worker-pool 的 DCSIpHostnamePool:

apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: DCSIpHostnamePool
metadata:
  name: <cluster-name>-worker-pool
  namespace: cpaas-system
spec:
  pool:
  - ip: "<worker-ip-1>"
    mask: "<worker-cidr-prefix-length>"
    gateway: "<worker-gateway>"
    dns: "<worker-dns>"
    hostname: "<worker-hostname-1>"
    machineName: "<worker-machine-name-1>"
    additionNic:
    - ip: "<worker-additional-ip-1>"
      mask: "<worker-additional-cidr-prefix-length>"
      gateway: "<worker-additional-gateway>"
      dns: "<worker-additional-dns>"
      dvSwitchName: "<additional-dvs>"
      portGroupName: "<additional-port-group>"
    persistentDisk:
    - slot: 0
      quantityGB: 40
      datastoreClusterName: <datastore-cluster-name>
      path: /var/cpaas
      format: xfs
  - ip: "<worker-ip-2>"
    mask: "<worker-cidr-prefix-length>"
    gateway: "<worker-gateway>"
    dns: "<worker-dns>"
    hostname: "<worker-hostname-2>"
    machineName: "<worker-machine-name-2>"
    persistentDisk:
    - slot: 0
      quantityGB: 40
      datastoreClusterName: <datastore-cluster-name>
      path: /var/cpaas
      format: xfs
  - ip: "<worker-ip-3>"
    mask: "<worker-cidr-prefix-length>"
    gateway: "<worker-gateway>"
    dns: "<worker-dns>"
    hostname: "<worker-hostname-3>"
    machineName: "<worker-machine-name-3>"
    persistentDisk:
    - slot: 0
      quantityGB: 40
      datastoreClusterName: <datastore-cluster-name>
      path: /var/cpaas
      format: xfs

关键参数:

参数类型描述是否必填
.spec.pool[].ipstringWorker 虚拟机的 IP 地址是
.spec.pool[].maskstring子网掩码,采用不带 / 的 CIDR 前缀长度格式,例如 24是
.spec.pool[].gatewaystring网关 IP 地址是
.spec.pool[].dnsstringDNS 服务器 IP 地址(多个时以分号分隔)否
.spec.pool[].machineNamestringDCS 平台中的虚拟机名称否
.spec.pool[].hostnamestring虚拟机的主机名否
.spec.pool[].additionNic[][]object绑定到此 IP 槽位的额外 NIC。用于存储、管理或隔离的应用网络。否
.spec.pool[].additionNic[].ipstring用于生成的客户机网络配置的额外 NIC IP 地址。建议*
.spec.pool[].additionNic[].maskstring额外 NIC 的子网掩码,采用不带 / 的 CIDR 前缀长度格式,例如 24。建议*
.spec.pool[].additionNic[].gatewaystring额外 NIC 网络的网关。设置此值前请确认路由行为。否
.spec.pool[].additionNic[].dnsstring额外 NIC 网络的 DNS 服务器 IP,多个值时以分号分隔。否
.spec.pool[].additionNic[].dvSwitchNamestring用于解析额外 NIC 的 Port Group 的 DCS 分布式虚拟交换机。是*
.spec.pool[].additionNic[].portGroupNamestring用于附加额外 NIC 的 DCS Port Group。是*
.spec.pool[].persistentDisk[][]object绑定到此 IP 槽位的持久磁盘。用于 /var/cpaas 以及必须在节点替换后保留的任何磁盘。否

*标记为 是* 的字段是 provider 解析目标网络并附加额外 NIC 所必需的。标记为 建议* 的字段是生成静态客户机网络配置所需要的。CRD 不会强制要求这些字段。

步骤 2:配置 Machine 模板

DCSMachineTemplate 定义 Worker 节点虚拟机的规格,包括虚拟机模板、计算资源、存储配置和网络设置。

此资源中的字段引用多个 Huawei DCS 平台概念(DCS VM Template、DCS VM Folder、DCS Datastore 及相关项)。有关这些概念的定义及其与 Cluster API 资源的映射关系,请参见 Huawei DCS 概念与术语。

WARNING

必需的磁盘配置 以下磁盘挂载点为必需项。请勿删除:

  • 系统卷(systemVolume: true)
  • /var/lib/kubelet - Kubelet 数据目录
  • /var/lib/containerd - 容器运行时数据

请在 IP 池中将 /var/cpaas 配置为持久磁盘,而不是在 DCSMachineTemplate 中配置。

你可以添加额外的模板磁盘,但必须保留这些必要的模板磁盘。

示例:

创建一个名为 <cluster-name>-worker-template 的 DCSMachineTemplate:

apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: DCSMachineTemplate
metadata:
  name: <cluster-name>-worker-template
  namespace: cpaas-system
spec:
  template:
    spec:
      vmTemplateName: <vm-template-name>
      location:
        type: folder
        name: <folder-name>
      vmConfig:
        dvSwitchName: <dv-switch-name> # Optional
        portGroupName: <port-group-name> # Optional
        dcsMachineCpuSpec:
          quantity: <worker-cpu>
        dcsMachineMemorySpec: # MB
          quantity: <worker-memory>
        dcsMachineDiskSpec: # GB
        - quantity: 0
          datastoreClusterName: <datastore-cluster-name>
          systemVolume: true
        - quantity: 100
          datastoreClusterName: <datastore-cluster-name>
          path: /var/lib/kubelet
          format: xfs
        - quantity: 100
          datastoreClusterName: <datastore-cluster-name>
          path: /var/lib/containerd
          format: xfs
      ipHostPoolRef:
        name: <cluster-name>-worker-pool

关键参数:

参数类型描述是否必填
.spec.template.spec.vmTemplateNamestring在 DCS 平台上注册的 DCS VM Template 名称。是
.spec.template.spec.locationobject将克隆的虚拟机放置在 DCS VM Folder 下以便进行组织分组。如果省略,则不会将虚拟机放入任何文件夹。有关 VM Folder 的定义,请参见 Huawei DCS 概念与术语;有关此字段在多集群中的用途,请参见 基础设施 → 高级:多集群部署。否
.spec.template.spec.location.typestring对于标准工作流,设置为 folder。该文件夹必须已在 DCS 平台上存在。是*
.spec.template.spec.location.namestring现有 DCS VM Folder 的名称。是*
.spec.template.spec.vmConfigobject虚拟机配置是
.spec.template.spec.vmConfig.dvSwitchNamestring虚拟交换机名称(未指定时使用模板默认值)否
.spec.template.spec.vmConfig.portGroupNamestringPort Group 名称(必须属于指定的交换机)否
.spec.template.spec.vmConfig.dcsMachineCpuSpec.quantityintWorker 虚拟机的 CPU 核数是
.spec.template.spec.vmConfig.dcsMachineMemorySpec.quantityint内存大小(MB)是
.spec.template.spec.vmConfig.dcsMachineDiskSpec[]object磁盘配置数组是
.spec.template.spec.vmConfig.dcsMachineDiskSpec[].quantityint磁盘大小(GB)(系统磁盘为 0 时使用模板大小)是
.spec.template.spec.vmConfig.dcsMachineDiskSpec[].datastoreClusterNamestringDatastore 集群名称是
.spec.template.spec.vmConfig.dcsMachineDiskSpec[].systemVolumebool系统磁盘标志(只能有一个磁盘为 true)否
.spec.template.spec.vmConfig.dcsMachineDiskSpec[].pathstring挂载路径(省略则不挂载磁盘)否
.spec.template.spec.vmConfig.dcsMachineDiskSpec[].formatstring文件系统格式(例如 xfs、ext4)否
.spec.template.spec.ipHostPoolRef.namestring引用的 DCSIpHostnamePool 名称是

*在指定父对象时为必填

由 IP 池管理的持久磁盘

在匹配的 DCSIpHostnamePool.spec.pool[].persistentDisk 条目中声明任何升级时需保留的磁盘(DCS provider v1.0.16 或更高版本)。

  • 将此用于平台所需的 /var/cpaas。
  • 系统磁盘以及可能随虚拟机一起重建的模板本地磁盘仍使用 DCSMachineTemplate。
  • 为每个 IP 条目选择唯一的 slot。控制器使用 (ip, slot) 作为持久磁盘的标识。
  • 在替换节点上,客户机磁盘设置逻辑会检查是否已存在文件系统。如果磁盘已经格式化,则跳过 mkfs 并直接挂载磁盘。
  • 持久磁盘工作流需要逐个替换,因此请保持 MachineDeployment.spec.strategy.rollingUpdate.maxSurge = 0。
  • 你可以追加新的 persistentDisk 条目,但不支持删除现有条目。控制器会在 DCS 侧将新添加的磁盘附加到正在运行的虚拟机,但不会在客户机操作系统内格式化或挂载该磁盘。客户机的格式化和挂载仅在虚拟机被替换且替换后的虚拟机在 bootstrap 期间运行生成的磁盘设置后才会生效。
  • 控制器将新的持久卷创建为独立的持久普通卷。当复用现有卷时,仅要求该卷为独立且持久的卷;不要求特定的 DCS 卷类型。
  • 将 format、options 和 pciType 视为创建后不可变。
  • 仅当 DCS 环境要求为新创建的持久卷显式指定精简配置(thin-provisioning)值时,才使用 isThin。如果省略,provider 不会发送 isThin,DCS 将使用平台默认值。
  • 将 quantityGB 和 datastore 的变更视为会触发滚动更新的敏感变更。当 webhook 具有足够的集群上下文时,会尽力对 DCS 平台执行校验。isThin 仅在创建时生效:更改该值不会校验、协调或转换现有卷,仅影响之后创建的持久卷。

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

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

由 IP 池管理的额外 NIC

在 DCSIpHostnamePool.spec.pool[].additionNic[] 中声明 Worker 的额外 NIC。

  • provider 仅在创建新虚拟机时应用 additionNic[]。
  • 编辑池时,不会对现有 Worker 虚拟机进行热更新。
  • 新的 Worker Machine 使用其所占用的池槽位中的 additionNic[] 值。
  • 每个额外 NIC 都应同时包含 dvSwitchName 和 portGroupName,以便 provider 在克隆虚拟机之前解析目标 DCS Port Group。
  • 如果同时使用 persistentDisk[],请保持 MachineDeployment.spec.strategy.rollingUpdate.maxSurge = 0,以便固定 IP 槽位和保留的磁盘一次只迁移一个节点。
  • 如果额外 NIC 配置了网关,请确认客户机操作系统的路由表仍然优先使用预期的主网络作为默认路由。

要检查额外 NIC 的运行时状态,请查看 DCSMachine.status.additionalNic:

kubectl -n cpaas-system get dcsmachine -l cluster.x-k8s.io/cluster-name=<cluster-name> \
  -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.networkConfig.ip}{"\t"}{.status.additionalNic}{"\n"}{end}'

步骤 3:配置 Bootstrap 模板

KubeadmConfigTemplate 定义 Worker 节点的 bootstrap 配置,包括用户账户、SSH 密钥、系统文件和 kubeadm join 设置。

imagePullCredentialsVerificationPolicy: NeverVerify 仅从 Kubernetes 1.35 开始才需要。在使用 Kubernetes 1.34 或更早版本创建 Worker 时,请省略此参数。如果 contentFrom.secret 提供补丁,请确认所引用的 worker-kubelet-patch.json 在 Kubernetes 1.35 中包含此参数。

INFO

模板优化 该模板包含针对安全性和性能预先优化的配置。仅修改需要针对你的环境进行自定义的参数。

示例:

apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
kind: KubeadmConfigTemplate
metadata:
  name: <cluster-name>-worker-kct
  namespace: cpaas-system
spec:
  template:
    spec:
      format: ignition
      users:
      - name: boot
        sshAuthorizedKeys:
        - "<ssh-authorized-keys>"
      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"
          }
      preKubeadmCommands:
      - while ! ip route | grep -q "default via"; do sleep 1; done; echo "NetworkManager started"
      - mkdir -p /run/cluster-api && restorecon -Rv /run/cluster-api
      - if [ -f /etc/disk-setup.sh ]; then bash /etc/disk-setup.sh; fi
      postKubeadmCommands:
      - chmod 600 /var/lib/kubelet/config.yaml
      joinConfiguration:
        patches:
          directory: /etc/kubernetes/patches
        nodeRegistration:
          kubeletExtraArgs:
            node-ip: NODE_IP
            provider-id: PROVIDER_ID
            volume-plugin-dir: "/opt/libexec/kubernetes/kubelet-plugins/volume/exec/"
            protect-kernel-defaults: "true"

PROVIDER_ID 和 NODE_IP 是 DCS Provider 在机器加入时替换的字面魔法令牌 — 请保持其原样书写。完整列表请参见 魔法令牌占位符。

TIP

备选方案:引用集中管理的 Secret 作为 Worker kubelet 补丁

DCS Provider 插件会在 cpaas-system 命名空间中提供名为 dcs-kubernetes-<kubernetes-major-minor>-files 的 Secret(例如,Kubernetes 1.33 对应 dcs-kubernetes-1.33-files)。除了提供给 KubeadmControlPlane 的控制平面文件(参见创建集群附录)外,此 Secret 还包含适用于 Worker KubeadmConfigTemplate 的 worker-kubelet-patch.json 键。当该 Secret 存在时,你可以用 contentFrom.secret 引用替换上面的内联 files 条目 — 这可使 Worker kubelet 补丁与已安装的插件版本保持同步,并避免在集群升级时手动更新。

files:
- contentFrom:
    secret:
      key: worker-kubelet-patch.json
      name: dcs-kubernetes-1.33-files
  owner: "root:root"
  path: /etc/kubernetes/patches/kubeletconfiguration0+strategic.json
  permissions: "0644"

内联形式和 Secret 引用形式在功能上等效;当目标集群中存在插件 Secret 时,推荐使用 Secret 形式。

最低插件版本:与控制平面附录提示相同 — worker-kubelet-patch.json 是 DCS Provider v1.0.13 起随附的 dcs-kubernetes-1.33-files Secret 的一部分。在较旧的插件版本中该 Secret 不存在;这种情况下请保留内联 content: 形式。

步骤 4:配置 MachineDeployment

MachineDeployment 通过引用先前配置的 DCSMachineTemplate 和 KubeadmConfigTemplate 资源,编排 Worker 节点的创建和管理。它管理所需的节点数量并处理滚动更新。

示例:

apiVersion: cluster.x-k8s.io/v1beta1
kind: MachineDeployment
metadata:
  name: <cluster-name>-md-0
  namespace: cpaas-system
spec:
  strategy:
    rollingUpdate:
      maxSurge: 0 # Required when this node pool relies on persistent disks
      maxUnavailable: 1
    type: RollingUpdate
  clusterName: <cluster-name>
  replicas: 3
  selector:
    matchLabels: null
  template:
    metadata:
      labels:
        cluster.x-k8s.io/cluster-name: <cluster-name>
        pool.name: <cluster-name>-md-0
    spec:
      nodeDrainTimeout: 1m
      nodeDeletionTimeout: 5m
      bootstrap:
        configRef:
          apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
          kind: KubeadmConfigTemplate
          name: <cluster-name>-worker-kct
          namespace: cpaas-system
      clusterName: <cluster-name>
      infrastructureRef:
        apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
        kind: DCSMachineTemplate
        name: <cluster-name>-worker-template
        namespace: cpaas-system
      version: <worker-kubernetes-version>

关键参数:

参数类型描述是否必填
.spec.clusterNamestring用于部署节点的目标集群名称是
.spec.replicasintWorker 节点数量(不得超过 IP 池大小)是
.spec.template.spec.bootstrap.configRefobject对 KubeadmConfigTemplate 的引用是
.spec.template.spec.infrastructureRefobject对 DCSMachineTemplate 的引用是
.spec.template.spec.versionstringKubernetes 版本(必须与虚拟机模板匹配)是
.spec.strategy.rollingUpdate.maxSurgeint更新期间超出期望数量的最大节点数。当节点池依赖持久磁盘时,请将此值保持为 0否
.spec.strategy.rollingUpdate.maxUnavailableint更新期间不可用的最大节点数。当使用持久磁盘且 maxSurge = 0 时,请将此值保持大于 0 且不超过副本数否

节点管理操作

本节介绍管理 Worker 节点的常见运维任务,包括扩缩容、更新、升级和模板修改。

INFO

Cluster API 框架 节点管理操作基于 Cluster API 框架。有关详细信息,请参阅 官方 Cluster API 文档。

扩缩容 Worker 节点

Worker 节点扩缩容使你可以根据工作负载需求调整集群容量。Cluster API 通过 MachineDeployment 资源自动管理节点生命周期。

添加 Worker 节点

增加 Worker 节点数量,以应对增加的工作负载或添加新容量。

使用场景:扩容集群以增加计算资源

前提条件:

  • 确认 IP 池有足够的可用 IP 地址供新节点使用
  • 确保 DCS 平台有足够的资源来置备新的虚拟机

操作步骤:

  1. 检查当前节点状态

    查看集群中的当前 Machine:

    # 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. 扩展 IP 池

    在扩容之前,向池中添加新节点所需的 IP 配置。

    INFO

    IP 池扩展 IP 池必须至少包含与期望副本数相同数量的条目。为计划部署的每个额外 Worker 节点添加新的 IP 条目。

    向池中添加 IP 条目:

    首先,导出当前池配置以保留现有条目:

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

    然后使用以下命令添加新的 IP 配置。pool 数组必须包含所有现有条目以及新条目:

    kubectl patch dcsiphostnamepool <cluster-name>-worker-pool -n cpaas-system \
      --type='merge' -p='
    {
      "spec": {
        "pool": [
          {
            "ip": "<existing-ip-1>",
            "mask": "<worker-cidr-prefix-length>",
            "gateway": "<worker-gateway>",
            "dns": "<worker-dns>",
            "hostname": "<existing-hostname-1>",
            "machineName": "<existing-machine-name-1>",
            "persistentDisk": [
              {
                "slot": 0,
                "quantityGB": 40,
                "datastoreClusterName": "<datastore-cluster-name>",
                "path": "/var/cpaas",
                "format": "xfs"
              }
            ]
          },
          {
            "ip": "<existing-ip-2>",
            "mask": "<worker-cidr-prefix-length>",
            "gateway": "<worker-gateway>",
            "dns": "<worker-dns>",
            "hostname": "<existing-hostname-2>",
            "machineName": "<existing-machine-name-2>",
            "persistentDisk": [
              {
                "slot": 0,
                "quantityGB": 40,
                "datastoreClusterName": "<datastore-cluster-name>",
                "path": "/var/cpaas",
                "format": "xfs"
              }
            ]
          },
          {
            "ip": "<new-worker-ip-1>",
            "mask": "<worker-cidr-prefix-length>",
            "gateway": "<worker-gateway>",
            "dns": "<worker-dns>",
            "hostname": "<new-worker-hostname-1>",
            "machineName": "<new-worker-machine-name-1>",
            "persistentDisk": [
              {
                "slot": 0,
                "quantityGB": 40,
                "datastoreClusterName": "<datastore-cluster-name>",
                "path": "/var/cpaas",
                "format": "xfs"
              }
            ]
          },
          {
            "ip": "<new-worker-ip-2>",
            "mask": "<worker-cidr-prefix-length>",
            "gateway": "<worker-gateway>",
            "dns": "<worker-dns>",
            "hostname": "<new-worker-hostname-2>",
            "machineName": "<new-worker-machine-name-2>",
            "persistentDisk": [
              {
                "slot": 0,
                "quantityGB": 40,
                "datastoreClusterName": "<datastore-cluster-name>",
                "path": "/var/cpaas",
                "format": "xfs"
              }
            ]
          }
        ]
      }'
    WARNING

    重要说明

    • pool 数组必须包含所有现有条目以及要添加的新条目
    • 从导出的 YAML 中复制现有条目,以避免数据丢失
    • kubectl patch --type='merge' 会替换整个 spec.pool 数组,因此请原样复制每个现有的 persistentDisk 块,包括其中的 isThin(如果存在),除非你有意添加新磁盘
    • 确保每个新条目具有唯一的 ip、hostname 和 machineName 值
    • 如果新 Worker 节点也需要平台所需的 /var/cpaas 磁盘,请在每个新条目的 persistentDisk 中声明它
    • 网络参数(mask、gateway、dns)通常与现有条目相同

    示例:向现有的 3 节点池中添加 2 个新节点

    # Current pool has 3 entries (10.0.1.11, 10.0.1.12, 10.0.1.13)
    # Adding 2 more entries for nodes 4 and 5
    kubectl patch dcsiphostnamepool worker-pool-1-ippool -n cpaas-system \
      --type='merge' -p='
    {
      "spec": {
        "pool": [
          {
            "ip": "10.0.1.11",
            "mask": "24",
            "gateway": "10.0.1.1",
            "dns": "10.0.0.2",
            "hostname": "worker-node-1",
            "machineName": "worker-vm-1",
            "persistentDisk": [
              {
                "slot": 0,
                "quantityGB": 40,
                "datastoreClusterName": "shared-datastore-cluster",
                "path": "/var/cpaas",
                "format": "xfs"
              }
            ]
          },
          {
            "ip": "10.0.1.12",
            "mask": "24",
            "gateway": "10.0.1.1",
            "dns": "10.0.0.2",
            "hostname": "worker-node-2",
            "machineName": "worker-vm-2",
            "persistentDisk": [
              {
                "slot": 0,
                "quantityGB": 40,
                "datastoreClusterName": "shared-datastore-cluster",
                "path": "/var/cpaas",
                "format": "xfs"
              }
            ]
          },
          {
            "ip": "10.0.1.13",
            "mask": "24",
            "gateway": "10.0.1.1",
            "dns": "10.0.0.2",
            "hostname": "worker-node-3",
            "machineName": "worker-vm-3",
            "persistentDisk": [
              {
                "slot": 0,
                "quantityGB": 40,
                "datastoreClusterName": "shared-datastore-cluster",
                "path": "/var/cpaas",
                "format": "xfs"
              }
            ]
          },
          {
            "ip": "10.0.1.14",
            "mask": "24",
            "gateway": "10.0.1.1",
            "dns": "10.0.0.2",
            "hostname": "worker-node-4",
            "machineName": "worker-vm-4",
            "persistentDisk": [
              {
                "slot": 0,
                "quantityGB": 40,
                "datastoreClusterName": "shared-datastore-cluster",
                "path": "/var/cpaas",
                "format": "xfs"
              }
            ]
          },
          {
            "ip": "10.0.1.15",
            "mask": "24",
            "gateway": "10.0.1.1",
            "dns": "10.0.0.2",
            "hostname": "worker-node-5",
            "machineName": "worker-vm-5",
            "persistentDisk": [
              {
                "slot": 0,
                "quantityGB": 40,
                "datastoreClusterName": "shared-datastore-cluster",
                "path": "/var/cpaas",
                "format": "xfs"
              }
            ]
          }
        ]
      }'
  3. 验证 IP 池容量

    扩展 IP 池后,确认其条目数量足以满足期望的副本数:

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

    检查池中包含的条目数量至少等于期望的副本数。

  4. 扩容 MachineDeployment

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

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

    示例:从 3 个节点扩容到 5 个节点

    kubectl patch machinedeployment worker-pool-1 -n cpaas-system \
      --type='json' -p='[{"op": "replace", "path": "/spec/replicas", "value": 5}]'
  5. 监控扩容进度

    观察 Machine 的创建过程:

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

    Cluster API 控制器将根据 MachineDeployment 模板自动创建新的 Machine。

  6. 验证节点已加入集群

    切换到目标集群上下文并验证新节点:

    # Switch to target cluster context
    kubectl config use-context <target-cluster-context>
    
    # Check all nodes are Ready
    kubectl get nodes

    新节点应出现在列表中并转换为 Ready 状态。

INFO

滚动更新行为 扩容时,新节点会立即创建,不影响现有节点。这可确保零停机扩容。

移除 Worker 节点

减少 Worker 节点数量,以降低集群容量或移除未充分利用的资源。Cluster API 支持两种移除策略:

  1. 随机移除:减少副本数,平台随机选择并删除 Machine
  2. 定向移除:将特定 Machine 标记为删除,然后减少副本数(推荐用于 IP 回收)
INFO

IP 回收场景 当你需要回收特定 Machine 的 IP(例如用于重新分配或 IP 池管理)时,请使用定向移除方法。删除注解可确保平台删除被标记的 Machine,而不是随机的 Machine。

WARNING

数据丢失警告 缩容会移除节点及其关联的虚拟机。请确保:

  • 工作负载能够通过适当的副本机制容忍节点丢失
  • 没有仅存储在被移除节点上的关键数据
  • 应用设计为可水平扩展

DCSIpHostnamePool.spec.pool[].persistentDisk 中声明的持久磁盘不会仅仅因为 Machine 被替换而被删除。只要相应的 IP 槽位仍保留在池中,它们就可以被复用。从池中移除 IP 槽位、删除池或删除集群可能会触发持久卷清理。

随机移除

使用场景:缩容集群且可以移除任意节点(无特定 IP 要求)

操作步骤:

  1. 确认当前 Machine 状态

    查看 MachineDeployment 中的当前 Machine:

    kubectl get machines -n cpaas-system -l cluster.x-k8s.io/deployment-name=<cluster-name>-md-0
  2. 缩容 MachineDeployment

    更新 replicas 字段以减少节点数量:

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

    示例:从 5 个节点缩容到 3 个节点

    kubectl patch machinedeployment worker-pool-1 -n cpaas-system \
      --type='json' -p='[{"op": "replace", "path": "/spec/replicas", "value": 3}]'

    Cluster API 控制器将随机选择并删除 Machine,以匹配期望的副本数。

  3. 监控移除进度

    观察 Machine 的删除过程:

    kubectl get machines -n cpaas-system -w

    Cluster API 控制器将会:

    • 驱逐所选节点(尽可能驱逐 Pod)
    • 从 DCS 平台删除底层虚拟机
    • 移除 Machine 资源
  4. 验证节点已移除

    切换到目标集群上下文:

    kubectl config use-context <target-cluster-context>
    kubectl get nodes

    被移除的节点不应再出现在列表中。

定向移除

使用场景:移除特定 Machine(例如用于 IP 回收、替换不健康的节点)

操作步骤:

  1. 确定要移除的 Machine

    查看当前 Machine:

    kubectl get machines -n cpaas-system -l cluster.x-k8s.io/deployment-name=<cluster-name>-md-0

    记下要移除的 Machine 的 <machine-name>。

  2. 为 Machine 添加删除注解

    将特定 Machine 标记为删除:

    kubectl patch machine <machine-name> -n cpaas-system \
      --type='merge' -p='{"metadata": {"annotations": {"cluster.x-k8s.io/delete-machine": "true"}}}'

    对要移除的每个 Machine 重复此操作。

    示例:移除两个特定 Machine

    kubectl patch machine worker-pool-1-abc123 -n cpaas-system \
      --type='merge' -p='{"metadata": {"annotations": {"cluster.x-k8s.io/delete-machine": "true"}}}'
    
    kubectl patch machine worker-pool-1-def456 -n cpaas-system \
      --type='merge' -p='{"metadata": {"annotations": {"cluster.x-k8s.io/delete-machine": "true"}}}'
  3. 缩容 MachineDeployment

    为 Machine 添加注解后,减少副本数:

    INFO

    副本数必须与被注解的 Machine 数量匹配 减少的副本数必须恰好等于被注解的 Machine 数量。

    • 如果减少的数量不足,则并非所有被注解的 Machine 都会被移除
    • 如果减少的数量过多,则还会随机选择其他 Machine 进行删除
    kubectl patch machinedeployment <cluster-name>-md-0 -n cpaas-system \
      --type='json' -p='[{"op": "replace", "path": "/spec/replicas", "value": <new-replica-count>}]'

    示例:如果注解了 2 个 Machine,则恰好将副本数减少 2(例如从 5 减到 3)

    平台将删除被注解的 Machine,而不是随机选择的 Machine。

  4. 监控移除进度

    观察 Machine 的删除过程:

    kubectl get machines -n cpaas-system -w
  5. 验证节点已移除

    切换到目标集群上下文:

    kubectl config use-context <target-cluster-context>
    kubectl get nodes

    被移除的节点不应再出现在列表中。

升级 Machine 基础设施

要升级 Worker 机器规格(CPU、内存、磁盘、虚拟机模板),请按以下步骤操作:

  1. 创建新的 Machine 模板

    • 复制你的 MachineDeployment 所引用的现有 DCSMachineTemplate
    • 修改所需的值(CPU、内存、磁盘、虚拟机模板等)
    • 为新模板指定唯一名称
    • 将新的 DCSMachineTemplate 应用到集群
  2. 更新 MachineDeployment

    • 修改 MachineDeployment 资源
    • 将 spec.template.spec.infrastructureRef.name 字段更新为引用新模板
    • 应用更改
  3. 滚动更新

    • 系统将自动触发滚动更新
    • Worker 节点将替换为新规格
    • 在 DCSIpHostnamePool.spec.pool[].persistentDisk 中声明的任何磁盘将从旧虚拟机分离并重新附加到替换虚拟机
    • 通过 MachineDeployment 状态监控更新进度

如果要将现有集群从旧的模板磁盘布局迁移到由池管理的持久磁盘,请在依赖升级时的数据保留之前,按照 将现有 Huawei DCS 集群迁移到由池管理的持久磁盘 进行操作。

更新 Bootstrap 模板

Bootstrap 模板(KubeadmConfigTemplate)由 MachineDeployment 和 MachineSet 资源使用。对现有模板的更改不会自动触发现有 Machine 的滚动更新;只有新的 Machine 会使用更新后的模板。

更新流程:

  1. 导出现有模板

    kubectl get KubeadmConfigTemplate <template-name> -o yaml > new-template.yaml
  2. 修改配置

    • 更新导出 YAML 中所需的字段
    • 对于 Kubernetes 1.35 或更高版本,将 所需的 kubelet 补丁设置 添加到 /etc/kubernetes/patches/kubeletconfiguration0+strategic.json
    • 将 metadata.name 更改为新的唯一名称
    • 移除多余的元数据字段(resourceVersion、uid、creationTimestamp 等)
  3. 创建新模板

    kubectl apply -f new-template.yaml
  4. 更新 MachineDeployment

    • 修改 MachineDeployment 资源
    • 将 spec.template.spec.bootstrap.configRef.name 更新为引用新模板
    • 应用更改以触发滚动更新
INFO

模板滚动更新行为 现有 Machine 继续使用旧的 bootstrap 配置。只有新创建的 Machine(在扩缩容或滚动更新期间)才会使用更新后的模板。

升级 Kubernetes 版本

有关在 Huawei DCS 上升级 Kubernetes 和 Alauda OS,请参见 在 Huawei DCS 上升级 Kubernetes。该指南涵盖了控制平面和 Worker 替换所需的顺序以及 YAML 工作流。


使用 Web UI 管理节点池

INFO

Fleet Essentials 升级边界

Fleet Essentials 1.0.4 及更高版本可以通过 CVO 请求 ACP 4.3 及更高版本的 Distribution Version 升级。它不会执行 DCS Kubernetes 和 Alauda OS 的替换。该第 2 阶段 YAML 操作步骤请使用 在 Huawei DCS 上升级 Kubernetes。通过 Fleet Essentials 添加、删除和查看节点池不受此边界影响。

节点池提供了一种声明式方式来管理具有相同配置的节点组。你可以通过 Web UI 查看、添加和删除 Worker 节点池。

版本要求:此工作流需要 Fleet Essentials 和 Alauda Container Platform DCS Infrastructure Provider 1.0.13 或更高版本。如果 provider 版本早于 1.0.13,请使用本文档中基于 YAML 的节点池工作流。如果节点池工作流依赖由池管理的持久磁盘,请使用 DCS provider v1.0.16 或更高版本。在 v1.0.16 中,DCSIpHostnamePool 上的 persistentDisk 声明仍仅支持 YAML,不会在节点池 UI 中公开。

如果节点池依赖由池管理的持久磁盘,请在使用此处的 Web UI 工作流之前,先用 YAML 准备或更新相应的 DCSIpHostnamePool 条目。

INFO

导航:集群 → 集群 → 选择集群 → 节点池选项卡

查看节点池

节点池选项卡显示集群中的所有节点池:

控制平面节点池:

  • 固定为 3 个副本,以实现高可用性
  • 显示 Kubernetes 版本,若有可用升级则显示升级标识
  • 显示 Conditions 链接以查看详细状态

Worker 节点池:

  • 可自定义副本数
  • 独立的 Kubernetes 版本管理
  • 扩缩容和升级操作

节点池卡片信息:

字段描述
类型控制平面 / Worker 节点
名称资源名称
状态显示池健康状况的徽章
副本数当前数量(Worker 包含 Max Surge/Max Unavailable)
SSH 授权密钥SSH 公钥列表
Kubernetes 版本当前版本(若有可用升级则显示升级标识)
Machine 模板关联的模板名称
Conditions指向 Conditions 列表的链接(仅控制平面)

添加 Worker 节点池

导航:节点池选项卡 → 单击 添加 Worker 节点池

表单字段:

字段类型是否必填描述
池名称文本是节点池的唯一标识符
Machine 模板下拉框是按类型筛选:Worker 节点以及兼容的 Kubernetes 版本
副本数数字是池中的节点数量
Max Surge数字否默认值:0,必须 ≥ 0。如果节点池依赖持久磁盘,请将此值保持为 0
Max Unavailable数字否默认值:1,必须 ≥ 0。当 maxSurge = 0 时,必须 > 0 且 ≤ 副本数
SSH 授权密钥文本否添加多个 SSH 公钥

校验:

  • 池名称在集群内必须唯一
  • IP 池必须有足够的可用 IP 地址(≥ 副本数)
  • 必须满足 maxSurge/maxUnavailable 约束
  • 如果节点池依赖持久磁盘,请保持 maxSurge = 0,以便逐个替换 Machine

提示:使用集群名称后跟连字符作为池名称的前缀(例如 mycluster-worker-1),以避免命名冲突。

创建后,新节点将出现在 节点 选项卡中。节点数量等于配置的副本数值。

删除 Worker 节点池

步骤:

  1. 单击 Worker 节点池卡片上的删除图标
  2. 在对话框中确认删除
WARNING

删除 Worker 节点池将永久移除所有关联的节点和 Machine。请确保工作负载能够通过适当的副本机制容忍这些节点的丢失。

查看 Conditions(仅控制平面)

单击控制平面节点池卡片上的 Conditions 链接以查看详细状态信息。

Conditions 列表:

类型状态上次转换时间原因消息
Condition 类型状态时间戳原因人类可读的详细信息

故障排查

新的 Worker Machine 停留在 Provisioning 状态,且 DCS 虚拟机停留在 creating 状态

控制平面和 Worker Machine 对象的诊断流程相同 — 当 DCSMachine 进入 Provisioning 且 status.cdRomFile 已设置(DCS API 认证和 ISO 上传成功),但底层 DCS 虚拟机从未调度到主机时,故障出在 DCS 平台侧,而非控制器。

完整诊断阶梯请参见 基础设施 → 故障排查:虚拟机卡在 creating 状态,其中涵盖:

  • 确认该症状是放置停滞(而非启动缓慢)。
  • 检查 datastore 可用空间。
  • 检查主机 CPU / 内存利用率以及超售比率。
  • 当单个 DCS Host 饱和时,与 DCS 平台团队协调以重新平衡负载。
  • 当部署任务确实死锁时的上报路径。

有关控制平面跨多个物理主机的高可用性,请参见 基础设施 → 控制平面跨主机高可用性。

无论卡住的节点是全新集群的第一个控制平面节点、通过 MachineDeployment 扩容添加的新 Worker,还是滚动更新期间创建的替换 Worker,均适用相同的诊断方法。


后续步骤