在 Huawei DCS 上创建集群

本文档介绍如何在 Huawei DCS 平台上创建 Kubernetes 集群。基于 YAML 的集群创建可通过清单实现。如果已安装 Fleet Essentials,且 Alauda Container Platform DCS Infrastructure Provider 为 1.0.13 或更高版本,则还可以通过 Web UI 创建集群。如果工作流依赖池管理的持久磁盘,请使用 v1.0.16 或更高版本的 DCS provider。在 v1.0.16 中,DCSIpHostnamePool 上的 persistentDisk 声明仅可通过 YAML 使用,Web UI 中不会显示。DCS Provider v1.0.22 或更高版本与 ACP v4.4 或更高版本配合使用时,还支持通过 YAML 工作流配置 Self-built VIP。

在选择 VM 模板和 provider 软件包之前,请查看 Alauda OS 和 Provider 兼容性。

INFO

Web UI 提供带验证功能的引导式工作流,而 YAML 则提供更灵活的自动化能力。

前提条件

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

1. 基础设施资源

创建集群之前,请配置以下基础设施资源:

  • Cloud Credential - DCS 平台访问信息
  • IP Pool - 用于集群节点、其他 NIC 以及任何 IP 槽位持久磁盘的网络配置,例如 /var/cpaas
  • Machine Template - 控制平面和工作节点的 VM 规格,不包括池管理的持久磁盘

有关详细配置说明,请参阅 Huawei DCS 的基础设施资源。

2. 所需插件安装

在 global 集群上安装以下插件:

  • Alauda Container Platform Kubeadm Provider
  • Alauda Container Platform DCS Infrastructure Provider

有关详细安装说明,请参阅安装指南。

3. 虚拟机模板准备

要安装 Kubernetes,必须:

  • 将 Alauda OS 镜像上传到 DCS 平台
  • 基于此镜像创建虚拟机模板
  • 确保模板包含所有必需的 Kubernetes 组件
  • 如果计划使用持久磁盘,请使用 4.2.1 或更高版本的 DCS VM 模板,因为安全关机和磁盘分离依赖 guest tools
  • 对于依赖池管理的持久磁盘的集群,使用逐个替换。将 maxSurge: 0 保留在控制平面和工作节点池上。

有关每个 VM 镜像中包含的 Kubernetes 组件的详细信息,请参阅 OS 支持矩阵。

4. 网络连接

global 集群节点必须能够访问 DCS 平台上的两个不同目标:

来源目标端口用途
global 集群节点DCS VRM 虚拟 IPTCP/7443DCS REST API。涵盖集群生命周期调用和文件上传的第一步(applyUpload)。
global 集群节点DCS 物理主机 MGMT IP(每个可能接收克隆的主机)DCS 返回的端口;通常为 TCP/8443;请向 DCS 管理员确认Ignition ISO 的文件流上传。provider 将文件流式传输到 applyUpload 响应返回的 URL。

文件上传分为两个步骤:provider 通过 VRM 虚拟 IP(TCP/7443)调用 applyUpload;DCS 平台返回一个指向特定物理主机管理 IP 和端口的 URL;随后 provider 将文件流式传输到该 URL。在创建集群之前,两个目标都必须能够端到端访问。

如果 global 集群节点使用多 NIC 布局(例如,一个 NIC 位于 ACP 集群网络,另一个 NIC 位于部署 DCS 的客户管理网络),请确保能够通过适当的 NIC 路由访问两个目标,即 VRM 虚拟 IP 和每个 DCS 物理主机 MGMT IP。

要求:集群的创建和管理必须能够连接到这两个目标。

5. LoadBalancer 配置

在创建集群之前配置稳定的 Kubernetes API 端点。该端点用于分发或定向控制平面访问所需的 API server 流量。

模式版本管理方使用场景
External LoadBalancer所有受支持的 DCS provider 版本在创建集群之前预配并维护负载均衡器。当环境中已有硬件或软件负载均衡器时使用。
Self-built VIPDCS Provider v1.0.22+ 与 ACP v4.4+DCS provider 创建并协调 provider 管理的 alive ModuleInfo。当需要高可用控制平面端点但没有外部负载均衡器时使用。
单控制平面直接端点所有受支持的版本不创建负载均衡器。API 端点为单个控制平面节点的 IP。仅用于包含一个控制平面副本的开发或 PoC 集群。

有关 External LoadBalancer 的要求,请遵循规划控制平面端点。对于 API server 前方没有负载均衡器的单控制平面部署,请参阅单控制平面(无外部 LB)布局。

6. 业务集群镜像仓库

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

选项配置内容使用场景
global 集群的 registry无需配置。集群会继承该配置。业务节点能够以可接受的吞吐量访问 global 集群使用的 registry。
专用 registry在 cpaas-system 中创建 RegistryCredential Secret,并通过 cpaas.io/registry-reference 标签从 Cluster 引用该 Secret。业务节点位于不同地域或网络段,应从距离较近的 registry 拉取镜像。

无论采用哪种方式,registry 都必须已存储目标版本的 Alauda Container Platform Core,以及计划在此集群上安装的每个平台插件的软件包;每个业务集群节点都必须能够访问其地址。

有关专用 registry 的操作步骤及其限制,请参阅为业务集群选择镜像仓库。

WARNING

registry 绑定仅在首次创建集群时读取。在现有 Cluster 上更改或移除 cpaas.io/registry-reference 不会将该集群迁移到其他 registry。专用 registry 只能通过 YAML 配置;Web UI 工作流始终使用 global 集群的 registry。

7. 节点标签和污点

要为池中的节点设置专属标签、注释或污点(例如为监控、日志记录或 ingress 保留专用池),请按照在节点上配置注释、标签和污点中的说明,在池的资源上声明这些内容。请在创建池之前进行规划:只有在 capi-controller-manager 上启用标签同步后,Machine 标签才会到达其 Node;该页面也介绍了相关内容。这适用于每个节点池,无论集群是通过 Web UI 还是 YAML 创建;Web UI 的节点池步骤不会设置标签或污点。


使用 Web UI

INFO

Fleet Essentials 升级边界

