在 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. 基础设施资源
创建集群之前,请配置以下基础设施资源:
有关详细配置说明,请参阅 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 平台上的两个不同目标:
文件上传分为两个步骤: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 的要求,请遵循规划控制平面端点。对于 API server 前方没有负载均衡器的单控制平面部署,请参阅单控制平面(无外部 LB)布局。
6. 业务集群镜像仓库
确定此集群从哪个 registry 拉取其平台组件,即 Kube-OVN 以及 Alauda Container Platform 在集群上安装的平台模块。此选择不影响 kubeadm 管理的镜像,这些镜像来自 KubeadmControlPlane.spec.kubeadmConfigSpec.clusterConfiguration.imageRepository。
无论采用哪种方式,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:基本信息
前提条件检查:
创建集群前,请确保:
- DCS VM Template 已存在于 DCS 平台中,并且 Alauda OS 版本与 Kubernetes 版本匹配
- Kubernetes API 端点已准备就绪。对于外部 LoadBalancer,请在创建集群前创建该负载均衡器。对于
Self-built VIP,请预留 VIP 并使用 YAML 路径。
版本限制:只能创建平台支持的最新 Kubernetes 版本。
步骤 2:控制平面节点池
控制平面节点池固定为 3 个副本,以实现高可用性。
验证:关联的 IP Pool 必须有足够的可用 IP 地址(≥ 3)。
步骤 3:业务节点池
您可以添加多个业务节点池。每个池具有以下配置:
验证规则:
- 池名称在集群内必须唯一
- IP Pool 必须有足够的可用 IP 地址(≥ Replicas)
- maxSurge 和 maxUnavailable 必须满足以下限制:如果 maxSurge = 0,则 maxUnavailable > 0
- 如果集群将依赖池管理的持久磁盘,请保持
maxSurge = 0,以便在未来升级期间逐个替换节点
提示:将池名称设置为以集群名称后跟连字符作为前缀(例如 mycluster-worker-1),以避免不同集群之间发生命名冲突。
步骤 4:网络
验证: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 时发生同一命名空间内的资源冲突,并使操作期间的资源归属一目了然。
配置工作流
按以下步骤依次操作,以预配可正常运行的集群(控制平面和工作节点):
- 配置
KubeadmControlPlane(控制平面规范和 kubeadm 引导配置)。
- 配置
DCSCluster(基础设施绑定和负载均衡器引用)。
- 创建
Cluster 资源(用于关联上述两项的顶层 CAPI 对象)。
- 配置工作节点资源:
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> 语法表示特定于环境的值。其中一些值有规范的数据源,建议查询数据源,而不是手动选择:
Magic-Token 占位符
示例清单中有几个值看起来像占位符,但它们实际上是由 DCS Provider 在机器加入时替换的字面令牌。请保持原样:
手动替换或加引号包裹这些令牌会破坏加入流程,导致节点无法向控制平面注册。
网络规划和负载均衡器
创建控制平面资源之前,请规划网络架构并选择控制平面端点模式。
要求:
- 网络分段:规划控制平面节点的 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 中包含此参数。
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>
参数说明:
有关组件版本(例如 <dns-image-tag>、<etcd-image-tag>),请参阅 OS Support Matrix。
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>
参数说明:
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:
- 在 bootstrap 期间,provider 仅在第一个
kubeadm init 控制平面节点上注入 dcs-bootstrap-vip.service。此服务会在 kubeadm 启动前添加 <self-built-vip>/32。
- 控制平面节点注册后,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>
参数说明:
集群注解:
上面的示例展示了三个注解,但完整的 Cluster 资源还包含其他几个注解。下表列出了由 operator 编写的注解(其他一些注解由 ACP 控制器写入,不应预先设置):
集群启动后,ACP 控制器可能会写入其他只读注解(cpaas.io/cpu-cores-number、cpaas.io/memories、cpaas.io/nodes-number 等)。这些注解由系统计算,应用 YAML 时不得预先设置。
集群标签:
部署节点
有关部署工作节点的说明,请参阅在 Huawei DCS 上管理节点。
集群验证
部署所有集群资源后,请验证集群是否已成功创建并正常运行。
使用控制台
- 导航至 集群 → 集群
- 在集群列表中找到新创建的集群
- 验证集群状态是否显示为 运行中
- 检查所有控制平面节点和工作节点是否为 就绪
使用 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}'
请按以下方式解释该条件:
检查已观测到的规则和成员快照:
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 写入的内容取决于集群:
工作节点不会收到此文件。
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 状态的业务集群。