ACK集群默认会将所有工作负载调度到x86架构的虚拟节点。如果您的集群中既有Arm虚拟节点,又有非Arm虚拟节点(例如x86虚拟节点),为了确保只兼容Arm架构的工作负载调度到Arm虚拟节点,或多架构镜像优先调度到Arm虚拟节点,您可以基于Kubernetes原生调度配置来实现。
前提条件
集群:
已创建ACK集群,且集群版本为v1.20及以上。具体操作,请参见创建Kubernetes托管版集群、手动升级集群。
说明Arm实例开放的地域及可用区是存在限制,请保证集群在已开放地域。查询Arm实例开放的地域及可用区,请参见ECS实例规格可购买地域总览。
组件:已安装ack-virtual-node组件,且组件版本为2.9.0及以上。详细信息,请参见ACK Virtual Node。
注意事项
如果您的集群版本为v1.24之前,在使用nodeSelector
或者nodeAffinity
指定应用调度至Arm节点时,您需要同时声明污点容忍kubernetes.io/arch=arm64:NoSchedule
的tolerations
。如果您的集群版本为v1.24版本及之后,调度器能够自动识别Arm节点的污点kubernetes.io/arch=arm64:NoSchedule
,无需您额外声明tolerations
。
相关计费
创建的Arm架构类型的ECI Pod,按照实际生成的ECS规格进行计费,不按照vCPU和内存计费。
ECI Pod创建成功后,您可以执行kubectl describe pod
命令查看其YAML详情。通过k8s.aliyun.com/eci-instance-spec
字段确认ECI Pod实际使用的ECS规格,ECI会按照该ECS规格进行计费。
关于Arm架构的ECS规格的详细信息,请参见:
步骤一:添加Arm架构的虚拟节点
在集群中部署Arm工作负载之前,需要先创建Arm架构的虚拟节点(Virtual Node)。您可以通过配置ECI Profile创建支持Arm架构类型的虚拟节点。您可以通过以下两种方式编辑eci-profile
配置文件。关于ECI Profile的详细信息,请参见配置eci-profile。
通过容器服务管理控制台
登录容器服务管理控制台,在左侧导航栏选择集群。
在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择 。
选择命名空间为kube-system,找到eci-profile单击编辑,将键值
enableLinuxArm64Node
修改为true
。然后单击确定。说明如果集群已有vSwitch的所处可用区均未支持Arm实例,您需要先创建指定可用区的vSwitch。创建成功后,将vSwitch的ID添加进
vSwitchIds
中。关于创建指定可用区的vSwitch,请参见创建和管理交换机。修改完成后,等待大概30s,您可以在节点页面查看创建的名为
virtual-kubelet-<zoneId>-linux-arm64
的虚拟节点。
通过kubectl edit命令
前提条件
获取集群KubeConfig并通过kubectl工具连接集群。
操作步骤
执行如下命令,编辑ConfigMap。
kubectl edit configmap eci-profile -n kube-system
添加或修改参数
enableLinuxArm64Node
为true
。设置
vSwitchIds
,确保当前集群使用的vSwitchIds
中,至少有一个支持Arm实例的可用区的vSwitch。说明如果集群已有vSwitch的所处可用区均未支持Arm实例,您需要先创建指定可用区的vSwitch。创建成功后,将vSwitch的ID添加进
vSwitchIds
中。关于创建指定可用区的vSwitch,请参见创建和管理交换机。修改完成后,等待大概30s,您可以在节点页面查看创建的名为
virtual-kubelet-<zoneId>-linux-arm64
的虚拟节点。
步骤二:指定工作负载调度到Arm虚拟节点
指定Arm架构的工作负载调度到Arm虚拟节点
如果您的集群中既有Arm节点也有非Arm节点,且您的应用只支持Arm架构,您可以指定应用运行在Arm节点上,以免应用Pod被调度到非Arm节点上导致启动失败。所有Arm节点上默认带有Labelkubernetes.io/arch=arm64
,您可以通过两种方式nodeSelector和nodeAffinity指定应用部署到Arm节点上。
使用nodeSelector
您可以在Pod上增加如下约束,使用nodeSelector将Pod调度到Arm架构的virtual-node上。nodeSelector将指定此工作负载仅调度到具有arm64
标签的节点,ACK集群中的Arm架构的virtual-node都具有此标签。
nodeSelector:
kubernetes.io/arch: arm64 # 指定Arm节点。
您可以使用以下示例代码将一个无状态应用部署到Arm虚拟节点。
使用nodeAffinity
前提条件
已开启集群虚拟节点调度策略,且集群版本、组件版本符合要求。
操作示例
您可以在Pod上增加如下约束,使用节点亲和性声明指定应用部署到Arm节点上。此约束指定Pod只能被调度到带有Label kubernetes.io/arm=arm64
的节点上。
当Pod Spec上带有此约束时,调度器自动容忍节点上的污点kubernetes.io/arch=arm64:NoSchedule
。
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/arch
operator: In
values:
- arm64
您可以使用以下示例代码将一个无状态应用部署到Arm虚拟节点。
指定多架构镜像调度到Arm虚拟节点
前提条件
已开启集群虚拟节点调度策略,且集群版本、组件版本符合要求。
操作示例
ACK集群默认会将所有工作负载调度到x86架构的虚拟节点,并在x86节点资源不足时保持等待x86节点资源。如果您的应用镜像为多架构镜像,例如同时支持x86和Arm架构,您需要配置跨x86和Arm架构的节点调度。
例如,您可以通过配置节点亲和性,使工作负载优先调度到Arm架构或x86架构的虚拟节点上,并在目标类型的虚拟节点资源不足时尝试调度至其他架构类型的虚拟节点。
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: kubernetes.io/arch
operator: In
values:
- arm64
将工作负载优先调度到Arm架构上
声明优先将工作负载调度到Arm虚拟节点的示例如下。
将工作负载优先调度到x86架构上
声明优先将工作负载调度到x86虚拟节点的示例如下。
常见问题
为什么配置nodeAffinity优先将Pod调度到Arm架构的节点,却调度到x86架构的ECS节点上?
集群调度器默认优先调度到ECS节点,ECS节点资源不足时调度到虚拟节点。在不修改调度器计分插件权重的情况下,如集群中存在资源充足的x86 ECS节点,即使通过nodeAffinity配置了优先调度到Arm架构的节点,Pod也可能会被调度到x86架构的ECS节点上。因此,通过本文中的nodeAffinity配置,只能保证不同架构(Arm/x86)虚拟节点的优先级,而无法保证虚拟节点和ECS节点的优先级。
是否可以使用Arm架构类型的竞价(Spot)实例?
目前已经提供Arm架构的竞价实例。使用方式,请参见使用抢占式实例。
在相应区域创建集群后,如何配置网络来创建出支持Arm可用区的虚拟节点?
在相应可用区创建ACK集群后,通过配置eci-profile中vSwitchIds
字段,选择支持Arm实例的可用区的虚拟交换机,从而保证创建出支持Arm架构的虚拟节点。
在ACK集群中使用Arm架构节点的限制?
目前,Arm架构不支持应用市场的组件;组件中心仅支持以下模块的组件:
核心组件
日志和监控
存储
网络
相关文档
您可以使用阿里云容器镜像服务企业版(ACR EE)构建多架构容器镜像。具体操作,请参见构建多架构容器镜像。
如果您需要创建并管理普通的Arm ECS节点,请参见配置Arm节点池。
如果您有大数据任务需求且不想关心底层集群资源的运维工作,您可以使用Arm虚拟节点运行Spark作业。