Fleet Essentials 1.0.4 及更高版本可以通过 CVO 请求 ACP 4.3 及更高版本的 Distribution Version 升级,但不会执行 DCS Kubernetes 和 Alauda OS 的替换。有关 Phase 2 YAML 操作步骤,请参阅在 Huawei DCS 上升级 Kubernetes。通过 Fleet Essentials 创建集群不受此边界影响。

版本要求:此工作流要求 Fleet Essentials 和 Alauda Container Platform DCS Infrastructure Provider 1.0.13 或更高版本。如果 provider 版本早于 1.0.13,请使用 YAML 清单。如果使用池管理的持久磁盘,请使用 DCS provider v1.0.16 或更高版本。在 v1.0.16 中,请通过 YAML 配置 DCSIpHostnamePool.spec.pool[].persistentDisk,因为 Web UI 不提供该字段。

如果新集群将依赖池管理的持久磁盘,请先通过 YAML 创建或更新后端 DCSIpHostnamePool,然后使用 Web UI 完成集群工作流的其余步骤。

创建工作流

集群创建分为 5 个步骤:

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

导航路径:Clusters → Clusters → Create Cluster → Select Huawei DCS

步骤 1:基本信息

字段类型必填描述
Infrastructure Credential下拉框是选择现有的 Cloud Credential
Name文本是唯一的集群标识符(小写字母、数字和连字符)
Display Name文本否便于识别的自定义描述
Distribution Version只读-ACP 版本(与 global 集群匹配)
Kubernetes Version只读-由 Distribution Version 确定
Cluster API Address文本是格式:https://<load-balancer-address>:6443。对于 Self-built VIP,请预留 VIP 并使用本文档中的 YAML 路径。

前提条件检查:

创建集群前,请确保:

  • DCS VM Template 已存在于 DCS 平台中,并且 Alauda OS 版本与 Kubernetes 版本匹配
  • Kubernetes API 端点已准备就绪。对于外部 LoadBalancer,请在创建集群前创建该负载均衡器。对于 Self-built VIP,请预留 VIP 并使用 YAML 路径。

版本限制:只能创建平台支持的最新 Kubernetes 版本。

步骤 2:控制平面节点池

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

字段类型必填描述
Machine Template下拉框是按类型筛选模板:Control Plane,以及兼容的 Kubernetes 版本
Replicas只读-固定为 3
SSH Authorized Keys文本否添加多个用于访问节点的 SSH 公钥

验证:关联的 IP Pool 必须有足够的可用 IP 地址(≥ 3)。

步骤 3:业务节点池

您可以添加多个业务节点池。每个池具有以下配置:

字段类型必填描述
Pool Name文本是此节点池的唯一标识符
Machine Template下拉框是按类型筛选模板:Worker Node,以及兼容的 Kubernetes 版本
Replicas数字是默认值:3
Max Surge数字否默认值:0,必须 ≥ 0。如果节点池将使用池管理的持久磁盘,请将此值保持为 0
Max Unavailable数字否默认值:1,必须 ≥ 0。当 maxSurge = 0 时,maxUnavailable 必须 > 0 且 ≤ Replicas
SSH Authorized Keys文本否添加多个 SSH 公钥

验证规则:

  • 池名称在集群内必须唯一
  • IP Pool 必须有足够的可用 IP 地址(≥ Replicas)
  • maxSurge 和 maxUnavailable 必须满足以下限制:如果 maxSurge = 0,则 maxUnavailable > 0
  • 如果集群将依赖池管理的持久磁盘,请保持 maxSurge = 0,以便在未来升级期间逐个替换节点

提示:将池名称设置为以集群名称后跟连字符作为前缀(例如 mycluster-worker-1),以避免不同集群之间发生命名冲突。

步骤 4:网络

字段类型必填描述
Pods CIDRCIDR是Pod 网络地址范围
Services CIDRCIDR是Service 网络地址范围
Join CIDRCIDR是Kube-OVN join CIDR 参数

验证:Pods CIDR 和 Services CIDR 不得重叠。

步骤 5:审核

创建集群前,请审核所有配置设置:

基本信息:

  • Name、Display Name、Infrastructure Credential
  • Distribution Version、Kubernetes Version
  • Cluster API Address

控制平面节点池:

  • 包含 VM Template Name、OS Version、Kubernetes Version 的 Machine Template
  • CPU、Memory、Replicas、SSH Keys

业务节点池(列表视图):

  • Pool Name、Machine Template、Replicas
  • Max Surge、Max Unavailable、SSH Keys

如果集群将依赖池管理的持久磁盘,请将业务节点池的 Max Surge 设置为 0。

网络:

  • Pods CIDR、Services CIDR、Join CIDR

点击 Create 开始创建集群。


使用 YAML

集群创建工作流

使用 YAML 时,您可以在 global 集群中创建 Cluster API 资源,以预配基础设施并引导可正常运行的 Kubernetes 集群。

WARNING

重要的命名空间要求

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

WARNING

业务集群命名

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

按照惯例,CAPI Cluster 和 provider 集群资源(DCSCluster)应保持命名为 <cluster-name>,非根 CAPI 和 provider 资源(KubeadmControlPlane、KubeadmConfigTemplate、MachineDeployment、机器模板、IP/主机名池等)则应使用 <cluster-name>- 作为前缀,例如,示例清单使用 <cluster-name>-kcp。这是建议,而非控制器强制执行的规则,但可避免多个业务集群位于 cpaas-system 时发生同一命名空间内的资源冲突,并使操作期间的资源归属一目了然。

配置工作流

按以下步骤依次操作,以预配可正常运行的集群(控制平面和工作节点):

  1. 配置 KubeadmControlPlane(控制平面规范和 kubeadm 引导配置)。
  2. 配置 DCSCluster(基础设施绑定和负载均衡器引用)。
  3. 创建 Cluster 资源(用于关联上述两项的顶层 CAPI 对象)。
  4. 配置工作节点资源:KubeadmConfigTemplate(工作节点引导配置)、工作节点 DCSMachineTemplate、工作节点 DCSIpHostnamePool 和 MachineDeployment。仅有控制平面并不能构成可用的集群。 四个工作节点 YAML 资源请参阅在 Huawei DCS 上管理节点。

