从 Docker Compose 迁到华为云 CCE:一次真实迁移记录

举报
yd_271063030 发表于 2026/11/07 21:07:07 2026/11/07
【摘要】 项目原本跑在一台 4C8G 的 ECS 上,用 docker compose 编排五个服务。用户涨上来之后单机扛不住,迁到了 CCE(云容器引擎)。这篇记录迁移过程里真正花时间的部分。 为什么迁 单机

项目原本跑在一台 4C8G 的 ECS 上,用 docker compose 编排五个服务。用户涨上来之后单机扛不住,迁到了 CCE(云容器引擎)。这篇记录迁移过程里真正花时间的部分。

为什么迁

单机 compose 的问题:

  • 无法水平扩容,CPU 打满只能升配
  • 单点故障,机器挂了全站不可用
  • 滚动更新要手动停服务,有 downtime
  • 配置散落在 docker-compose.yml 里,多环境要复制多份

CCE 是托管的 Kubernetes,能解决上面这些,代价是复杂度和成本上升。

迁移前的准备

第一步:把所有配置外置

compose 里的 environment 全部抽到 ConfigMap,敏感信息(数据库密码、API key)抽到 Secret。

原先是:

environment:
  - DB_HOST=127.0.0.1
  - DB_PASSWORD=xxx

迁移后 ConfigMap 存非敏感项,Secret 存密码。

第二步:确认镜像能推送到 SWR

CCE 拉镜像从华为云容器镜像服务(SWR)最快。要先建组织、建命名空间,然后:

docker tag myapp:v1 swr.cn-north-4.myhuaweicloud.com/myorg/myapp:v1
docker login -u cn-north-4@XXXX -p **** swr.cn-north-4.myhuaweicloud.com
docker push swr.cn-north-4.myhuaweicloud.com/myorg/myapp:v1

登录用户名不是账号名,是「区域@AK」这种格式,在 SWR 控制台的「客户端上传」里能看到准确的命令。

第三步:梳理服务依赖

compose 里靠 depends_on 保证启动顺序。K8s 没有这个机制,需要用 readinessProbe + initContainer 或者应用自己重试。

我们做法是:所有服务启动时对数据库连接做重试(最多 30 次,间隔 2 秒),不依赖启动顺序。

关键配置怎么写

Deployment 最小可用版本:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-server
spec:
  replicas: 2
  selector:
    matchLabels:
      app: api-server
  template:
    metadata:
      labels:
        app: api-server
    spec:
      containers:
      - name: api
        image: swr.cn-north-4.myhuaweicloud.com/myorg/api:v1
        ports:
        - containerPort: 8080
        envFrom:
        - configMapRef:
            name: app-config
        - secretRef:
            name: app-secret
        resources:
          requests:
            cpu: 200m
            memory: 256Mi
          limits:
            cpu: 1000m
            memory: 512Mi
        livenessProbe:
          httpGet:
            path: /healthz
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ready
            port: 8080
          initialDelaySeconds: 10
          periodSeconds: 5

resources 必须写。不写的话调度器无法合理分配,节点容易 OOM。

两个 probe 的区别:

  • livenessProbe 失败 → 重启容器
  • readinessProbe 失败 → 从 Service 摘掉,不接流量

健康检查接口要分开:/healthz 只检查进程活着,/ready 检查依赖(数据库、缓存)是否可用。如果把依赖检查放进 liveness,数据库抖一下会导致所有 Pod 重启,雪崩。

Service 暴露:

apiVersion: v1
kind: Service
metadata:
  name: api-server
spec:
  selector:
    app: api-server
  ports:
  - port: 80
    targetPort: 8080
  type: ClusterIP

集群内访问用 ClusterIP,对外暴露用 Ingress 或 LoadBalancer。生产建议 Ingress + ELB,一个 ELB 带多个域名。

Ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: main-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-server
            port:
              number: 80

踩过的坑

坑一:镜像拉取失败

报 ImagePullBackOff。原因通常是:

  • SWR 的组织/命名空间不对
  • 没配 imagePullSecrets
  • 镜像 tag 写错

CCE 节点如果和 SWR 同区域,内网拉取免密。跨区域要配 secret。

坑二:Pod 一直 Pending

看 kubectl describe pod 的 Events。常见原因:

  • 资源不足(节点剩余 CPU/内存不够 requests)
  • 节点亲和性规则不满足
  • PVC 挂载失败

坑三:时区不对

容器默认 UTC,日志时间差 8 小时。解决:

env:
- name: TZ
  value: Asia/Shanghai

或者挂载宿主机的 /etc/localtime。

坑四:日志看不到

kubectl logs 只能看 stdout/stderr。应用如果写文件,要挂载 emptyDir 或者接日志服务(LTS)。

坑五:滚动更新时 502

默认滚动更新是「先起新的再停旧的」,但如果 readinessProbe 配得太宽松,新 Pod 还没真正就绪就接流量,会报错。

解决:readinessProbe 的 initialDelaySeconds 给够,failureThreshold 设小一点(比如 2),让不健康的 Pod 快速摘除。

成本控制

CCE 的费用分三块:集群管理费(按集群收)、节点费用(ECS)、ELB/带宽。

省钱要点:

  1. 节点池用弹性伸缩。低峰缩到最小节点数,高峰自动扩。
  2. 按需 + 抢占式混合。无状态服务可以用抢占式实例,成本低很多,但会被回收,要能容忍。
  3. 集群管理费按规模阶梯。小集群(50 节点以下)费用固定,大集群反而单位成本低。

我们目前是 3 节点固定 + 弹性伸缩到 6,月成本比原来单台高配 ECS 贵约 40%,但可用性和扩容能力提升明显。

值不值得迁

适合迁:

  • 服务多、需要独立扩缩容
  • 要求零停机发布
  • 团队有 K8s 经验或者愿意投入学习

不适合迁:

  • 单服务、流量稳定
  • 团队没人懂 K8s
  • 预算敏感

五个服务以下的单体应用,用两台 ECS + 负载均衡 + 手动滚动更新,成本低得多,故障率也未必更高。容器编排的收益在规模上来之后才明显。

小结

迁移本身不难,难的是「把 compose 的隐式依赖显式化」——启动顺序、配置注入、健康检查、日志收集,这些在单机上靠约定,在 K8s 里必须写进配置。

最值得花时间的是两个 probe 的设计。配好了滚动更新无感,配坏了频繁重启或者流量打到没准备好的实例上。

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

评论(0)

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

全部回复

上滑加载中

设置昵称

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

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

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