在 Huawei Cloud Stack 上创建集群

本文档提供了使用 Cluster API 在 Huawei Cloud Stack 平台上创建 Kubernetes 集群的完整说明。

前提条件

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

1. 安装所需插件

global 集群上安装以下插件:

  • Alauda Container Platform Kubeadm Provider
  • Alauda Container Platform HCS Infrastructure Provider

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

2. 准备 HCS 基础设施输入

在编写本文档中的任何 YAML 之前,请先准备好所有 HCS 相关输入:

  • HCS 凭证 Secret 值
  • Provider 可识别的计算值,例如 imageNameflavorNameavailabilityZone
  • 集群网络清单,包括集群使用的子网和可用 IP 范围
  • 控制平面 ELB 地址规划,包括 vipAddressvipSubnetName 以及固定的 L4 和 L7 IP
  • 控制平面和 worker 节点的静态 IP 池规划

完整的检查清单、来源信息和约束条件请参见 Huawei Cloud Stack 的基础设施资源

集群创建概览

从高层来看,你将在 global 集群中创建以下 Cluster API 资源,以便部署基础设施并引导一个可用的 Kubernetes 集群。

在编写本页中的任何 YAML 之前,请先完成 Huawei Cloud Stack 的基础设施资源 中的准备检查清单。该清单涵盖了 provider 期望的值、这些值的获取方式,以及在填写 manifest 之前必须提前规划的字段。

WARNING

重要的命名空间要求

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

WARNING

Workload 集群命名

workload cluster-name 不能global。该名称是为 global 集群保留的,重复使用会导致 workload 集群资源与 cpaas-system 中的 global 集群资源发生冲突。global- 前缀保留给 global 集群 DR 工作流所拥有的资源;请参见 通用前提条件。不要将 global- 用于 workload 集群资源,因为故障切换操作可能会将这些资源视为属于 global 集群。

作为约定,请将 CAPI Cluster 和 provider 集群资源(HCSCluster)命名为完全相同的 <cluster-name>,并将非根级 CAPI 和 provider 资源(KubeadmControlPlaneKubeadmConfigTemplateMachineDeployment、machine 模板、machine config pool 等)统一以前缀 <cluster-name>- 命名——例如,示例 manifest 使用 <cluster-name>-kcp。这是一项建议,而非 controller 强制规则,但它可以防止多个 workload 集群同时存在于 cpaas-system 时发生同命名空间冲突,并使资源归属在操作期间更清晰。

集群创建流程按以下顺序进行:

  1. 配置 HCS 身份认证(Secret)
  2. 创建 machine configuration pool(HCSMachineConfigPool)
  3. 配置 machine template(HCSMachineTemplate)
  4. 配置 KubeadmControlPlane
  5. 配置 HCSCluster
  6. 创建 Cluster

控制平面配置

控制平面负责管理集群状态、调度和 Kubernetes API。本节展示如何配置高可用控制平面。

WARNING

配置参数指南

在配置资源时,请谨慎修改参数:

  • 仅替换用 <> 括起来的值,将其替换为你环境中的具体值
  • 保留所有其他参数,因为它们代表了优化后的或必需的配置
  • 修改非占位符参数可能会导致集群不稳定或集成问题

配置 HCS 身份认证

HCS 身份认证信息存储在 Secret 资源中。

apiVersion: v1
kind: Secret
metadata:
  name: <credential-secret-name>
  namespace: cpaas-system
type: Opaque
data:
  accessKey: <base64-encoded-access-key>
  secretKey: <base64-encoded-secret-key>
  projectID: <base64-encoded-project-id>
  region: <base64-encoded-region>
  externalGlobalDomain: <base64-encoded-domain>
  schema: <base64-encoded-schema>
参数描述
.data.accessKey来自 My Settings > Access Keys 的 HCS access key ID(base64 编码)
.data.secretKey来自 My Settings > Access Keys 的 HCS secret access key(base64 编码)
.data.projectID来自 My Settings > Resource Spaces 的 Resource Space ID(base64 编码)
.data.regionprovider 使用的 HCS region API 值(base64 编码)。租户管理员无法从 HCS UI 获取此值;请从 HCS 管理员处获取
.data.externalGlobalDomainprovider 使用的 HCS 平台访问域名(base64 编码)
.data.schemaHCS IAM endpoint 的可选 API scheme,通常为 https(base64 编码)。如果省略,provider 将使用 https

