华为云CCE+鲲鹏节点池:信创应用容器化上云实战指南

举报
行者·全栈架构师 发表于 2026/10/30 16:15:04 2026/10/30
【摘要】 华为云CCE(CloudContainerEngine)是信创场景下首选的容器平台。本文记录了如何创建CCE集群、配置鲲鹏节点池、将一个SpringBoot应用从自建K8s迁移到CCE的全过程。重点讲清楚了CCE的计费模式选型、节点池配置的最佳实践,以及迁移过程中遇到的3个坑和解决方式。

文章摘要:华为云 CCE(Cloud Container Engine)是信创场景下首选的容器平台。本文记录了如何创建 CCE 集群、配置鲲鹏节点池、将一个 Spring Boot 应用从自建 K8s 迁移到 CCE 的全过程。重点讲清楚了 CCE 的计费模式选型、节点池配置的最佳实践,以及迁移过程中遇到的 3 个坑和解决方式。

为什么选择 CCE?

在信创场景下,CCE(Cloud Container Engine)对比自建 K8s 的优势:

对比项 自建 K8s(裸机) 华为云 CCE
Master 节点 自己运维 + 升级 华为云托管
故障恢复 手动处理 etcd 故障 自动恢复
鲲鹏节点 自己找 ARM64 镜像 一键创建鲲鹏节点池
存储对接 手动配置 CSI 集成 EVS/OBS/SFS
网络 Calico 自运维 集成 VPC 网络
安全 自己做 集成容器安全 CGS

第一步:创建 CCE 集群

通过控制台

# 也可以用 huaweicloud CLI 创建,更可重复
hcloud CCE CreateCluster \
    --name="xinchuang-prod" \
    --flavor="cce.s2.medium" \
    --version="v1.28" \
    --container_network_type="vpc-router" \
    --eni_network=false \
    --vpc_id="vpc-xxx" \
    --subnet_id="subnet-xxx"

关键参数说明

# cluster-config.yaml
apiVersion: v1
kind: Cluster
name: xinchuang-prod
spec:
  # Master 节点规格(生产集群建议 s2 系列)
  flavor: cce.s2.medium    # 1000 节点规模
  # 容器网络(VPC 网络性能最好)
  containerNetwork:
    mode: vpc-router       # vpc-router / tunnel / eni
    cidr: 10.0.0.0/16      # 不要跟 VPC 网段重叠
  # 服务网络
  serviceNetwork:
    cidr: 10.247.0.0/16

第二步:配置鲲鹏节点池

# 创建鲲鹏节点池
hcloud CCE AddNodePool \
    --cluster_id="${CLUSTER_ID}" \
    --name="kunpeng-pool-32c" \
    --node_template='{
        "flavor": "kc1.4xlarge.2",       # 32C/64GB 鲲鹏通用计算型
        "os": "EulerOS 2.9",
        "root_volume": {
            "volumetype": "SSD",
            "size": 100
        },
        "data_volumes": [{
            "volumetype": "SSD",
            "size": 200
        }],
        "count": 5,
        "max_pods": 110
    }'

节点规格选型

用途 规格 配置 月成本(估)
通用 Web kc1.2xlarge.2 16C/32GB ¥1,200
高内存 kc1.4xlarge.4 32C/128GB ¥3,800
数据库 kc1.4xlarge.2 32C/64GB + 高IO磁盘 ¥4,500
AI 推理 kc1p.4xlarge 32C/64GB + NPU ¥5,000

CCE + 鲲鹏节点池整体架构

下图展示了 CCE 集群与鲲鹏节点池的整体架构,包括 VPC 网络、控制面托管、节点池分组、存储集成和 Ingress 流量入口。

Mermaid 图表 1

架构说明:

  • CCE 控制面由华为云托管,用户无需运维 Master 节点,自动升级、自动容灾
  • 节点池按架构分组(x86 / 鲲鹏),通过节点亲和性确保工作负载调度到正确架构
  • 存储层按场景选择:单副本用 EVS、多副本用 SFS、日志归档用 OBS
  • 中间件使用华为云托管服务(DCS/DDS/RDS),降低运维负担
  • 流量入口通过 CCE Ingress 分发,支持灰度发布和蓝绿部署

第三步:迁移 Spring Boot 应用到 CCE

原来的部署

