华为云 CCE 实战:从镜像构建到 HPA 弹性伸缩的完整落地路径

举报
yd_265411139 发表于 2026/10/31 10:24:13 2026/10/31
【摘要】 在华为云 CCE 上把弹性能力真正做成闭环:从 SWR 镜像推送、节点池容量规划,到 Deployment 探针、HPA v2 策略与压测验证,附完整 YAML 与排障顺序。

本文基于 Kubernetes 1.27 与华为云 CCE v1.27 集群验证,示例代码可直接复用。

一、为什么要把"弹性"做成一条闭环

很多团队在 CCE 上跑得好好的,直到大促或突发流量来袭,才发现弹性能力是"半成品":镜像推送靠人手,Deployment 靠复制粘贴,HPA 配了但从不生效,压测报告和扩容曲线对不上。

问题往往不在 Kubernetes 本身,而在于从镜像到副本数的链路没有被串起来。本文按一条完整链路走一遍:

  1. 本地构建镜像并推送到 SWR(容器镜像服务)
  2. 在 CCE 创建集群与节点池
  3. 用 Deployment + Service 跑通最小可用服务
  4. 配置基于 CPU 利用率的 HPA
  5. 用压测验证扩缩容是否真的发生

二、前置准备

资源 说明
CCE 集群 v1.27 及以上,开启 metrics-server 插件
SWR 组织 用于存放私有镜像
节点池 建议至少 2 个节点,避免单点
kubectl 与集群版本偏差不超过一个小版本

在 CCE 控制台"集群信息 → 连接信息"下载 kubeconfig,替换本地 ~/.kube/config 后验证:

kubectl cluster-info
kubectl get nodes -o wide

节点状态为 Ready 即可继续。

三、第一步:构建镜像并推送到 SWR

先登录 SWR。华为云各区域的镜像仓库地址格式固定:

docker login -u cn-north-4@AK -p <登录密钥> swr.cn-north-4.myhuaweicloud.com

登录密钥在 SWR 控制台"我的镜像 → 登录指令"中获取,有效期通常为 24 小时,不要写进脚本提交到仓库。

准备一个最小服务。这里用 Go 写一个带 /healthz 的 HTTP 服务,便于后续压测:

package main

import (
    "net/http"
    "os"
)

func main() {
    port := os.Getenv("PORT")
    if port == "" {
        port = "8080"
    }
    http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
        w.WriteHeader(http.StatusOK)
        w.Write([]byte("ok"))
    })
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("hello from cce"))
    })
    http.ListenAndServe(":"+port, nil)
}

Dockerfile 使用多阶段构建,把镜像压到最小:

FROM golang:1.22-alpine AS builder
WORKDIR /src
COPY . .
RUN CGO_ENABLED=0 go build -o /out/app .

FROM alpine:3.19
RUN adduser -D -u 10001 appuser
COPY --from=builder /out/app /app
USER appuser
EXPOSE 8080
ENTRYPOINT ["/app"]

构建并推送:

export REGISTRY=swr.cn-north-4.myhuaweicloud.com
export ORG=my-demo-org

docker build -t $REGISTRY/$ORG/demo-api:v1 .
docker push $REGISTRY/$ORG/demo-api:v1

推送完成后在 SWR 控制台确认镜像已出现,记录完整地址,下一步要用。

四、第二步:创建集群与节点池

控制台创建集群时,有三个参数值得特别注意:

  • 容器网络模型:新建集群建议选云原生网络 2.0,Pod 密度和性能更好。
  • 节点池规格:HPA 扩容的实际落点是节点池,节点池容量不足时 Pod 会一直 Pending。
  • 节点池弹性:开启后节点数量可随 Pod 需求自动增减,避免"Pod 扩容成功但调度不上"。

节点池数量建议为 HPA 最大副本数预留余量。若单节点可调度 30 个 Pod,HPA 最大 10 副本,2 个节点即可留出滚动升级空间。

五、第三步:跑通最小可用服务

创建 demo-api.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-api
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: demo-api
  template:
    metadata:
      labels:
        app: demo-api
    spec:
      containers:
        - name: demo-api
          image: swr.cn-north-4.myhuaweicloud.com/my-demo-org/demo-api:v1
          ports:
            - containerPort: 8080
          resources:
            requests:
              cpu: 200m
              memory: 128Mi
            limits:
              cpu: 500m
              memory: 256Mi
          readinessProbe:
            httpGet:
              path: /healthz
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 5
          livenessProbe:
            httpGet:
              path: /healthz
              port: 8080
            initialDelaySeconds: 15
            periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
  name: demo-api
  namespace: default
spec:
  selector:
    app: demo-api
  ports:
    - port: 80
      targetPort: 8080
  type: ClusterIP