未设置 schema 的现有凭证 Secret 仍可继续正常使用。只有当你的 HCS IAM endpoint 使用 http 而不是默认的 https 时,才需要设置 schema

你可以复用现有的 HCS 凭证 Secret。其名称不必与集群名称一致,但 HCSCluster.spec.identityRef.name 必须引用该 Secret。

配置 Machine Configuration Pool

HCSMachineConfigPool 定义了预配置的主机名、静态 IP 地址,以及由 pool 管理的 VM 持久化磁盘。

WARNING

Pool 大小要求

该配置池至少必须包含与你计划部署的控制平面节点数量相同的条目。

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

如果你在 machine configuration pool 中使用 subnetName,请在 HCSCluster.spec.network.subnets 中包含相同的子网名称。

对于初始集群创建流程,仅按名称列出一个现有子网即可,因为 controller 会在集群变为 Ready 之前解析子网元数据。如果你之后向一个已处于 Ready 状态的 HCSCluster 中新增另一个子网,不要只追加 name。请用完整的子网对象补丁更新父级 HCSCluster.spec.network.subnets 条目,这样后续的 machine 或 ELB 操作就可以复用已解析的子网元数据。

apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: HCSMachineConfigPool
metadata:
  name: <cluster-name>-cp-pool
  namespace: cpaas-system
  labels:
    cluster.x-k8s.io/cluster-name: <cluster-name>
spec:
  configs:
    - hostname: master-1
      networks:
        - subnetName: <subnet-name>
          ipAddress: 192.168.1.11
      persistentDisks:
        - slot: 0
          size: 100
          type: SSD
          mountPath: /var/cpaas
          format: xfs
    - hostname: master-2
      networks:
        - subnetName: <subnet-name>
          ipAddress: 192.168.1.12
      persistentDisks:
        - slot: 0
          size: 100
          type: SSD
          mountPath: /var/cpaas
          format: xfs
    - hostname: master-3
      networks:
        - subnetName: <subnet-name>
          ipAddress: 192.168.1.13
      persistentDisks:
        - slot: 0
          size: 100
          type: SSD
          mountPath: /var/cpaas
          format: xfs
参数类型必填描述
.spec.configs[]array非空的 machine 配置列表
.spec.configs[].hostnamestringVM 主机名。使用小写字母、数字、连字符(-)或点(.);该值必须以小写字母或数字开头和结尾,且长度不得超过 253 个字符(符合 RFC 1035 中 DNS 名称长度限制)。前导点、尾随点、全点字符串以及大写字母都会被拒绝,controller 会将错误显示在所属 MachineCluster 的状态中。关于当该值包含点时 hostnamehostname -f 的返回结果,请参见下面的 节点上的主机名行为 小节。
.spec.configs[].networks[]arrayVM 的非空网络配置列表
.spec.configs[].networks[].subnetNamestring否*新 manifest 推荐使用的 subnet 名称字段
.spec.configs[].networks[].subnetIdstring否*子网 ID。当子网名称存在歧义时,请使用此字段替代 subnetName
.spec.configs[].networks[].ipAddressstringVM 的静态 IP 地址
.spec.configs[].persistentDisks[]array在 HCSMachine 删除-重建替换后仍可保留的 EVS 磁盘
.spec.configs[].persistentDisks[].slotint是*单个 machine 配置中的磁盘槽位。对于同一 hostname,槽位必须唯一且从 0 开始连续
.spec.configs[].persistentDisks[].sizeint是*EVS 磁盘大小,单位 GB。对于新创建的 EVS 数据盘,使用 1032768 GB。已存在且被认领的磁盘必须与其当前大小一致
.spec.configs[].persistentDisks[].typestring是*目标 availability zone 中可用的 EVS 磁盘类型名称
.spec.configs[].persistentDisks[].mountPathstringGuest 挂载路径。对于必须在 VM 替换后仍然保留的平台状态,请使用 /var/cpaas
.spec.configs[].persistentDisks[].formatstring文件系统格式。如果省略,provider 将使用 xfs
.spec.configs[].persistentDisks[].mountOptionsarray挂载选项。如果省略,provider 将使用 defaults,noatime

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

如果指定了 persistentDisks,则持久化磁盘字段为必填。

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

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