注意:基础设施资源(Secret、控制平面 DCSIpHostnamePool、控制平面 DCSMachineTemplate)应单独配置。相关说明请参阅Huawei DCS 的基础设施资源。

如果需要在滚动替换后保留任何磁盘,请在对应的 DCSIpHostnamePool.spec.pool[].persistentDisk 条目中声明该磁盘。这包括平台所需的 /var/cpaas 磁盘。provider 会创建新的持久卷,作为独立的普通持久卷。当 DCS 环境要求显式设置精简置备时,请设置 persistentDisk[].isThin;如果省略,provider 不会发送 isThin,DCS 将使用平台默认值。

如果集群需要额外的 NIC,请在创建相应的 Machines 之前,在 DCSIpHostnamePool.spec.pool[].additionNic[] 中声明。provider 仅在创建新 VM 时应用额外的 NIC。之后编辑 Pool 时,现有 VM 不会热添加 NIC。

解析占位符值

以下示例清单使用 <placeholder> 语法表示特定于环境的值。其中一些值有规范的数据源,建议查询数据源,而不是手动选择:

占位符规范数据源获取方式
<control-plane-kubernetes-version> / <worker-kubernetes-version>cpaas-system 命名空间中的 cpaas.io/dcs-vm-template ConfigMap,每个发行版版本对应一个。kubectl -n cpaas-system get cm -l cpaas.io/dcs-vm-template -o yaml — 读取 data.kubernetesVersion。
<dns-image-tag>同一 ConfigMap 中的 data.corednsTag。使用与上文相同的 kubectl get cm 查询。
<etcd-image-tag>同一 ConfigMap 中的 data.etcdTag。使用与上文相同的 kubectl get cm 查询。
<vm-template-name>(位于 DCSMachineTemplate.spec.template.spec.vmTemplateName 中)ConfigMap 的 cpaas.io/dcs-vm-template 标签值(必须与 DCS 平台中注册的 VM 模板名称匹配)。使用相同的 kubectl get cm 查询 — 读取标签。
<ssh-authorized-keys>由 operator 提供。每个条目都是单行 OpenSSH 格式的公钥(ssh-ed25519 AAAA… / ssh-rsa AAAA…)。该字段是 ignition 验证器要求的必填项,且不能为空。对于不需要交互式 SSH 的测试或 PoC 集群,请提供任意语法有效的公钥(无需持有对应的私钥);对于生产环境,请使用 operator 团队的签名密钥。不适用 — 由 operator 生成或提供。
<auth-secret-name>您在基础设施 → 云凭证中创建的 Secret。kubectl -n cpaas-system get secret <name>
<cluster-name>由 operator 选择;必须符合 DNS-1123 规范,且不得为 global(该名称已保留给 global 集群)。在 Cluster、DCSCluster 以及每个 Machine 的 cluster.x-k8s.io/cluster-name 标签中重复使用。KubeadmControlPlane 使用带前缀的形式 <cluster-name>-kcp。完整命名约定请参阅业务集群命名。不适用
<load-balancer-ip>由 operator 提供,供客户端用于访问集群 API server。对于 type: external,此值为外部负载均衡器 VIP(必须是 IP 地址;集群端点不支持域名)。对于没有外部 LB 的单控制平面集群,此值为唯一控制平面节点的 IP(请参阅单控制平面布局)。不适用
<self-built-vip>由 operator 提供的 Self-built VIP IPv4 VIP。请在创建集群前预留此地址。该地址不得分配给节点主 IP 或 DCSIpHostnamePool.spec.pool[].additionNic[].ip。不适用
<pods-cidr> / <services-cidr> / <kube-ovn-join-cidr>由 operator 提供。不得与主机网络、global 集群的 CIDR,或您计划互连的任何其他 CAPI 集群的 CIDR 重叠。留空时将回退到 global 集群随附的 kube-ovn 默认值;生产环境不建议这样做:显式指定 CIDR 可避免多个业务集群位于同一 global 集群时发生未被察觉的冲突。不适用

Magic-Token 占位符

示例清单中有几个值看起来像占位符,但它们实际上是由 DCS Provider 在机器加入时替换的字面令牌。请保持原样:

