ACK Serverless集群默認會將所有工作負載調度到x86架構的虛擬節點。如果您的集群中既有Arm虛擬節點,又有非Arm虛擬節點(例如x86虛擬節點),為了確保只兼容Arm架構的工作負載調度到Arm虛擬節點,或多架構鏡像優先調度到Arm虛擬節點,您可以基于Kubernetes原生調度配置來實現。
前提條件
集群:
已創建ACK Serverless集群,且集群版本為1.20及以上,請參見創建集群、手動升級集群。
說明Arm實例開放的地域及可用區是存在限制,請保證集群在已開放地域。查詢Arm實例開放的地域及可用區,請參見ECS實例規格可購買地域總覽。
組件:已安裝ack-virtual-node組件,且組件版本為2.9.0及以上。詳細信息,請參見ACK Virtual Node。
注意事項
如果您的集群版本為1.24之前,在使用nodeSelector
或者nodeAffinity
指定應用調度至Arm節點時,您需要同時聲明污點容忍kubernetes.io/arch=arm64:NoSchedule
的tolerations
。如果您的集群版本為1.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。
控制臺
kubectl
前提條件
獲取集群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 Serverless集群中的Arm架構的virtual-node都具有此標簽。
nodeSelector:
kubernetes.io/arch: arm64 # 指定Arm節點。
您可以使用以下示例代碼將一個無狀態應用部署到Arm虛擬節點。
下方YAML中添加了對kubernetes.io/arch=arm64:NoSchedule
的容忍。如果您的集群為1.24及以上版本的ACK集群Pro版,ACK調度器會自動識別此污點,無需您額外聲明容忍。
apiVersion: apps/v1
kind: Deployment
metadata:
name: only-arm
spec:
selector:
matchLabels:
app: nginx
replicas: 1
template:
metadata:
labels:
app: nginx
spec:
nodeSelector:
kubernetes.io/arch: arm64 # 指定Arm節點。
tolerations:
# 容忍虛擬節點的Taint。
- key: virtual-kubelet.io/provider
operator: Exists
effect: NoSchedule
# 容忍Arm架構的虛擬節點上的Taint。
- key: kubernetes.io/arch
operator: Equal
value: arm64
effect: NoSchedule
containers:
- name: nginx
image: alibaba-cloud-linux-3-registry.cn-hangzhou.cr.aliyuncs.com/alinux3/nginx_optimized:20240221-1.20.1-2.3.0
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虛擬節點。
下方YAML中添加了對kubernetes.io/arch=arm64:NoSchedule
的容忍。如果您的集群為1.24及以上版本的ACK集群Pro版,ACK調度器會自動識別此污點,無需您額外聲明容忍。
apiVersion: apps/v1
kind: Deployment
metadata:
name: only-arm
spec:
selector:
matchLabels:
app: nginx
replicas: 1
template:
metadata:
labels:
app: nginx
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/arch
operator: In
values:
- arm64
tolerations:
# 容忍虛擬節點的Taint。
- key: virtual-kubelet.io/provider
operator: Exists
effect: NoSchedule
# 容忍Arm架構的虛擬節點上的Taint。
- key: kubernetes.io/arch
operator: Equal
value: arm64
effect: NoSchedule
containers:
- name: nginx
image: nginx
指定多架構鏡像調度到Arm虛擬節點
前提條件
已開啟集群虛擬節點調度策略,且集群版本、組件版本符合要求。
操作示例
ACK Serverless集群默認會將所有工作負載調度到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虛擬節點的示例如下。
下方YAML中添加了對kubernetes.io/arch=arm64:NoSchedule
的容忍。如果您的集群為1.24及以上版本的ACK集群Pro版,ACK調度器會自動識別此污點,無需您額外聲明容忍。
apiVersion: apps/v1
kind: Deployment
metadata:
name: arm-prefer
spec:
replicas: 1
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
tolerations:
# 容忍虛擬節點的Taint。
- key: virtual-kubelet.io/provider
operator: Exists
effect: NoSchedule
# 容忍Arm架構的虛擬節點上的Taint。
- key: kubernetes.io/arch
operator: Equal
value: arm64
effect: NoSchedule
# 優先調度到Arm架構的節點上。
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: kubernetes.io/arch
operator: In
values:
- arm64
containers:
- name: my-container
image: nginx
優先調度到x86架構
聲明優先將工作負載調度到x86虛擬節點的示例如下。
下方YAML中添加了對kubernetes.io/arch=arm64:NoSchedule
的容忍。如果您的集群為1.24及以上版本的ACK集群Pro版,ACK調度器會自動識別此污點,無需您額外聲明容忍。
apiVersion: apps/v1
kind: Deployment
metadata:
name: amd-prefer
spec:
replicas: 1
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
tolerations:
# 容忍虛擬節點的Taint。
- key: virtual-kubelet.io/provider
operator: Exists
effect: NoSchedule
# 容忍Arm架構的虛擬節點上的Taint。
- key: kubernetes.io/arch
operator: Equal
value: arm64
effect: NoSchedule
# 優先調度到x86架構的節點上。
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: kubernetes.io/arch
operator: In
values:
- amd64
containers:
- name: my-container
image: nginx
常見問題
為什么配置nodeAffinity優先將Pod調度到Arm架構的節點,卻調度到x86架構的ECS節點上?
集群調度器默認優先調度到ECS節點,ECS節點資源不足時調度到虛擬節點。在不修改調度器計分插件權重的情況下,如集群中存在資源充足的x86 ECS節點,即使通過nodeAffinity配置了優先調度到Arm架構的節點,Pod也可能會被調度到x86架構的ECS節點上。因此,通過本文中的nodeAffinity配置,只能保證不同架構(Arm/x86)虛擬節點的優先級,而無法保證虛擬節點和ECS節點的優先級。
是否可以使用Arm架構類型的競價(Spot)實例?
目前已經提供Arm架構的競價實例。使用方式,請參見使用搶占式實例。
在相應區域創建集群后,如何配置網絡來創建出支持Arm可用區的虛擬節點?
在相應可用區創建ACK Serverless集群后,通過配置eci-profile中vSwitchIds
字段,選擇支持Arm實例的可用區的虛擬交換機,從而保證創建出支持Arm架構的虛擬節點。
在ACK Serverless集群中使用Arm架構節點的限制?
目前,Arm架構不支持應用市場的組件;組件中心僅支持以下模塊的組件:
核心組件
日志和監控
存儲
網絡
相關文檔
您可以使用阿里云容器鏡像服務企業版(ACR EE)構建多架構容器鏡像。具體操作,請參見構建多架構容器鏡像。
如果您需要創建并管理普通的Arm ECS節點,請參見配置Arm節點池。
如果您有大數據任務需求且不想關心底層集群資源的運維工作,您可以使用Arm虛擬節點運行Spark作業。