kubectl apply -f demo-api.yaml
kubectl get pods -l app=demo-api -w

两个副本都 Running 且 READY 1/1 后,再验证服务连通性:

kubectl run curl-test --rm -it --image=curlimages/curl -- \
  curl -s http://demo-api.default.svc.cluster.local/healthz

六、第四步:配置 HPA

6.1 确认指标管道可用

HPA 读不到指标是最常见的失败原因。先确认 metrics-server 正常:

kubectl top pods

如果报 error: Metrics API not available,到 CCE 插件中心安装或升级 metrics-server,等待约 1 分钟后再试。

注意:kubectl top 返回空值说明 Pod 刚启动、指标尚未采样,不代表插件故障,稍等再看。

6.2 编写 HPA

使用 autoscaling/v2,可以同时约束行为策略:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: demo-api-hpa
  namespace: default
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: demo-api
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 60
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 0
      policies:
        - type: Percent
          value: 100
          periodSeconds: 60
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
        - type: Pods
          value: 2
          periodSeconds: 60

几个关键点:

  • 目标利用率是相对 requests 计算的。request 200m、目标 60%,意味着单 Pod 平均 CPU 超过 120m 就触发扩容。request 设得过大,HPA 永远不会动。
  • 扩容快、缩容慢。scaleUp 窗口设为 0 让流量突发时快速响应,scaleDown 保留 300 秒稳定窗口,避免抖动。
  • 不要同时用 HPA 和固定 replicas 管理同一个 Deployment,会出现反复改写副本数的情况。
kubectl apply -f demo-api-hpa.yaml
kubectl get hpa demo-api-hpa -w

七、第五步:压测验证弹性

用一个临时压测 Pod 打流量:

kubectl run loadgen --rm -it --image=busybox -- \
  sh -c "while true; do wget -q -O- http://demo-api.default.svc.cluster.local/ > /dev/null; done"

如果压测 Pod 被 HPA 统计进指标(默认不会,因为它不属于目标 Deployment),观察 TARGETS 一列即可:

kubectl get hpa demo-api-hpa
kubectl describe hpa demo-api-hpa | tail -20

预期行为:

  1. TARGETS 从 0%/60% 逐步升高并越过 60%
  2. Deployment 副本数从 2 增至更多,受 maxReplicas: 10 约束
  3. 压测停止后,约 5 分钟内副本数回落到 2

如果副本数一直不动,按这个顺序排查:

kubectl top pods -l app=demo-api        # 指标是否存在
kubectl describe hpa demo-api-hpa       # Events 里会写明具体原因
kubectl get pods -o wide                # 是否因节点资源不足 Pending
kubectl get nodes                       # 节点是否已满

describe hpa 的 Events 是最有价值的信息来源,常见的 failed to get cpu utilization、missing request for cpu 都能直接指向根因。

八、容易踩的坑

1. 没有设置 resources.requests。 HPA 按 request 计算利用率,缺省时无法计算,事件里会提示 missing request for cpu。requests 必须写。

2. 只扩 Pod 不扩节点。 HPA 最大 10 副本、单节点只能放 4 个 Pod 时,多出来的 Pod 会 Pending。要么开启节点池弹性,要么按峰值预留节点容量。

3. readinessProbe 配得太激进。 扩容出来的新 Pod 还没就绪就被打流量,会放大超时。initialDelaySeconds 与 periodSeconds 要按实际启动时间给足。

4. 镜像地址带 tag 但用了 latest。 滚动升级时 latest 不会触发重新拉取(取决于 imagePullPolicy),线上很容易"改了代码没生效"。生产环境坚持用不可变 tag 或 digest。

5. 缩容把长连接打断。 缩容前优雅退出需要应用处理 SIGTERM 并在 terminationGracePeriodSeconds 内完成。HTTP 服务至少要停止接收新请求、等待存量请求结束。

九、小结

把上面这条链路拆开看,每一环都不复杂,真正的难点是让它们互相成立:requests 设置决定 HPA 是否有效,节点池容量决定扩容是否落地,探针配置决定扩容后是否真能承接流量。

建议按这个顺序固化下来:

  1. 镜像用不可变 tag 推送 SWR
  2. Deployment 必须带 requests/limits 与两类探针
  3. HPA 用 autoscaling/v2,显式声明 behavior
  4. 每次变更后用一次压测确认弹性曲线

这样"弹性伸缩"才不是一个配置项,而是一条可以被验证的能力。


以上示例集群与镜像均为演示用途,实际部署请结合业务压测数据调整 requests 与 HPA 阈值。

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

评论(0)

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

全部回复

上滑加载中

设置昵称

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

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

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