字面令牌含义替换方
PROVIDER_ID每台 Machine 的 provider ID(例如 dcs://<dcsmachine-name>)。DCS Provider — 在 kubeadm init / kubeadm join 运行之前,覆盖生成的 kubelet 配置中的值。
NODE_IP从附加到此 Machine 的 DCSIpHostnamePool 条目中分配的节点 IP。DCS Provider — 使用 DCSIpHostnamePool.spec.pool[].ip 的值覆盖。

手动替换或加引号包裹这些令牌会破坏加入流程,导致节点无法向控制平面注册。

网络规划和负载均衡器

创建控制平面资源之前,请规划网络架构并选择控制平面端点模式。

要求:

  • 网络分段:规划控制平面节点的 IP 地址范围
  • 额外 NIC:如果节点需要存储、管理或隔离的应用网络,请为每个 IP 槽位规划 DCSIpHostnamePool.spec.pool[].additionNic[] 值,包括 DVS 和 Port Group 名称
  • API 端点模式:使用外部 LoadBalancer,或将 Self-built VIP 与 DCS Provider v1.0.22+ 和 ACP v4.4+ 配合使用
  • API server 地址:为 Kubernetes API server 准备稳定的 VIP 或负载均衡器地址
  • 连通性:确保所有组件之间的网络连通

对于 Self-built VIP,请验证目标 DCS 端口组允许 VIP 所有权、GARP 或 ARP 更新,以及控制平面 VM 之间的 VRRP 流量。VIP 必须与将承载该 VIP 的 NIC 位于同一 Layer 2 网络中。 对于外部 LoadBalancer,请在规划控制平面端点中验证 Layer 4 侦听器、TCP 6443 后端、HTTPS /healthz 检查、后端所有权以及端点可达性。

配置 KubeadmControlPlane

KubeadmControlPlane 资源定义控制平面配置,包括 Kubernetes 版本、节点规范和引导设置。

Kubernetes 1.35 kubelet 设置

只有从 Kubernetes 1.35 开始,才需要 imagePullCredentialsVerificationPolicy: NeverVerify。使用 Kubernetes 1.34 或更早版本创建集群时,请省略此参数。如果 contentFrom.secret 提供了补丁,请确认引用的 Secret 键在 Kubernetes 1.35 中包含此参数。

TIP

完整配置参考

为便于阅读,以下示例省略了较长配置文件中的部分内容。完整配置(包括默认审计策略、准入控制和文件内容)请参阅附录中的完整 KubeadmControlPlane 配置。

kubeadmcontrolplane.yaml
apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: KubeadmControlPlane
metadata:
  name: <cluster-name>-kcp
  namespace: cpaas-system
  annotations:
    controlplane.cluster.x-k8s.io/skip-coredns: ""
    controlplane.cluster.x-k8s.io/skip-kube-proxy: ""
spec:
  rolloutStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 0 # Required when the cluster relies on pool-managed persistent disks
  kubeadmConfigSpec:
    users:
    - name: boot
      sshAuthorizedKeys:
      - "<ssh-authorized-keys>"
    format: ignition
    files:
    - path: /etc/kubernetes/admission/psa-config.yaml
      owner: "root:root"
      permissions: "0644"
      content: |
        # ... (Admission Configuration Content) ...
    - path: /etc/kubernetes/patches/kubeletconfiguration0+strategic.json
      owner: "root:root"
      permissions: "0644"
      content: |
        {
          "apiVersion": "kubelet.config.k8s.io/v1beta1",
          "kind": "KubeletConfiguration",
          "imagePullCredentialsVerificationPolicy": "NeverVerify",
          "_comment": "... (Kubelet Configuration Content) ..."
        }
    # ... (other files) ...
    clusterConfiguration:
      imageRepository: cloud.alauda.io/alauda
      dns:
        imageTag: <dns-image-tag>
      etcd:
        local:
          imageTag: <etcd-image-tag>
      # ... (apiServer, controllerManager, scheduler) ...
    initConfiguration:
      patches:
        directory: /etc/kubernetes/patches
      nodeRegistration:
        kubeletExtraArgs:
          node-labels: "kube-ovn/role=master"
          provider-id: PROVIDER_ID
          volume-plugin-dir: "/opt/libexec/kubernetes/kubelet-plugins/volume/exec/"
          protect-kernel-defaults: "true"
    joinConfiguration:
      patches:
        directory: /etc/kubernetes/patches
      nodeRegistration:
        kubeletExtraArgs:
          node-ip: NODE_IP
          node-labels: "kube-ovn/role=master"
          provider-id: PROVIDER_ID
          volume-plugin-dir: "/opt/libexec/kubernetes/kubelet-plugins/volume/exec/"
          protect-kernel-defaults: "true"
  machineTemplate:
    nodeDrainTimeout: 1m
    nodeDeletionTimeout: 5m
    infrastructureRef:
      apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
      kind: DCSMachineTemplate
      name: <cp-dcs-machine-template-name>
  replicas: 3
  version: <control-plane-kubernetes-version>

参数说明:

参数类型描述必填
.spec.kubeadmConfigSpecobjectkubeadm bootstrap provider 启动参数是
.spec.machineTemplate.infrastructureRefobjectDCSMachineTemplate 引用是
.spec.replicasint控制平面副本数。必须满足 1 ≤ replicas ≤ IP Pool size。对于开发或 PoC 单控制平面部署,请设置为 1(参见单控制平面布局)。生产环境通常使用 3 实现 HA。是
.spec.versionstringKubernetes 版本(必须与 VM 模板匹配,参见解析占位符值)是

有关组件版本(例如 <dns-image-tag>、<etcd-image-tag>),请参阅 OS Support Matrix。

配置 DCSCluster

DCSCluster 是基础设施集群声明,用于引用负载均衡器和 DCS 平台凭证。

如果在集群外部管理负载均衡器,请使用 type: external。所有文档中列出的 DCS provider 版本均支持此模式。

dcscluster.yaml
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: DCSCluster
metadata:
  name: "<cluster-name>"
  namespace: cpaas-system
spec:
  controlPlaneLoadBalancer:
    host: <load-balancer-ip>
    port: 6443
    type: external
  credentialSecretRef:
    name: <auth-secret-name>
  controlPlaneEndpoint:
    host: <load-balancer-ip>
    port: 6443
  # Optional. Enable only when the target DCS compute cluster has DRS enabled.
  controlPlaneHA:
    enabled: true
  networkType: kube-ovn
  site: <site>

对于 DCS Provider v1.0.22+ 和 ACP v4.4+,请使用 type: internal 启用 Self-built VIP:

dcscluster-self-built-vip.yaml
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: DCSCluster
metadata:
  name: "<cluster-name>"
  namespace: cpaas-system
spec:
  controlPlaneLoadBalancer:
    host: <self-built-vip>
    port: 6443
    type: internal
    vrid: 42
    interface: eth0
  credentialSecretRef:
    name: <auth-secret-name>
  controlPlaneEndpoint:
    host: <self-built-vip>
    port: 6443
  networkType: kube-ovn
  site: <site>

参数说明:

参数类型描述必填
.spec.controlPlaneLoadBalancerobject控制平面 API server 暴露方式是
.spec.controlPlaneLoadBalancer.typestringexternal 使用 operator 管理的负载均衡器。internal 启用 Self-built VIP,并要求使用 DCS Provider v1.0.22+ 和 ACP v4.4+。是
.spec.controlPlaneLoadBalancer.hoststring对于 external,外部负载均衡器 VIP(IP 地址)。对于 internal,预留的 IPv4 VIP。是
.spec.controlPlaneLoadBalancer.portintKubernetes API server 端口。有效范围为 1-65535。是
.spec.controlPlaneLoadBalancer.vridintSelf-built VIP 使用的 Keepalived VRID。当 type 为 internal 时,请设置为 1 到 255 之间的值。当 type 为 external 时,此字段将被忽略。有条件必填
.spec.controlPlaneLoadBalancer.interfacestringbootstrap VIP 和 alive 使用的可选 NIC 名称。留空时,将根据节点 IP 检测 NIC。在 VIP 必须绑定到特定接口的多 NIC 集群中,请显式设置此项。否
.spec.credentialSecretRef.namestringDCS 身份验证 Secret 名称。Secret 定义 DCS Provider 是以接口互联用户(默认)还是域用户身份进行身份验证,参见凭证用户类型。是
.spec.controlPlaneEndpointobjectCAPI 和 kubeadm 使用的 Kubernetes API 端点。请将其设置为与 controlPlaneLoadBalancer 相同的主机和端口。是
.spec.controlPlaneHA.enabledbool为控制平面 VM 启用由 provider 管理的 DCS DRS 互斥规则。仅当目标 DCS 计算集群已启用 DRS,且具有足够的主机和容量以支持跨主机放置时,才设置为 true。否
.spec.networkTypestring目前仅支持 "kube-ovn"是
.spec.sitestringDCS 平台站点 ID是

controlPlaneHA 为可选项。启用后,provider 会为此业务集群当前的控制平面 VM 创建并维护一条 DRS ruleType=2 互斥规则。实际放置和运行时迁移由 DCS 执行。provider 不会运行 DRS,也不会应用 DRS 建议。如果规则已维护但放置尚未收敛,请等待 DCS 调度机制完成,或在 DCS 平台侧触发/应用 DRS。有关基础设施前提条件,请参阅控制平面跨主机高可用。

自建 VIP 的行为和限制

Self-built VIP 要求 DCS Provider 版本为 v1.0.22 或更高版本,且 ACP 版本为 v4.4 或更高版本。请在创建集群前规划此模式。

建议:仅对具有三个控制平面副本的新建高可用集群使用 type: internal。对于使用 type: external 的现有集群,除非已有经过测试的迁移计划,否则请保留外部负载均衡器。controlPlaneHA.enabled 是独立的 DRS 放置功能,不是 Self-built VIP 的必需项。

DCS provider 分两个阶段处理 Self-built VIP:

  1. 在 bootstrap 期间,provider 仅在第一个 kubeadm init 控制平面节点上注入 dcs-bootstrap-vip.service。此服务会在 kubeadm 启动前添加 <self-built-vip>/32。
  2. 控制平面节点注册后,provider 会创建或更新由 provider 管理的 alive ModuleInfo。平台插件流程会渲染业务集群 AppRelease,而 alive 会在控制平面节点上安装 VIP 运行时。

重要限制:

  • 两种模式都只接受 IP 地址:type: external 接受外部负载均衡器 VIP,type: internal 接受预留的 IPv4 VIP。两种模式下,集群端点均不支持域名。
  • VIP 不得与 DCSIpHostnamePool 的主 IP 或附加 NIC IP 冲突。
  • 目标 DCS 端口组必须允许 VIP 所有权、GARP 或 ARP 更新,以及 VRRP 流量。
  • interface 必须是长度不超过 15 个字符的 Linux 接口名称。当 VIP 必须绑定到特定 NIC(例如 eth0 或 eth1)时,请设置此项。
  • 集群控制平面初始化后,不应更改 type、host、port、vrid 和 interface。
  • DCS provider 会创建或修补 alive ModuleInfo;平台插件流程会创建业务集群 AppRelease 和运行时资源。
  • DCS provider 不会注入或持久化 IPVS 内核模块或 sysctl 参数。请使用受支持的 ACP 版本随附的 VM 模板和插件包。

验证自建 VIP

如果将 DCSCluster.spec.controlPlaneLoadBalancer.type 设置为 internal,请在集群创建后验证由 provider 管理的 VIP 路径。

kubectl -n cpaas-system get dcscluster <cluster-name> \
  -o jsonpath='{.spec.controlPlaneLoadBalancer.type}{" "}{.spec.controlPlaneEndpoint.host}{":"}{.spec.controlPlaneEndpoint.port}{"\n"}'
kubectl -n cpaas-system get cluster <cluster-name> \
  -o jsonpath='{.spec.controlPlaneEndpoint.host}{":"}{.spec.controlPlaneEndpoint.port}{"\n"}'
kubectl -n cpaas-system get moduleinfo \
  -l cpaas.io/cluster-name=<cluster-name>,cpaas.io/module-name=alive
kubectl --kubeconfig <workload-kubeconfig> -n cpaas-system get apprelease alive
kubectl --kubeconfig <workload-kubeconfig> -n kube-system get pods -l app=alive -o wide
kubectl --kubeconfig <vip-kubeconfig> get --raw=/version

预期结果包括:配置的 VIP 端点、由 provider 创建的 alive ModuleInfo、已同步且运行正常的 alive AppRelease、每个控制平面节点上均处于 Ready 状态的 alive Pod,以及通过 VIP 成功执行的 /version 请求。

单控制平面(无外部 LB)布局

对于开发、PoC 或控制平面仅有 一个 副本(KubeadmControlPlane.spec.replicas: 1)的任何部署,API server 前方都没有真正的负载均衡器。不过,仍有两个字段必须提供值:

  • .spec.controlPlaneLoadBalancer.host 和 .spec.controlPlaneEndpoint.host — 两者都设置为唯一控制平面节点的 IP(即分配给控制平面 DCSIpHostnamePool 中该节点的同一 IP)。
  • .spec.controlPlaneLoadBalancer.type — 保留与 schema 兼容的值 external;此布局不会创建负载均衡组件。

具体配置如下:

spec:
  controlPlaneLoadBalancer:
    host: 10.226.82.150     # same IP as the control plane node from the IP pool
    port: 6443
    type: external
  controlPlaneEndpoint:
    host: 10.226.82.150     # same as above
    port: 6443

此布局不具备 HA — 如果唯一的控制平面节点发生故障,在节点恢复前将无法访问集群 API。此布局不要使用 Self-built VIP。生产环境请使用配备外部 LoadBalancer 的 replicas: 3,或使用 Self-built VIP。

配置集群

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

cluster.yaml
apiVersion: cluster.x-k8s.io/v1beta1
kind: Cluster
metadata:
  annotations:
    capi.cpaas.io/resource-group-version: infrastructure.cluster.x-k8s.io/v1beta1
    capi.cpaas.io/resource-kind: DCSCluster
    cpaas.io/kube-ovn-join-cidr: <kube-ovn-join-cidr>
  labels:
    cluster-type: DCS
    # Optional. Bind this cluster to a dedicated image registry instead of the
    # registry of the `global` cluster. Read only at cluster creation.
    # cpaas.io/registry-reference: <registry-credential-name>
  name: <cluster-name>
  namespace: cpaas-system
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: DCSCluster
    name: <cluster-name>

参数说明:

参数类型描述必填
.spec.clusterNetwork.pods.cidrBlocks[]stringPod CIDR。在 CAPI schema 中为可选项,但建议显式设置,以便多个 CAPI 集群可以共存而不发生重叠。如果未设置,kube-ovn 将回退到默认值,该值可能与同一 global 上的其他集群冲突。建议
.spec.clusterNetwork.services.cidrBlocks[]stringService CIDR。与 Pod CIDR 的建议相同——显式设置以避免集群间地址冲突。建议
.spec.controlPlaneRefobject控制平面引用是
.spec.infrastructureRefobject基础设施集群引用是

集群注解:

上面的示例展示了三个注解,但完整的 Cluster 资源还包含其他几个注解。下表列出了由 operator 编写的注解(其他一些注解由 ACP 控制器写入,不应预先设置):

注解必填值来源用途
capi.cpaas.io/resource-group-version是字面值 infrastructure.cluster.x-k8s.io/v1beta1告知 CAPI 基础设施绑定应使用的 API 组。
capi.cpaas.io/resource-kind是字面值 DCSCluster告知 CAPI 基础设施绑定应绑定的 kind。
capi.cpaas.io/kubernetes是与 KubeadmControlPlane.spec.version 和 MachineDeployment.spec.template.spec.version 相同的值。显示标签,也由某些升级和清单工具使用。事实来源是 cpaas.io/dcs-vm-template ConfigMap 的 kubernetesVersion。
cpaas.io/kube-ovn-join-cidr是由 operator 选择的 /16 CIDR,不得与 Pod / Service CIDR 或任何其他集群的 join CIDR 重叠。Kube-OVN 节点间隧道网络。
cpaas.io/kube-ovn-version是global 集群随附的 kube-ovn 版本。从 global CAPI Cluster(kubectl get cluster global -n cpaas-system -o jsonpath='{.metadata.annotations.cpaas\.io/kube-ovn-version}')上的 cpaas.io/kube-ovn-version 注解中读取。同一 global 集群上每个正常运行的业务集群都具有相同的值,因此如果存在,也可以从其中任意一个业务集群读取。固定安装到业务集群中的 kube-ovn 版本。
cpaas.io/registry-address是global 集群使用的镜像仓库(通常为 <registry-host>:11443)。从 global CAPI Cluster(kubectl get cluster global -n cpaas-system -o jsonpath='{.metadata.annotations.cpaas\.io/registry-address}')上的 cpaas.io/registry-address 注解中读取。使 day-2 reconciler 能够在集群置备期间解析镜像。此注解不会选择仓库凭证:要从专用仓库拉取平台镜像,请使用下面所述的 cpaas.io/registry-reference 标签。
cpaas.io/nodes-mode是对于由 DCS Provider 置备的集群,使用字面值 self-managed。标记该集群的节点生命周期由 CAPI 和此 provider 管理。
cpaas.io/os-family仅 KubeOS当集群的 DCS VM 模板基于 KubeOS 镜像构建时,使用字面值 kubeos。对于 Alauda OS,请省略此项:DCS Provider 会将未设置的值或任何非 kubeos 的值处理为 slemicro。需要 DCS Provider v1.0.19 或更高版本。告知 DCS Provider 不要将 /home 挂载写入节点 Ignition 配置。接收该挂载的 KubeOS 节点会在 Ignition 早期阶段失败并无法启动。请在创建 Cluster 时设置此项,并且要早于任何机器置备。

集群启动后,ACP 控制器可能会写入其他只读注解(cpaas.io/cpu-cores-number、cpaas.io/memories、cpaas.io/nodes-number 等)。这些注解由系统计算,应用 YAML 时不得预先设置。

集群标签:

标签必填值来源用途
cluster-type是字面值 DCS。标记该集群由 DCS Provider 置备。
cpaas.io/registry-reference否cpaas-system 中 RegistryCredential Secret 的名称。将此集群绑定到专用镜像仓库。省略此项则继承 global 集群的仓库。仅在创建集群时读取——请参阅为业务集群选择镜像仓库。

部署节点

有关部署工作节点的说明,请参阅在 Huawei DCS 上管理节点。


集群验证

部署所有集群资源后,请验证集群是否已成功创建并正常运行。

使用控制台

  1. 导航至 集群 → 集群
  2. 在集群列表中找到新创建的集群
  3. 验证集群状态是否显示为 运行中
  4. 检查所有控制平面节点和工作节点是否为 就绪

使用 kubectl

或者,使用 kubectl 命令验证集群:

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

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

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

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

对于使用其他 NIC 的集群,还要验证 provider 是否在匹配的 DCSMachine 对象上记录了这些 NIC:

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}'

