扩展 VMware vSphere 集群部署

本文档说明在最小单数据中心工作流成功运行后,如何扩展基线 VMware vSphere 集群部署。

场景

在以下场景中使用本文档:

  • 你需要在控制平面或 worker 节点上增加第二个 NIC。
  • 你希望将节点分布到多个数据中心或部署区域。
  • 你希望增加更多数据磁盘。
  • 你希望扩展 worker 池。

前提条件

开始之前,请确保满足以下条件:

添加第二个 NIC

当节点需要额外的管理、存储或服务网络时,请在以下资源中扩展 manifest:

  • 02-vspheremachineconfigpool-control-plane.yaml
  • 03-vspheremachineconfigpool-worker.yaml
  • 20-control-plane.yaml
  • 30-workers-md-0.yaml
  • 如果启用了 failure domain,则还包括 04-failure-domains.yaml

每个节点槽位都会在 network.primarynetwork.additional 下声明其 NIC 布局。主 NIC 用于派生 kubelet 的 node-ip,并作为节点的主标识;其他 NIC 会按照列表中所列顺序合并在其后。

在 machine config pool 中将第二个 NIC 添加到每个控制平面节点槽位:

network:
  primary:
    networkName: "<nic1_network_name>"
    deviceName: "<nic1_device_name>"
    ip: "<master_01_nic1_ip>/<nic1_prefix>"
    gateway: "<nic1_gateway>"
    dns:
    - "<nic1_dns_1>"
  additional:
  - networkName: "<nic2_network_name>"
    deviceName: "<nic2_device_name>"
    ip: "<master_01_nic2_ip>/<nic2_prefix>"
    gateway: "<nic2_gateway>"
    dns:
    - "<nic2_dns_1>"

对 worker 节点槽位应用相同的模式:

network:
  primary:
    networkName: "<nic1_network_name>"
    deviceName: "<nic1_device_name>"
    ip: "<worker_01_nic1_ip>/<nic1_prefix>"
    gateway: "<nic1_gateway>"
    dns:
    - "<nic1_dns_1>"
  additional:
  - networkName: "<nic2_network_name>"
    deviceName: "<nic2_device_name>"
    ip: "<worker_01_nic2_ip>/<nic2_prefix>"
    gateway: "<nic2_gateway>"
    dns:
    - "<nic2_dns_1>"

在 machine templates 中添加第二个 NIC:

network:
  devices:
  - networkName: "<nic1_network_name>"
  - networkName: "<nic2_network_name>"

如果启用了 failure domain,请更新 VSphereFailureDomain.spec.topology.networks 中的网络列表:

topology:
  networks:
  - <nic1_network_name>
  - <nic2_network_name>

在定义第二个 NIC 的值时,请在清单和检查表中准备以下占位符:

  • <master_01_nic2_ip>
  • <master_02_nic2_ip>
  • <master_03_nic2_ip>
  • <worker_01_nic2_ip>
  • <worker_02_nic2_ip>,如果你同时扩展 worker 池

当你在一个 NIC 和两个 NIC 之间切换时,请应用以下规则:

从一个 NIC 扩展到两个 NIC

同时更新以下所有字段:

  1. VSphereMachineConfigPool.spec.configs[].network.additional(追加第二个 NIC 条目;保持 network.primary 不变)
  2. VSphereMachineTemplate.spec.template.spec.network.devices
  3. 启用 failure domain 时的 VSphereFailureDomain.spec.topology.networks

从两个 NIC 回退到一个 NIC

从以下所有字段中移除第二个 NIC 块:

  1. VSphereMachineConfigPool.spec.configs[].network.additional 中的第二个 NIC 条目(保留列表为空或完全移除 additional 键)
  2. VSphereMachineTemplate.spec.template.spec.network.devices 中的第二个 device 条目
  3. VSphereFailureDomain.spec.topology.networks 中的第二个网络名称

启用多个数据中心和 failure domain

当你需要将节点放置在不同的 vCenter 数据中心或计算集群中时,请使用多个数据中心和 failure domain。

适用以下原则:

  • 一个集群可以定义多个 VSphereFailureDomain 对象。
  • 每个 VSphereDeploymentZone 引用一个 VSphereFailureDomain
  • 控制平面使用 VSphereCluster.spec.failureDomainSelector
  • 当 worker MachineDeployment 必须指向特定部署区域时,它使用 spec.template.spec.failureDomain