# k8s-deploy.yaml(跟自建 K8s 完全一样,不用改)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service
spec:
  replicas: 3
  selector:
    matchLabels:
      app: order-service
  template:
    metadata:
      labels:
        app: order-service
    spec:
      containers:
      - name: order-service
        image: registry.company.com/order-service:latest
        ports:
        - containerPort: 8080
        env:
        - name: SPRING_PROFILES_ACTIVE
          value: "prod-kunpeng"
        resources:
          requests:
            cpu: "2"
            memory: "4Gi"
          limits:
            cpu: "4"
            memory: "8Gi"
        livenessProbe:
          httpGet:
            path: /actuator/health
            port: 8080
          initialDelaySeconds: 60
      tolerations:
      - key: "kunpeng"
        operator: "Exists"
# 部署到 CCE(跟自建 K8s 用法一样)
kubectl apply -f k8s-deploy.yaml

# 暴露服务
kubectl expose deployment order-service \
    --name=order-service-svc \
    --type=LoadBalancer \
    --port=80 --target-port=8080

完整 YAML 配置集(生产推荐)

生产环境中建议将配置拆分为多个 YAML 文件,便于管理和灰度发布。

# 1. configmap.yaml —— 应用配置外置
apiVersion: v1
kind: ConfigMap
metadata:
  name: order-service-config
  namespace: default
data:
  application-prod-kunpeng.yml: |
    server:
      port: 8080
    spring:
      datasource:
        url: jdbc:opengauss://og-master:5432/order_db
        username: order_user
        password: ${DB_PASSWORD}
    logging:
      level:
        com.company.order: INFO
---
# 2. deployment.yaml —— 完整版含亲和性 + 存储挂载
apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service
  namespace: default
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
      maxSurge: 1
  selector:
    matchLabels:
      app: order-service
  template:
    metadata:
      labels:
        app: order-service
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: "node.kubernetes.io/instance-type"
                operator: In
                values:
                - "kunpeng"
      containers:
      - name: order-service
        image: registry.company.com/order-service:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
          name: http
        env:
        - name: SPRING_PROFILES_ACTIVE
          value: "prod-kunpeng"
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: password
        - name: JAVA_OPTS
          value: "-Xms4g -Xmx4g -XX:+UseG1GC -XX:+HeapDumpOnOutOfMemoryError"
        resources:
          requests:
            cpu: "2"
            memory: "4Gi"
          limits:
            cpu: "4"
            memory: "8Gi"
        livenessProbe:
          httpGet:
            path: /actuator/health/liveness
            port: 8080
          initialDelaySeconds: 60
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /actuator/health/readiness
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 5
        volumeMounts:
        - name: config
          mountPath: /app/config
          readOnly: true
        - name: logs
          mountPath: /app/logs
      volumes:
      - name: config
        configMap:
          name: order-service-config
      - name: logs
        emptyDir: {}
      tolerations:
      - key: "kunpeng"
        operator: "Exists"
---
# 3. service.yaml —— ClusterIP 供内部调用 + Headless 用于治理
apiVersion: v1
kind: Service
metadata:
  name: order-service-svc
  namespace: default
  labels:
    app: order-service
spec:
  type: ClusterIP
  ports:
  - port: 8080
    targetPort: 8080
    protocol: TCP
    name: http
  selector:
    app: order-service
---
# 4. ingress.yaml —— 通过 CCE Ingress 对外暴露
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: order-service-ingress
  namespace: default
  annotations:
    kubernetes.io/ingress.class: cce
spec:
  rules:
  - host: order.xinchuang.company.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: order-service-svc
            port:
              number: 8080
---
# 5. hpa.yaml —— 基于 CPU 和内存的自动弹性伸缩
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: order-service-hpa
  namespace: default
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: order-service
  minReplicas: 3
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80

一次性创建所有资源:

kubectl apply -f configmap.yaml
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl apply -f ingress.yaml
kubectl apply -f hpa.yaml

# 一键应用所有 YAML(推荐)
kubectl apply -f ./

1. 节点选择器没配,Pod 调度到了 x86 节点

现象:应用在鲲鹏节点池上部署后,P99 延迟从原来的 35ms 降到了 52ms。

原因:镜像虽然支持 multi-arch,但它被调度到了 x86 节点上(如果同时有 x86 和鲲鹏节点池)。x86 节点规格更小,导致性能下降。