验证控制平面 HA

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

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

请按以下方式解释该条件:

状态和原因含义后续步骤
True ControlPlaneHAReadyprovider 管理的 DRS 规则已存在,并且 provider 已观察到当前控制平面 VM 位于不同的 DCS 主机上。无需执行任何操作。
False ControlPlaneHAPendingprovider 正在等待可恢复状态,例如足够的 VM URN、足够的成员数量或 DCS 侧的放置结果。阅读消息。如果消息提到放置,请检查 DCS 主机容量、DRS 状态以及运行时迁移是否被阻止。
False ControlPlaneHAFailedprovider 无法查询、验证、创建、更新、删除或检查 DRS 规则。阅读消息,然后检查 DCS 凭证、DRS 设置、规则名称冲突,并在需要时检查控制器日志。

检查已观测到的规则和成员快照:

kubectl get dcscluster <cluster-name> -n cpaas-system \
  -o jsonpath='rule={.status.controlPlaneHA.ruleName}{" index="}{.status.controlPlaneHA.ruleIndex}{" cluster="}{.status.controlPlaneHA.clusterUrn}{"\n"}{range .status.controlPlaneHA.members[*]}{.machineName}{" "}{.vmUrn}{"\n"}{end}'

members[] 列表包含规则中每个控制平面 VM 的 CAPI Machine 名称和 DCS VM URN。当前 DCS 状态快照不包含 DCS 主机名称。如果需要确认确切的主机放置位置,请从 DCS 平台或 DCS API 查询 VM 详细信息,并比较 VM 的 hostName 或 hostUrn 值。