为第一个数据中心准备以下占位符:

  • <compute_cluster_1>
  • <default_datastore_1>
  • <resource_pool_path_1>
  • <fd_name_1>
  • <dz_name_1>

为第二个数据中心准备以下占位符:

  • <dc_name_2>
  • <fd_name_2>
  • <dz_name_2>
  • <compute_cluster_2>
  • <default_datastore_2>
  • <resource_pool_path_2>

如果你添加第三个数据中心,请继续使用相同的占位符模式:

  • <dc_name_3>
  • <fd_name_3>
  • <dz_name_3>
  • <compute_cluster_3>
  • <default_datastore_3>
  • <resource_pool_path_3>

04-failure-domains.yaml 中创建 failure-domain 对象。启用 failure domain 时,第一个数据中心也需要一个 VSphereFailureDomainVSphereDeploymentZone

apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: VSphereFailureDomain
metadata:
  name: <fd_name_1>
spec:
  region:
    name: region-a
    type: Datacenter
    tagCategory: k8s-region
    autoConfigure: true
  zone:
    name: zone-1
    type: ComputeCluster
    tagCategory: k8s-zone
    autoConfigure: true
  topology:
    datacenter: <default_datacenter>
    computeCluster: <compute_cluster_1>
    datastore: <default_datastore_1>
    networks:
    - <nic1_network_name>
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: VSphereDeploymentZone
metadata:
  name: <dz_name_1>
spec:
  server: <vsphere_server>
  failureDomain: <fd_name_1>
  controlPlane: true
  placementConstraint:
    resourcePool: <resource_pool_path_1>
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: VSphereFailureDomain
metadata:
  name: <fd_name_2>
spec:
  region:
    name: region-a
    type: Datacenter
    tagCategory: k8s-region
    autoConfigure: true
  zone:
    name: zone-2
    type: ComputeCluster
    tagCategory: k8s-zone
    autoConfigure: true
  topology:
    datacenter: <dc_name_2>
    computeCluster: <compute_cluster_2>
    datastore: <default_datastore_2>
    networks:
    - <nic1_network_name>
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: VSphereDeploymentZone
metadata:
  name: <dz_name_2>
spec:
  server: <vsphere_server>
  failureDomain: <fd_name_2>
  controlPlane: true
  placementConstraint:
    resourcePool: <resource_pool_path_2>

通过在 10-cluster.yaml 中的 VSphereCluster spec 添加 failureDomainSelector,启用跨可用 failure domain 的控制平面选择:

apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: VSphereCluster
metadata:
  name: <cluster_name>
  namespace: <namespace>
spec:
  controlPlaneEndpoint:
    host: "<vip>"
    port: <api_server_port>
  identityRef:
    kind: Secret
    name: <credentials_secret_name>
  server: "<vsphere_server>"
  thumbprint: "<thumbprint>"
  failureDomainSelector: {}

空选择器 {} 会匹配所有 controlPlane: trueVSphereDeploymentZone。使用 match labels 可以将控制平面限制在部分 zone 中。

还要将 [Labels] 块添加到 CPI ConfigMap,以便 vSphere CPI 在工作负载节点上发布匹配的 zone 和 region 标签。键必须与 VSphereFailureDomain.spec.zone.tagCategoryVSphereFailureDomain.spec.region.tagCategory 中使用的 tagCategory 值一致。更新 15-vsphere-cpi-clusterresourceset.yaml 中的 vsphere.conf 数据:

      vsphere.conf: |
        [Global]
        secret-name = "vsphere-cloud-secret"
        secret-namespace = "kube-system"
        service-account = "cloud-controller-manager"
        port = "443"
        insecure-flag = "<cpi_insecure_flag>"
        datacenters = "<cpi_datacenters>"

        [Labels]
        zone = "k8s-zone"
        region = "k8s-region"

        [VirtualCenter "<vsphere_server>"]

failureDomainSelector 和 CPI [Labels] 块必须同时启用。仅添加其中一个会使集群处于不一致状态:节点会获得无法解析的 zone 或 region 标签,或者控制平面无法选择部署目标。

当 worker MachineDeployment 必须固定到某个部署目标时,请设置 worker 的 deployment zone。将 failureDomain 添加到 30-workers-md-0.yaml 中的 spec.template.spec

apiVersion: cluster.x-k8s.io/v1beta1
kind: MachineDeployment
metadata:
  name: <cluster_name>-md-0
  namespace: <namespace>