解决:添加节点亲和性

spec:
  template:
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: "node.kubernetes.io/instance-type"
                operator: In
                values:
                - "kunpeng"

2. 镜像架构不对,容器启动失败

现象:Deployment 创建后 Pod 一直处于 CrashLoopBackOff 状态,kubectl logs 看到 exec format error。

$ kubectl logs order-service-7d8f9c6b4f-abc12
standard_init_linux.go: exec: exec format error

原因:镜像构建在 x86 机器上,没有做 ARM64 交叉编译。鲲鹏节点是 ARM64 架构,x86 的二进制无法直接运行。即使节点池选对了,镜像本身不支持 ARM64 也白搭。

解决:使用多架构镜像构建(Docker Buildx),或直接在鲲鹏节点上编译。

# 方案 A:Docker Buildx 构建多架构镜像(推荐)
docker buildx build \
    --platform linux/amd64,linux/arm64 \
    -t registry.company.com/order-service:latest \
    --push .

# 方案 B:CI/CD 中分别构建两个标签
docker build -t registry.company.com/order-service:amd64-latest .              # x86 构建
docker build -t registry.company.com/order-service:arm64-latest .              # ARM64 构建

# 方案 C:在 Deployment 中明确指定架构
# 结合 nodeSelector 使用,只拉取对应架构的镜像

💡 经验:镜像架构问题是最隐蔽的坑。我们的 CI 流水线最开始只在 x86 构建机上跑 docker build,推上去的镜像是 amd64 格式,部署到鲲鹏节点上就报 exec format error。后来改成 Buildx 多架构构建,同时在 Deployment 中加上 nodeSelector: kubernetes.io/arch: arm64 兜底。

3. Pod 启动成功但存储挂载失败

现象:Pod 启动正常,应用日志报 “Permission denied” 或 “Directory not empty”,无法读写挂载的 EVS 磁盘。

$ kubectl exec order-service-7d8f9c6b4f-abc12 -- ls -la /data
ls: cannot open directory '/data': Permission denied

原因分析:CCE 使用的 EVS 卷默认挂载到节点后,Pod 内的用户(UID 非 root)没有写入权限。另外,如果 PVC 的 accessModes 配置为 ReadWriteOnce,多个副本间共用一个卷时第二个 Pod 会挂载失败。

# 错误配置:accessModes 不匹配多副本场景
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: order-data-pvc
spec:
  accessModes:
    - ReadWriteOnce   # 只能被一个 Pod 挂载
  resources:
    requests:
      storage: 100Gi

解决:根据场景选择合适的存储方案。

# 方案 A:单副本读写 —— 使用 EVS 高性能盘,注意 fsGroup
apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service
spec:
  template:
    spec:
      securityContext:
        fsGroup: 1000          # 与容器内 UID 一致
        runAsUser: 1000
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: order-data-pvc
---
# 方案 B:多副本共享读写 —— 使用 SFS(NFS)替代 EVS
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: order-shared-pvc
spec:
  accessModes:
    - ReadWriteMany             # 多节点多 Pod 同时读写
  storageClassName: csi-nas    # 使用 SFS 文件存储
  resources:
    requests:
      storage: 200Gi

💡 经验:第一次遇到这个问题时,我们排查了 2 天 —— 容器日志没有明确错误,只是应用启动后写入文件失败。最终通过 kubectl exec 进入容器用 id 命令发现容器内进程是 UID 1000,而 EVS 卷归属 root。加上 fsGroup 后问题解决。多副本场景一定要用 SFS 而不是 EVS,否则第二个 Pod 永远起不来。

计费模式选型

计费模式 适合场景 成本(对比按需)
按需 测试/临时任务 基准
包年包月(1 年) 稳定生产负载 -25%
包年包月(3 年) 长期稳定 -45%
竞价实例 批处理/弹性扩展 -70%

推荐策略:基础资源用包年包月 + 弹性资源用竞价实例。我们的 5 个鲲鹏节点中 3 个包年包月(保底容量)+ 2 个按需(高峰期自动扩容)。

常见问题(FAQ)

Q1:CCE 集群创建后,可以同时管理 x86 和鲲鹏节点池吗?

