应用现状
云容器引擎允许在同一集群内同时创建两种不同架构的节点:x86架构和ARM架构。然而,由于这两种架构在底层技术上存在显著差异,因此通常来说,无法将为ARM架构设计的镜像(即应用程序)在x86架构的节点上成功运行,反之亦然。因此,在拥有同时支持x86和ARM节点的集群上部署工作负载时,可能会遭遇部署失败的情况。
解决方案
解决在不同架构的节点使用镜像创建工作负载通常有三种方法:
- 创建工作负载的时候通过亲和性设置,使用ARM架构镜像时让Pod调度到ARM架构的节点上,使用x86架构镜像时让Pod调度到x86架构的节点上。
- 创建工作负载的时候通过nodeSelector设置,使用ARM架构镜像时让Pod调度到ARM架构的节点上,使用x86架构镜像时让Pod调度到x86架构的节点上。
- 构建双架构镜像,同时支持ARM和x86架构。当Pod被调度到ARM架构节点时,将自动拉取针对ARM架构的镜像;而当Pod被调度到x86架构节点时,将自动拉取针对x86架构的镜像。尽管使用同一个地址,但背后实际上包含两个镜像。这种设计简化了工作负载描述文件,使其更具可读性和易于维护,无需单独配置节点亲和性和nodeSelector。
亲和性配置说明
云容器引擎在创建节点时,会自动给节点打上kubenetes.io/arch的标签,表示节点架构,如下所示。
kubernetes.io/arch=amd64
取值amd64表示是x86架构,arm64表示是ARM架构。
在创建工作负载时,可以通过配置节点亲和性,将Pod调度到对应架构的节点上,示例如下:
apiVersion: v1
kind: Deployment
metadata:
name: test
spec:
selector:
matchLabels:
app: test
template:
metadata:
labels:
app: test
spec:
containers:
- name: container0
image: registry-crs-huadong1.ctyun.cn/library/nginx:1.5-amd64
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/arch
operator: In
values:
- amd64
nodeSelector配置说明
也可以使用nodeSelector实现相同的效果,示例如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: test
spec:
selector:
matchLabels:
app: test
template:
metadata:
labels:
app: test
spec:
nodeSelector:
kubernetes.io/arch: amd64
containers:
- name: container0
image: registry-crs-huadong1.ctyun.cn/library/nginx:1.5-amd64
resources:
limits:
cpu: 250m
memory: 512Mi
requests:
cpu: 250m
memory: 512Mi
imagePullSecrets:
- name: default-secret
使用双架构镜像
双架构镜像实际上就是对已有的两个不同架构的镜像做一个类似超链接的操作,能够实现在不同的操作系统拉取不同架构的镜像,构建上传步骤如下:
# 给原始镜像增加tag,方便标识具体区别
docker tag nginx:1.5-amd64 registry-crs-huadong1.ctyun.cn/library/nginx:1.5-amd64
docker tag nginx:1.5-arm64 registry-crs-huadong1.ctyun.cn/library/nginx:1.5-arm64
# 先上传镜像至容器镜像服务仓库,然后才能做manifest
docker push registry-crs-huadong1.ctyun.cn/library/nginx:1.5-amd64
docker push registry-crs-huadong1.ctyun.cn/library/nginx:1.5-arm64
创建双架构manifest文件并上传。
# 创建镜像manifest文件
docker manifest create --amend --insecure registry-crs-huadong1.ctyun.cn/library/nginx:1.5 registry-crs-huadong1.ctyun.cn/library/nginx:1.5-amd64 registry-crs-huadong1.ctyun.cn/library/nginx:1.5-arm64
# 如果镜像在之前制作中没有添加架构信息,需要给镜像manifest文件添加arch信息
docker manifest annotate registry-crs-huadong1.ctyun.cn/library/nginx:1.5 registry-crs-huadong1.ctyun.cn/library/nginx:1.5-amd64 --arch amd64
docker manifest annotate registry-crs-huadong1.ctyun.cn/library/nginx:1.5 registry-crs-huadong1.ctyun.cn/library/nginx:1.5-arm64 --arch arm64
# 向容器镜像服务仓库推送镜像manifest
docker manifest push -p --insecure registry-crs-huadong1.ctyun.cn/library/nginx:1.5
用户在使用时只需要image中填写registry-crs-huadong1.ctyun.cn/library/nginx:1.5这个镜像地址,
当Pod调度到 x86 架构的节点时,会拉取registry-crs-huadong1.ctyun.cn/library/nginx:1.5-amd64这个镜像;
当Pod调度到ARM架构的节点时,会拉取registry-crs-huadong1.ctyun.cn/library/nginx:1.5-arm64这个镜像。