注意: 若要为一个节点挂载多个 NIC,请添加多个 networks[] 条目。provider 只使用这些条目来挂载 NIC,并分配 subnet selector 以及静态 IP。它不支持声明每个 NIC 的角色、默认网关、静态路由或每个 NIC 的 DNS 设置。

节点上的主机名行为

provider 根据 hostname 派生节点的 POSIX 主机名和 FQDN,如下所示:

Pool hostname节点 hostname节点 hostname -f写入的 /etc/hosts 条目
master-1(不含点)master-1master-1(resolver 返回短名称)provider 不会添加
master-1.example.org(含点)master-1(短标签,点及其后内容会被剥离)master-1.example.org<node-ip> master-1.example.org master-1

带点的形式适用于配置依赖 FQDN 解析的应用(hostname -f、包含 SAN 条目的证书、日志标签)。当提供带点的主机名时,provider 会设置 prefer_fqdn_over_hostname: false 并启用 cloud-init 的 manage_etc_hosts,因此 POSIX 工具仍会看到短名称,而 hostname -f 会返回完整的 FQDN。

无效的主机名(前导点、尾随点、全点字符串、大写字母,或任何违反字段约束的值)会在 VM 启动前被拒绝。错误会写入所属 Machine.status,并反映到 Cluster.status.conditions 中,因此你可以在 kubectl describe cluster <name>kubectl get machines -n cpaas-system -o wide 中看到它。

配置 Machine Template

HCSMachineTemplate 定义了控制平面节点的 VM 规格。

WARNING

存储要求

建议为控制平面节点配置以下数据盘挂载点:

  • /var/lib/etcd - etcd 数据(10GB+)
  • /var/lib/kubelet - kubelet 数据(100GB+)
  • /var/lib/containerd - 容器运行时数据(100GB+)

/var/cpaas 路径用于存储平台状态和日志。当它必须在 VM 替换后仍然保留时,请在 HCSMachineConfigPool.spec.configs[].persistentDisks[] 中声明。

apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: HCSMachineTemplate
metadata:
  name: <cluster-name>-control-plane
  namespace: cpaas-system
spec:
  template:
    spec:
      imageName: <vm-image-name>
      flavorName: <instance-flavor>
      availabilityZone: <availability-zone>
      rootVolume:
        type: SSD
        size: 100
      configPoolRef:
        name: <cluster-name>-cp-pool
      dataVolumes:
        - size: 10
          type: SSD
          mountPath: /var/lib/etcd
          format: xfs
        - size: 100
          type: SSD
          mountPath: /var/lib/kubelet
          format: xfs
        - size: 100
          type: SSD
          mountPath: /var/lib/containerd
          format: xfs
