文档首页/ 云容器引擎 CCE/ 最佳实践/ 容器/ CCE中使用x86和ARM双架构镜像
更新时间:2026-05-21 GMT+08:00
分享

CCE中使用x86和ARM双架构镜像

华为云CCE支持x86与ARM节点混部在同一集群。但两种架构的指令集不兼容,导致x86镜像无法在ARM节点上运行,反之ARM镜像无法在x86节点上运行。如果镜像与节点架构不适配,就容易造成工作负载在拥有x86与ARM节点的集群中部署失败。

为解决这一问题,您可以构建x86和ARM双架构镜像,使用同一个镜像地址,Kubelet会根据节点架构自动拉取对应版本的镜像,实现一次配置,全架构运行。

工作原理

双架构镜像的核心原理是利用Docker的Manifest List功能,将一个逻辑镜像名(如defaultbackend:1.5)关联到多个物理镜像(如defaultbackend-linux-amd64:1.5、defaultbackend-linux-arm64:1.5)。这样在描述工作负载时,可以使用同一个镜像地址,且不用配置亲和性,工作负载描述文件更简洁更容易维护。当Pod调度到ARM架构节点时拉取ARM架构的镜像,当Pod调度到x86架构节点时拉取x86架构的镜像。

前提条件

  • 制作双架构镜像,Docker客户端版本需要大于18.03。
  • 已分别构建并测试通过对应x86和ARM架构的单体镜像。例如本示例中已经构建好了defaultbackend-linux-amd64:1.5和defaultbackend-linux-arm64:1.5两个镜像,分别是x86架构和ARM架构。
  • 已登录目标SWR镜像仓库,并有推送权限。

操作步骤

步骤一:开启Docker功能

  1. 登录已安装Docker的虚拟机。
  2. 开启Docker功能。

    # 临时开启(当前终端会话有效)
    export DOCKER_CLI_EXPERIMENTAL=enabled

  3. 验证是否开启成功。

    docker version --format '{{.Client.Experimental}}' 

    应输出true则表示开启成功。

步骤二:构建并上传x86与ARM单体镜像

本示例中已经构建好了defaultbackend-linux-amd64:1.5和defaultbackend-linux-arm64:1.5两个镜像,分别是x86架构和ARM架构。

将它们重命名(打标签) 并推送到SWR仓库,如下所示。上传镜像的具体方法请参见客户端上传镜像

# 定义变量,请替换为你的实际信息
REGISTRY="swr.cn-north-4.myhuaweicloud.com"  # 你的SWR仓库地址
NAMESPACE="test-namespace"                  # 你的SWR组织
IMAGE_NAME="defaultbackend"                 # 镜像名
VERSION="1.5"                               # 版本号

# ---- 处理 AMD64 (x86) 镜像 ----
# 给本地镜像打上SWR的完整标签
docker tag defaultbackend-linux-amd64:${VERSION} ${REGISTRY}/${NAMESPACE}/${IMAGE_NAME}-linux-amd64:${VERSION}
# 上传
docker push ${REGISTRY}/${NAMESPACE}/${IMAGE_NAME}-linux-amd64:${VERSION}

# ---- 处理 ARM64 镜像 ----
docker tag defaultbackend-linux-arm64:${VERSION} ${REGISTRY}/${NAMESPACE}/${IMAGE_NAME}-linux-arm64:${VERSION}
docker push ${REGISTRY}/${NAMESPACE}/${IMAGE_NAME}-linux-arm64:${VERSION}

步骤三:创建并推送Manifest列表

创建双架构Manifest列表并上传,将上面两个镜像关联到一个逻辑镜像名下。

  1. 创建Manifest列表。

    docker manifest create --amend --insecure \
        ${REGISTRY}/${NAMESPACE}/${IMAGE_NAME}:${VERSION} \
        ${REGISTRY}/${NAMESPACE}/${IMAGE_NAME}-linux-amd64:${VERSION} \
        ${REGISTRY}/${NAMESPACE}/${IMAGE_NAME}-linux-arm64:${VERSION}
    • --amend: 如果manifest存在则修改。
    • --insecure: 允许与HTTP仓库交互(通常SWR是HTTPS,但保留参数不报错)。

  2. 为Manifest列表中的每个镜像标注操作系统架构。

    docker manifest annotate ${REGISTRY}/${NAMESPACE}/${IMAGE_NAME}:${VERSION} \
        ${REGISTRY}/${NAMESPACE}/${IMAGE_NAME}-linux-amd64:${VERSION} --arch amd64
    
    docker manifest annotate ${REGISTRY}/${NAMESPACE}/${IMAGE_NAME}:${VERSION} \
        ${REGISTRY}/${NAMESPACE}/${IMAGE_NAME}-linux-arm64:${VERSION} --arch arm64

  3. 推送Manifest列表到SWR。

    docker manifest push -p --insecure ${REGISTRY}/${NAMESPACE}/${IMAGE_NAME}:${VERSION}
    • -p:推送列表本身,而不是镜像内容(内容已在上步推送)。

  4. 查看已创建的Manifest列表。

    docker manifest inspect ${REGISTRY}/${NAMESPACE}/${IMAGE_NAME}:${VERSION}

步骤四:在CCE中使用双架构镜像

完成上述操作后,在CCE中创建工作负载时可以直接使用同一个逻辑镜像地址:

  • 当Pod调度到x86架构的节点时,会拉取swr.cn-north-4.myhuaweicloud.com/test-namespace/defaultbackend-linux-amd64:1.5这个镜像。
  • 当Pod调度到ARM架构的节点时,会拉取swr.cn-north-4.myhuaweicloud.com/test-namespace/defaultbackend-linux-arm64:1.5这个镜像。
apiVersion: apps/v1
kind: Deployment
metadata:
  name: defaultbackend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: defaultbackend
  template:
    metadata:
      labels:
        app: defaultbackend
    spec:
      containers:
      # 直接使用双架构镜像地址
      - image: swr.cn-north-4.myhuaweicloud.com/test-namespace/defaultbackend:1.5
        name: nginx
      # 可无需配置 nodeSelector,Kubelet会自动选择正确架构的镜像,但如果需要控制Pod调度到特定架构节点,仍需配合亲和性
      # nodeSelector:      # 可选:若仍想强制调度到某类节点,可添加nodeSelector
      #   kubernetes.io/arch: arm64   # 强制调度到ARM节点
      imagePullSecrets:
      - name: default-secret

常见问题

使用双架构镜像后是否还需要配置节点亲和性?

不一定。您可以根据实际需求进行选择。

  • 无需配置:如果您的集群既有x86又有ARM节点,且不关心Pod具体跑在哪种架构上,仅需使用双架构镜像,无需任何亲和配置,调度器自动分配,Kubelet自动选镜像。
  • 仍需配置:如果您必须让某个工作负载跑在x86节点上(例如某些旧版二进制依赖),则仍需要配置节点亲和性,此时双架构镜像可保证应用在x86节点上能拉取到正确镜像。

如何验证镜像是否支持双架构?

您可以使用以下命令进行查询:
docker manifest inspect <镜像地址>

查看返回的manifests列表中是否包含platform.architecture为amd64和arm64的条目。

相关文档