预期结果

成功创建的集群应显示:

  • 集群状态:运行中 或 已置备
  • 所有控制平面机器:运行中
  • 所有工作节点(如果已部署):运行中
  • Kubernetes 节点:就绪
  • 集群模块状态:已完成
  • 对于多 NIC 集群,每个已创建的 VM 都在 DCSMachine.status.additionalNic 中具有预期的其他 NIC,并且客户机 OS 显示相应的 ethN 接口。

附录

完整的 KubeadmControlPlane 配置

以下是完整的 KubeadmControlPlane 配置,其中包含所有默认审计策略、准入控制和文件内容。

嵌入式 kubelet 补丁包含 imagePullCredentialsVerificationPolicy: NeverVerify,仅从 Kubernetes 1.35 开始才需要此参数。对于 Kubernetes 1.34 或更早版本,请移除此参数。

apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: KubeadmControlPlane
metadata:
  name: <cluster-name>-kcp
  namespace: cpaas-system
  annotations:
    controlplane.cluster.x-k8s.io/skip-coredns: ""
    controlplane.cluster.x-k8s.io/skip-kube-proxy: ""
spec:
  rolloutStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 0 # Required when the cluster relies on pool-managed persistent disks
  kubeadmConfigSpec:
    users:
    - name: boot
      sshAuthorizedKeys:
      - "<ssh-authorized-keys>"
    format: ignition
    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/audit/policy.yaml
      owner: "root:root"
      append: false
      permissions: "0644"
      content: |
        apiVersion: audit.k8s.io/v1
        kind: Policy
        omitStages:
        - "RequestReceived"
        rules:
        - level: None
          users:
          - system:kube-controller-manager
          - system:kube-scheduler
          - system:serviceaccount:kube-system:endpoint-controller
          verbs: ["get", "update"]
          namespaces: ["kube-system"]
          resources:
          - group: ""
            resources: ["endpoints"]
        - level: None
          nonResourceURLs:
          - /healthz*
          - /version
          - /swagger*
        - level: None
          resources:
          - group: ""
            resources: ["events"]
        - level: None
          resources:
          - group: "devops.alauda.io"
        - level: None
          verbs: ["get", "list", "watch"]
        - level: None
          resources:
          - group: "coordination.k8s.io"
            resources: ["leases"]
        - level: None
          resources:
          - group: "authorization.k8s.io"
            resources: ["subjectaccessreviews", "selfsubjectaccessreviews"]
          - group: "authentication.k8s.io"
            resources: ["tokenreviews"]
        - level: None
          resources:
          - group: "app.alauda.io"
            resources: ["imagewhitelists"]
          - group: "k8s.io"
            resources: ["namespaceoverviews"]
        - level: Metadata
          resources:
          - group: ""
            resources: ["secrets", "configmaps"]
        - level: Metadata
          resources:
          - group: "operator.connectors.alauda.io"
            resources: ["installmanifests"]
          - group: "operators.katanomi.dev"
            resources: ["katanomis"]
        - level: RequestResponse
          resources:
          - group: ""
          - group: "aiops.alauda.io"
          - group: "apps"
          - group: "app.k8s.io"
          - group: "authentication.istio.io"
          - group: "auth.alauda.io"
          - group: "autoscaling"
          - group: "asm.alauda.io"
          - group: "clusterregistry.k8s.io"
          - group: "crd.alauda.io"
          - group: "infrastructure.alauda.io"
          - group: "monitoring.coreos.com"
          - group: "operators.coreos.com"
          - group: "networking.istio.io"
          - group: "extensions.istio.io"
          - group: "install.istio.io"
          - group: "security.istio.io"
          - group: "telemetry.istio.io"
          - group: "opentelemetry.io"
          - group: "networking.k8s.io"
          - group: "portal.alauda.io"
          - group: "rbac.authorization.k8s.io"
          - group: "storage.k8s.io"
          - group: "tke.cloud.tencent.com"
          - group: "devopsx.alauda.io"
          - group: "core.katanomi.dev"
          - group: "deliveries.katanomi.dev"
          - group: "integrations.katanomi.dev"
          - group: "artifacts.katanomi.dev"
          - group: "builds.katanomi.dev"
          - group: "versioning.katanomi.dev"
          - group: "sources.katanomi.dev"
          - group: "tekton.dev"
          - group: "operator.tekton.dev"
          - group: "eventing.knative.dev"
          - group: "flows.knative.dev"
          - group: "messaging.knative.dev"
          - group: "operator.knative.dev"
          - group: "sources.knative.dev"
          - group: "operator.devops.alauda.io"
          - group: "flagger.app"
          - group: "jaegertracing.io"
          - group: "velero.io"
            resources: ["deletebackuprequests"]
          - group: "connectors.alauda.io"
          - group: "operator.connectors.alauda.io"
            resources: ["connectorscores", "connectorsgits", "connectorsocis"]
        - level: Metadata
    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
    clusterConfiguration:
      imageRepository: cloud.alauda.io/alauda
      dns:
        imageTag: <dns-image-tag>
      etcd:
        local:
          imageTag: <etcd-image-tag>
      apiServer:
        extraArgs:
          audit-log-format: json
          audit-log-maxage: "30"
          audit-log-maxbackup: "10"
          audit-log-maxsize: "200"
          profiling: "false"
          audit-log-mode: batch
          audit-log-path: /etc/kubernetes/audit/audit.log
          audit-policy-file: /etc/kubernetes/audit/policy.yaml
          tls-cipher-suites: "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"
          encryption-provider-config: /etc/kubernetes/encryption-provider.conf
          admission-control-config-file: /etc/kubernetes/admission/psa-config.yaml
          tls-min-version: VersionTLS12
          kubelet-certificate-authority: /etc/kubernetes/pki/ca.crt
        extraVolumes:
        - name: vol-dir-0
          hostPath: /etc/kubernetes
          mountPath: /etc/kubernetes
          pathType: Directory
      controllerManager:
        extraArgs:
          bind-address: "::"
          profiling: "false"
          tls-min-version: VersionTLS12
          flex-volume-plugin-dir: "/opt/libexec/kubernetes/kubelet-plugins/volume/exec/"
      scheduler:
        extraArgs:
          bind-address: "::"
          tls-min-version: VersionTLS12
          profiling: "false"
    initConfiguration:
      patches:
        directory: /etc/kubernetes/patches
      nodeRegistration:
        kubeletExtraArgs:
          node-labels: "kube-ovn/role=master"
          provider-id: PROVIDER_ID
          volume-plugin-dir: "/opt/libexec/kubernetes/kubelet-plugins/volume/exec/"
          protect-kernel-defaults: "true"
    joinConfiguration:
      patches:
        directory: /etc/kubernetes/patches
      nodeRegistration:
        kubeletExtraArgs:
          node-ip: NODE_IP
          node-labels: "kube-ovn/role=master"
          provider-id: PROVIDER_ID
          volume-plugin-dir: "/opt/libexec/kubernetes/kubelet-plugins/volume/exec/"
          protect-kernel-defaults: "true"
  machineTemplate:
    nodeDrainTimeout: 1m
    nodeDeletionTimeout: 5m
    infrastructureRef:
      apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
      kind: DCSMachineTemplate
      name: <cp-dcs-machine-template-name>
  replicas: 3
  version: <control-plane-kubernetes-version>