参数类型必填描述
.spec.template.spec.imageNamestringHCS 镜像名称。使用当前版本 OS 支持矩阵中发布的镜像标识;上方 manifest 中显示为占位符 <alaudaos-version>。精确名称会随着每个 Alauda OS 版本变化,因此不要在不同版本之间硬编码示例值。
.spec.template.spec.flavorNamestringprovider 可识别的 HCS API 值,与 Flavor.Name 匹配。不要使用租户 UI 中显示的名称
.spec.template.spec.availabilityZonestringprovider 可识别的 HCS API 值,与 ZoneName 匹配。不要使用租户 UI 中显示的名称
.spec.template.spec.rootVolume.typestring卷类型(SSDSATA
.spec.template.spec.rootVolume.sizeint系统盘大小,单位 GB
.spec.template.spec.configPoolRef.namestring所引用的 HCSMachineConfigPool 名称
.spec.template.spec.dataVolumes[]array数据卷配置
.spec.template.spec.dataVolumes[].sizeint是*数据盘大小,单位 GB
.spec.template.spec.dataVolumes[].typestring是*卷类型
.spec.template.spec.dataVolumes[].mountPathstring是*挂载路径
.spec.template.spec.dataVolumes[].formatstring是*文件系统格式(xfsext4

*当指定 dataVolumes 时为必填。

dataVolumes[] 会随 ECS 一起重建。不要将其用于 /var/cpaas 或任何必须在滚动替换后仍然存在的路径。请将这些路径放在 HCSMachineConfigPool.spec.configs[].persistentDisks[] 中。

注意: 不要在 HCSMachineTemplate manifest 中设置诸如 providerIDserverId 之类的运行时身份字段。provider 会在创建 HCS 实例时分配这些值。

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

配置 KubeadmControlPlane

KubeadmControlPlane 定义了 Kubernetes 控制平面配置。

apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: KubeadmControlPlane
metadata:
  name: <cluster-name>-kcp
  namespace: cpaas-system
spec:
  replicas: 3
  version: <kubernetes-version>
  rolloutStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 0
  kubeadmConfigSpec:
    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",
            "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/encryption-provider.conf
        owner: root:root
        permissions: "0600"
        content: |
          apiVersion: apiserver.config.k8s.io/v1
          kind: EncryptionConfiguration
          resources:
          - resources:
            - secrets
            providers:
            - aescbc:
                keys:
                - name: key1
                  secret: bootstrap-placeholder
      - path: /etc/kubernetes/audit/policy.yaml
        owner: root:root
        permissions: "0644"
        content: |
          apiVersion: audit.k8s.io/v1
          kind: Policy
          rules:
          - level: Metadata
    clusterConfiguration:
      imageRepository: <image-repository>
      dns:
        imageTag: <dns-image-tag>
      etcd:
        local:
          imageTag: <etcd-image-tag>
      apiServer:
        extraArgs:
          audit-log-format: json
          audit-log-mode: batch
          audit-log-path: /etc/kubernetes/audit/audit.log
          audit-policy-file: /etc/kubernetes/audit/policy.yaml
          admission-control-config-file: /etc/kubernetes/admission/psa-config.yaml
          encryption-provider-config: /etc/kubernetes/encryption-provider.conf
          kubelet-certificate-authority: /etc/kubernetes/pki/ca.crt
          profiling: "false"
          tls-min-version: VersionTLS12
        extraVolumes:
          - name: vol-dir-0
            hostPath: /etc/kubernetes
            mountPath: /etc/kubernetes
            pathType: Directory
      controllerManager:
        extraArgs:
          bind-address: "::"
          flex-volume-plugin-dir: "/opt/libexec/kubernetes/kubelet-plugins/volume/exec/"
          profiling: "false"
          tls-min-version: VersionTLS12
      scheduler:
        extraArgs:
          bind-address: "::"
          profiling: "false"
          tls-min-version: VersionTLS12
    postKubeadmCommands:
      - chmod 600 /var/lib/kubelet/config.yaml
    initConfiguration:
      patches:
        directory: /etc/kubernetes/patches
      nodeRegistration:
        kubeletExtraArgs:
          node-labels: "kube-ovn/role=master"
          protect-kernel-defaults: "true"
          volume-plugin-dir: "/opt/libexec/kubernetes/kubelet-plugins/volume/exec/"
    joinConfiguration:
      patches:
        directory: /etc/kubernetes/patches
      nodeRegistration:
        kubeletExtraArgs:
          node-labels: "kube-ovn/role=master"
          volume-plugin-dir: "/opt/libexec/kubernetes/kubelet-plugins/volume/exec/"
  machineTemplate:
    nodeDrainTimeout: 1m
    nodeDeletionTimeout: 5m
    infrastructureRef:
      apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
      kind: HCSMachineTemplate
      name: <cluster-name>-control-plane

HCS controller 在解析 cloud-init 数据时还会注入文件。它会为控制平面机器写入 /etc/kubernetes/pki/kubelet.crt/etc/kubernetes/pki/kubelet.key/etc/kubernetes/encryption-provider.conf。对于第一台控制平面机器,controller 会生成 encryption provider 配置。在控制平面初始化之后,它会尝试复用现有的 kube-apiserver encryption provider 配置。如果你在 /etc/kubernetes/encryption-provider.conf 中包含了一个 bootstrap 文件,请将其视为占位符,因为 controller 生成或同步的文件具有优先级。

注意: 请同时配置 apiServer.extraArgsapiServer.extraVolumes。如果该 volume 未挂载,kube-apiserver 将无法读取写入 /etc/kubernetes 下的文件。

注意: 上面的 rolloutStrategy.rollingUpdate.maxSurge: 0 示例适用于具有静态 IP 的高可用控制平面。对于至少有三个副本的固定规模控制平面池,请保持该设置,以便替换操作按先缩容、再扩容的顺序进行。如果你创建的是单控制平面 HCS 集群(spec.replicas: 1),不要将 rolloutStrategy 块复制到创建 manifest 中。KubeadmControlPlane 的校验会拒绝单副本使用这种缩容式 rollout 配置。

注意: HCS 也支持通过设置 spec.replicas: 1 并在引用的 HCSMachineConfigPool 中准备一个控制平面配置条目来创建单控制平面集群。请将其视为仅用于创建的拓扑,并在该创建 manifest 中保持 rollout strategy 未设置。本文档中的升级流程不支持单控制平面 HCS 集群。

仅将 OS 支持矩阵 用于其明确列出的组件版本,例如受支持的 Alauda OS 镜像对应的 coredns 和 etcd 镜像 tag。它并不是所有 HCS manifest 值的完整来源。在应用此 YAML 之前,还请使用已批准的发布基线来获取诸如 imageRepository、DNS image repository、Kube-OVN version、Kube-OVN join CIDR、Pod CIDR 和 Service CIDR 等值。

配置 HCSCluster

HCSCluster 资源定义了 HCS 基础设施配置。

HCS provider 会在 HCS 平台上为 Kubernetes API server 创建一个 Elastic Load Balance(ELB)。该 ELB 必须保持启用 Hybrid Load Balancing,以便集群节点也可以通过 ELB 地址访问 API server。

对于本文档中的 HCS 工作流,请提供 vipAddresselbVirsubnetL4IpselbVirsubnetL7Ips。每个 elbVirsubnetL4Ips[].ipselbVirsubnetL7Ips[].ips 条目都必须包含两个 IP。

如果你设置了 vipDomainName,请配置 HCS Cloud DNS Private Zones,使该域名解析到 vipAddress

在任何地方引用某个子网之前,请先在 spec.network.subnets 中列出该集群的所有子网。vipSubnetNameelbVirsubnetL4Ips[].subnetNameelbVirsubnetL7Ips[].subnetName 以及 HCSMachineConfigPool 中使用的 subnetName 值都必须存在于 spec.network.subnets 中。

对于初始集群创建流程,controller 可以从 name 解析现有子网元数据。对于已存在且处于 Ready 状态的集群,请追加完整的子网对象,而不是只追加 name。请包含 id,并为控制平面 ELB 将使用的任何子网包含 neutronSubnetId。同时也要在子网清单中保留 cidrgatewayIpprimaryDNSsecondaryDNS

集群创建完成后,不要关闭 provider 创建的 ELB 上的 Hybrid Load Balancing。集群依赖该 ELB 模式,以便节点可以通过 ELB 地址访问 API server。

apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: HCSCluster
metadata:
  name: <cluster-name>
  namespace: cpaas-system
spec:
  controlPlaneLoadBalancer:
    vipAddress: <control-plane-vip-address>
    vipSubnetName: <vip-subnet-name>
    vipDomainName: <control-plane-vip-domain-name>
    elbVirsubnetL4Ips:
      - subnetName: <subnet-name>
        ips:
          - <l4-ip-1>
          - <l4-ip-2>
    elbVirsubnetL7Ips:
      - subnetName: <subnet-name>
        ips:
          - <l7-ip-1>
          - <l7-ip-2>
  networkType: kube-ovn
  network:
    vpc:
      name: <vpc-name>
    subnets:
      - name: <subnet-name>
    securityGroup:
      name: <security-group-name>
  identityRef:
    name: <credential-secret-name>
参数类型必填描述
.spec.networkTypestring网络类型,当前支持 kube-ovn
.spec.network.vpc.namestringVPC 名称
.spec.network.subnets[].namestring集群子网清单中的子网名称。集群 manifest 中其他位置引用的每个子网都必须出现在此列表中
.spec.network.subnets[].idstring推荐子网 ID。对于已存在且处于 Ready 状态的集群,当你后续追加子网时请包含此值,以便 machine 创建可以安全复用子网清单
.spec.network.subnets[].neutronSubnetIdstringELB 子网推荐使用Neutron subnet ID。对于控制平面 ELB 使用的任何子网都应包含此值
.spec.network.subnets[].cidrstring推荐保留在集群子网清单中的子网 CIDR
.spec.network.subnets[].gatewayIpstring推荐保留在集群子网清单中的子网网关
.spec.network.subnets[].primaryDNSstring推荐保留在集群子网清单中的主 DNS
.spec.network.subnets[].secondaryDNSstring推荐保留在集群子网清单中的备 DNS
.spec.network.securityGroup.namestring安全组名称
.spec.identityRef.namestringHCSCluster 引用的非空凭证 Secret 名称;该值不必与集群名称一致
.spec.controlPlaneLoadBalancerobjectprovider 创建的控制平面 ELB 的 ELB 设置
.spec.controlPlaneLoadBalancer.vipAddressstring控制平面 ELB 的固定 VIP
.spec.controlPlaneLoadBalancer.vipSubnetNamestring包含 ELB VIP 的子网名称。该子网也必须出现在 .spec.network.subnets
.spec.controlPlaneLoadBalancer.vipDomainNamestringVIP 的域名。配置 HCS Cloud DNS Private Zones 使其解析到 vipAddress
.spec.controlPlaneLoadBalancer.elbVirsubnetL4Ips[]arrayHybrid Load Balancing 使用的 L4 虚拟子网 IP 组
.spec.controlPlaneLoadBalancer.elbVirsubnetL4Ips[].subnetNamestringL4 虚拟子网 IP 所属的子网名称。该子网也必须出现在 .spec.network.subnets
.spec.controlPlaneLoadBalancer.elbVirsubnetL4Ips[].ips[]string两个固定的 L4 虚拟子网 IP
.spec.controlPlaneLoadBalancer.elbVirsubnetL7Ips[]arrayHybrid Load Balancing 使用的 L7 虚拟子网 IP 组
.spec.controlPlaneLoadBalancer.elbVirsubnetL7Ips[].subnetNamestringL7 虚拟子网 IP 所属的子网名称。该子网也必须出现在 .spec.network.subnets
.spec.controlPlaneLoadBalancer.elbVirsubnetL7Ips[].ips[]string两个固定的 L7 虚拟子网 IP

创建 manifest 中不要包含 spec.controlPlaneEndpoint。在 HCS 创建流程中,controller 会在 HCSCluster 创建后根据 spec.controlPlaneLoadBalancer 推导并填充该字段。不要手动设置 controlPlaneEndpoint,也不要添加空的 controlPlaneEndpoint 对象。如果 manifest 中显式存在 controlPlaneEndpoint,则它必须同时包含 hostport

配置 Cluster

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

apiVersion: cluster.x-k8s.io/v1beta1
kind: Cluster
metadata:
  name: <cluster-name>
  namespace: cpaas-system
  annotations:
    cpaas.io/sentry-deploy-type: Baremetal
    cpaas.io/alb-address-type: ClusterAddress
    capi.cpaas.io/resource-group-version: infrastructure.cluster.x-k8s.io/v1beta1
    capi.cpaas.io/resource-kind: HCSCluster
    cpaas.io/kube-ovn-join-cidr: <kube-ovn-join-cidr>
    cpaas.io/kube-ovn-version: <kube-ovn-version>
  labels:
    cluster-type: HCS
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: HCSCluster
    name: <cluster-name>
注解描述
cpaas.io/sentry-deploy-type部署类型,设置为 Baremetal
cpaas.io/alb-address-typeALB 地址类型,设置为 ClusterAddress
capi.cpaas.io/resource-group-version资源组版本
cpaas.io/resource-kind资源类型,设置为 HCSCluster
cpaas.io/kube-ovn-join-cidrKube-OVN join 子网 CIDR
cpaas.io/kube-ovn-versionKube-OVN 版本

集群验证

部署完所有集群资源后,请验证集群是否已成功创建。

使用 kubectl

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

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

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

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

预期结果

成功创建的集群应显示:

  • Cluster 状态:RunningProvisioned
  • 所有控制平面机器:Running
  • Kubernetes 节点:Ready
  • Cluster Module 状态:Completed

添加 Worker 节点

有关向集群添加 worker 节点的说明,请参阅 管理节点

升级集群

有关升级集群组件的说明,请参阅 升级集群

故障排查

如果集群已经达到 Provisioned,但一直无法变为 Ready——例如,由于 CNI 未部署导致 workload 节点一直处于 NotReady——请先参考与 provider 无关的 Workload 集群卡在 Provisioned 状态的故障排查

对于 HCS 特有的失败模式(例如,由于带点的 HCSMachineConfigPool 主机名生成了包含点的 POSIX 主机名,导致 kubeadm init 一直无法完成),请参阅 Huawei Cloud Stack Workload 集群故障排查