spec:
  clusterName: <cluster_name>
  replicas: <worker_replicas>
  template:
    spec:
      clusterName: <cluster_name>
      failureDomain: <worker_failure_domain>
      version: "<k8s_version>"
      # ... rest of spec

<worker_failure_domain> 使用 VSphereDeploymentZone 名称,而不是 VSphereFailureDomain 名称。

建议: 在启用多个数据中心之前,请确认 VM template、网络和 datastore 在每个目标数据中心中都可用。

在启用多个数据中心之前,还请确认以下前提条件:

  1. template 已同步到每个目标数据中心。
  2. 每个目标数据中心都能解析网络名称。
  3. 每个目标数据中心都能解析 datastore 名称。
  4. vSphere CPI 数据中心列表覆盖了每个目标数据中心。

添加数据磁盘

基线部署包含以下必需的数据磁盘:

  • 控制平面节点var-cpaasvar-lib-containerdvar-lib-etcd(每个节点 3 个磁盘)。不要移除这些磁盘中的任何一个。var-lib-etcd 磁盘必须设置 wipeFilesystem: true,以便在滚动更新期间允许 kubeadm join
  • Worker 节点var-cpaasvar-lib-containerd(每个节点 2 个磁盘)。不要移除这些磁盘中的任何一个。

如果节点需要超出必需集合的额外数据磁盘,请在相应 VSphereMachineConfigPool 节点槽位中的同一个 persistentDisks 列表里追加更多条目。以下可选字段在此处尤其相关:

  • mountPath:如果设置了该字段,磁盘会在指定路径上格式化并挂载;如果省略,该磁盘会作为原始设备附加,并在 /dev/disk/by-capv/<name> 下提供符号链接,从而允许外部进程在运行时管理它。
  • wipeFilesystem:当为 true 时,新 VM 首次启动时会擦除磁盘内容。正常重启和手动服务重启不受影响。默认值为 false

扩展 worker 节点

worker 扩展取决于 MachineDeployment.spec.replicas 与 worker machine config pool 中可用节点槽位 VSphereMachineConfigPool.spec.configs[] 之间的关系。

请应用以下规则:

  1. 节点槽位数量可以大于 replicas
  2. 空闲槽位不会影响正在运行的集群。
  3. 如果 replicas 超过可用槽位数量,CAPV 将无法正确分配新的 worker 节点。

扩展 worker 时,请按以下顺序操作:

  1. 03-vspheremachineconfigpool-worker.yaml 添加新的 worker 节点槽位。
  2. 增加 30-workers-md-0.yaml 中的 MachineDeployment.spec.replicas

以下示例添加了一个新的 worker 槽位:

- hostname: "<worker_node_name_2>"
  datacenter: "<worker_02_datacenter>"
  network:
    primary:
      networkName: "<nic1_network_name>"
      ip: "<worker_02_nic1_ip>/<nic1_prefix>"
      gateway: "<nic1_gateway>"
      dns:
      - "<nic1_dns_1>"
  persistentDisks:
  - name: var-cpaas
    sizeGiB: <worker_var_cpaas_size_gib>
    mountPath: /var/cpaas
    fsFormat: ext4
  - name: var-lib-containerd
    sizeGiB: <worker_var_lib_containerd_size_gib>
    mountPath: /var/lib/containerd
    fsFormat: ext4

要附加原始磁盘而不进行格式化或挂载(例如,当 Application 自行管理磁盘时),请省略 mountPathfsFormat

  persistentDisks:
  # ...required disks...
  - name: app-data
    sizeGiB: 50

该磁盘在 guest OS 内可通过 /dev/disk/by-capv/app-data 访问。在滚动更新期间,同一个 VMDK 会重新附加到新的 VM,并重新创建符号链接。磁盘不会自动格式化或挂载——由 Application 负责在运行时管理它。

然后更新 worker 副本数:

replicas: <worker_replicas>

验证

每次扩展后,请使用以下命令验证集群状态:

kubectl -n <namespace> get cluster,vspherecluster,kubeadmcontrolplane,machinedeployment,machine,vspheremachine,vspherevm
kubectl --kubeconfig=/tmp/<cluster_name>.kubeconfig get nodes -o wide

确认以下结果:

  • 新的放置、NIC 或磁盘定义已反映到目标资源中。
  • 新的 worker 节点已达到 Ready 状态。
  • 现有节点在变更后仍保持健康。

下一步

一次只应用一种扩展。先验证结果,再将多项变更组合到同一个集群中。