可以。 CCE 集群支持混合节点池架构,你可以在同一个集群下创建 x86 节点池和鲲鹏(ARM64)节点池。关键是要通过 nodeAffinity 和 nodeSelector 确保工作负载调度到正确的架构节点上。建议为不同架构的节点池打上差异化的标签(如 node.kubernetes.io/instance-type: kunpeng),并在 Deployment 中指定亲和性规则。

Q2:鲲鹏节点上的镜像从哪里获取?必须自己编译吗?

两种方式:

  1. 使用华为云 SWR 镜像仓库:SWR 支持多架构镜像(manifest list),拉取时会自动匹配节点架构。你只需要用 docker buildx 构建多架构镜像并推送到 SWR,CCE 会按需拉取对应版本。
  2. 使用华为开源镜像站:华为云维护了适配鲲鹏的常用开源镜像(如 Nginx、Redis、MySQL、Java 等),搜索 “Kunpeng” + 软件名即可找到。

推荐使用方案 1,自己维护基础镜像可以确保安全合规。

Q3:鲲鹏节点池的节点可以自动扩缩容吗?

支持。 CCE 提供了节点池的自动伸缩能力(Cluster Autoscaler),配置步骤:

  1. 在节点池中开启「弹性伸缩」开关
  2. 设置最小/最大节点数(如 min: 3, max: 10)
  3. 结合 HPA(Horizontal Pod Autoscaler)实现 Pod 级别的弹性

当业务高峰期 Pod 调度失败时,CCE 会自动触发节点池扩容;低谷时自动缩容释放资源。注意竞价实例节点不支持自动缩容到 0。

Q4:迁移到 CCE 后,之前自建 K8s 的 YAML 文件还能用吗?

绝大多数可以原封不动使用。 CCE 兼容标准的 Kubernetes API,Deployment、Service、Ingress、ConfigMap、Secret 等资源定义完全一致。需要调整的主要有两点:

  1. 存储类(StorageClass)名称:自建 K8s 用的存储类名(如 managed-nfs-storage)需要改为 CCE 的存储类名(如 csi-disk、csi-nas)
  2. Ingress 注解:如果使用 Nginx Ingress Controller,需改为 CCE 的 kubernetes.io/ingress.class: cce 注解

除此之外,应用层的 YAML 基本不用改动。

Q5:CCE 的运维成本比自建 K8s 高多少?

实际上更低。 这里算一笔账:

成本项 自建 K8s(3 Master + 10 Node) CCE(10 Node + 托管 Master)
Master 节点 ECS 费用 3 × ¥800 = ¥2,400/月 ¥0(托管免费)
Master 运维人力 约 0.5 人天/周(升级+巡检) ¥0(华为云负责)
故障恢复 SLA 自行保障 华为云 99.95%
网络/存储集成 手动配置 内置集成

结论:CCE 托管集群虽然有一定的集群管理费(通常几百元/月),但省去了 Master 节点的 ECS 费用和运维人力成本,综合成本更低。

CCE + 鲲鹏节点池部署信创应用完整流程

下图展示了从创建节点池到监控运维的全流程,涵盖资源准备、应用部署、弹性伸缩和日常运维四个阶段。

Mermaid 图表 2

流程说明:

  • 阶段一(资源准备):创建 CCE 集群 + 鲲鹏节点池,配置节点规格和亲和性标签,为后续调度打好基础
  • 阶段二(应用部署):核心是解决镜像架构兼容性(Buildx 多架构构建)和存储选型(EVS/SFS/OBS 按需选择)
  • 阶段三(弹性伸缩):HPA + Cluster Autoscaler 双层弹性,高峰期自动扩容、低谷期自动缩容
  • 阶段四(监控运维):AOM 监控 + 告警规则 + 日志查询 + WDR 报告,形成闭环运维体系

总结

CCE + 鲲鹏节点池是华为云信创容器化最推荐的方案。主要优势:

  1. Master 托管,不需要运维 K8s 控制面
  2. 鲲鹏节点一键创建,不用手动配置 ARM64 环境
  3. K8s 原生的方式部署应用,不需要学习新的编排方式

迁移过程比预想的顺利 —— 应用层的 YAML 文件一行不改,只需要加上 nodeSelector 保证调度到鲲鹏节点。

下篇文章讲在 CCE 上部署 openGauss 容器化主备集群。

你们用的是什么云上的容器服务?CCE 还是自建 K8s?评论区聊聊。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。