TIP

替代方案:引用集中管理的 Secret,而非内联内容

Alauda Container Platform DCS Infrastructure Provider 插件会在 cpaas-system 命名空间中提供名为 dcs-kubernetes-<kubernetes-major-minor>-files 的 Secret(例如,Kubernetes 1.33 对应 dcs-kubernetes-1.33-files)。其中包含 psa-config.yaml、control-plane-kubelet-patch.json 和 audit-policy.yaml 的规范内容,并会随每次发布一同更新。

存在该 Secret 时,可以将三个内联的 files 条目替换为 contentFrom.secret 引用。内联形式和 Secret 引用形式在功能上等效;使用 Secret 可使文件内容与已安装的插件版本保持一致,并避免集群升级时手动更新。

files:
- contentFrom:
    secret:
      key: psa-config.yaml
      name: dcs-kubernetes-1.33-files
  owner: "root:root"
  path: /etc/kubernetes/admission/psa-config.yaml
  permissions: "0644"
- contentFrom:
    secret:
      key: control-plane-kubelet-patch.json
      name: dcs-kubernetes-1.33-files
  owner: "root:root"
  path: /etc/kubernetes/patches/kubeletconfiguration0+strategic.json
  permissions: "0644"
- contentFrom:
    secret:
      key: audit-policy.yaml
      name: dcs-kubernetes-1.33-files
  owner: "root:root"
  path: /etc/kubernetes/audit/policy.yaml
  permissions: "0644"

encryption-provider.conf 不属于此 Secret,也完全不属于 files——它由 DCS provider 提供。请参阅如何交付加密 provider 配置。

最低插件版本:从 v1.0.13 开始,DCS Provider 插件会提供此 Secret。较旧的插件版本中不存在该 Secret;在这种情况下,请保留内联的 content: 形式。在决定使用哪种形式之前,请检查目标集群中是否存在该 Secret:

# Replace <kubernetes-major-minor> with the value matching this cluster
# (for example, 1.33 for Kubernetes v1.33.x).
K8S_MM=<kubernetes-major-minor>
kubectl -n cpaas-system get secret "dcs-kubernetes-${K8S_MM}-files" >/dev/null 2>&1 \
  && echo "Secret present — contentFrom.secret form is supported" \
  || echo "Secret missing — use inline content form"

如何交付加密 provider 配置

/etc/kubernetes/encryption-provider.conf 由 DCS provider 管理,而非由 KubeadmControlPlane 管理。provider 构建控制平面机器的 Ignition 配置时,会自行写入该文件,并移除来自 kubeadmConfigSpec.files 的该路径的任何条目。在此处添加条目不会产生任何效果——它既不会被合并,也不会被应用,因此写入其中的密钥会被静默忽略。

provider 写入的内容取决于集群:

条件文件内容
已设置 DCSCluster.spec.encryptionProviderConfigRef被引用 Secret 的 encryption-provider.conf 密钥。用于灾难恢复,此时两端必须持有相同的密钥。该 Secret 必须存在于运行 provider 的集群中;请参阅可选的灾难恢复部署
未设置,且控制平面尚未初始化(第一台控制平面机器)新生成的随机 AES-CBC 密钥
未设置,且控制平面已在运行(后续每台控制平面机器)从正在运行的 kube-apiserver 中读取的文件,因此所有控制平面节点共用一个密钥

工作节点不会收到此文件。

clusterConfiguration.apiServer.extraVolumes 会将 /etc/kubernetes 挂载到 API server 容器中,因此 apiServer.extraArgs.encryption-provider-config: /etc/kubernetes/encryption-provider.conf 在每个控制平面节点上都会生效。请保留此参数(如本附录所示),以启用 etcd 静态数据加密。移除此参数会关闭静态数据加密;provider 仍会写入该文件,但 API server 将不再使用它。

此行为适用于 DCS Provider v1.0.10 及更高版本,涵盖本文档支持的所有版本。


后续步骤

创建集群后:

故障排查

如果集群达到 Provisioned,但始终未变为 Ready——例如,由于 CNI 未部署,业务节点保持在 NotReady——请参阅排查卡在 Provisioned 状态的业务集群。