Container Service for Kubernetes (ACK) allows you to manage the lifecycles of Elastic Compute Service (ECS) instances in Advanced RISC Machine (ARM)-based node pools. You can add, update, and remove ECS instances in ARM-based node pools. You can use Container Registry to deploy a multi-arch image across x86-based ECS instances and ARM-based ECS instances in a unified manner. Container Registry simplifies image deployment for basic components and applications in clusters that contain nodes based on different architectures. This topic describes how to create an ARM-based cluster and an ARM-based node pool. It also describes how to deploy an application on an ARM-based node.
Limits
The Kubernetes version of the cluster to which the ARM-based node pool belongs must be 1.20 or later.
ARM-based node pools support only Alibaba Cloud Linux 3.
The following components that are displayed on the Add-ons page in the ACK console support the ARM architecture:
Key components
Logging and monitoring components
Volume components
Network components
Components that are displayed on the Marketplace page in the ACK console do not support the ARM architecture.
Step 1: Create an ARM-based cluster and an ARM-based node pool
To use both the ARM and x86 architectures in an ACK cluster, we recommend that you add the
kubernetes.io/arch=arm64:NoSchedule
taint to ARM-based nodes in case applications or components that do not support the ARM architecture are accidentally scheduled to ARM-based nodes.When you configure nodeSelector or nodeAffinity to deploy applications on ARM-based nodes in an ACK cluster that runs Kubernetes 1.24 or later, the scheduler automatically tolerates the
kubernetes.io/arch=arm64:NoSchedule
taint. Therefore, you do not need to add a toleration to tolerate the taint.
Method 1: Add Arm-based nodes when you create a cluster
You can add ARM-based nodes when you create a cluster. This way, you can create a cluster that contains only ARM-based nodes.
For more information about how to create a cluster, see Create an ACK managed cluster. When you configure the node pool of the cluster, select Arm for Architecture in the Instance Type section. Then, select instance types that belong to the g8m general-purpose instance family. Set other parameters and create the cluster.
You can go to the ECS Instance Types Available for Each Region page to view instance types available in each region.
Method 2: Create an ARM-based node pool in an existing cluster
You can create an ARM-based node pool in an existing cluster.
For more information about how to create a node pool, see Procedure. When you create the node pool, select Arm for Architecture in the Instance Type section. Then, select instance types that belong to the g8m general-purpose instance family. Set other parameters and create the node pool.
You can go to the ECS Instance Types Available for Each Region page to view instance types available in each region.
Step 2: Deploy an application on an ARM-based node
To deploy an application on an ARM-based node, make sure that the application supports the ARM architecture. You can deploy the application by using a multi-arch image or an image that is built for the ARM architecture.
Schedule the application to an ARM-based node
If the application supports only the ARM architecture, and your cluster contains ARM-based nodes and nodes that are based on other architectures, make sure that the application is scheduled to an ARM-based node. The application fails to start up if it is scheduled to a node other than ARM-based nodes. By default, all ARM-based nodes have the kubernetes.io/arch=arm64
label. You can configure nodeSelector or nodeAffinity to deploy applications on ARM-based nodes.
Method 1: Configure nodeSelector to deploy applications on ARM-based nodes
You can add the following constraint to the Spec of a pod to schedule the pod to an ARM-based node:
nodeSelector:
kubernetes.io/arch: arm64 # The label that is used to select an ARM-based node.
After this constraint is added, the pod can be scheduled only to a node that has the kubernetes.io/arm=arm64
label.
When the Spec of a pod contains this constraint, the ACK scheduler automatically tolerates the kubernetes.io/arch=arm64:NoSchedule
taint when scheduling the pod.
The following example shows how to deploy an NGINX application on an ARM-based node:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
nodeSelector:
kubernetes.io/arch: arm64 # The label that is used to select an ARM-based node.
containers:
- name: nginx
image: nginx:1.14.2
Method 2: Configure nodeAffinity to deploy applications on ARM-based nodes
In addition to nodeSelector, you can configure nodeAffinity to deploy applications on ARM-based nodes. To do this, add the following constraint to the Spec of a pod:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/arch
operator: In
values:
- arm64
After this constraint is added, the pod can be scheduled only to a node that has the kubernetes.io/arm=arm64
label.
When the Spec of a pod contains this constraint, the ACK scheduler automatically tolerates the kubernetes.io/arch=arm64:NoSchedule
taint when scheduling the pod.
The following example shows how to deploy an NGINX application on an ARM-based node:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/arch
operator: In
values:
- arm64
containers:
- name: nginx
image: nginx:1.14.2
Use multi-arch images
A multi-arch image contains variants for multiple architectures, such as AMD64 and ARM. You can deploy a multi-arch image on an ARM-based node or an AMD64-based node. To push a multi-arch image, make sure that the client and the registry support multi-arch images. Container Registry supports multi-arch images.
The following example shows how to create and push a multi-arch NGINX image:
Build an image for AMD64 and an image for ARM. In this example, the images
registry.cn-hangzhou.aliyuncs.com/acs/myapp:amd64
andregistry.cn-hangzhou.aliyuncs.com/acs/myapp:arm
are created.Run the following command to build a multi-arch image:
docker manifest create registry.cn-hangzhou.aliyuncs.com/acs/myapp \ --amend registry.cn-hangzhou.aliyuncs.com/acs/myapp:amd64 \ --amend registry.cn-hangzhou.aliyuncs.com/acs/myapp:arm64
Run the
docker manifest push
command to push the multi-arch imageregistry.cn-hangzhou.aliyuncs.com/acs/myapp:latest
to Container Registry:docker manifest push registry.cn-hangzhou.aliyuncs.com/acs/myapp
After you have performed the preceding steps, you can pull this image from Container Registry and deploy pods based on this image.
Push an open source multi-arch image to Container Registry
Most open source software provides multi-arch images. To accelerate application deployment, you can push images to Container Registry and then pull the images from Container Registry. The following example shows how to push an nginx:1.23.2
image to Container Registry.
Run the following commands to pull an nginx:1.23.2 image for AMD64 and change the image tag to
nginx:1.23.2-amd64
:docker pull --platform linux/amd64 nginx:1.23.2 docker tag nginx:1.23.2 nginx:1.23.2-amd64
Run the following commands to pull an nginx:1.23.2 image for ARM and change the image tag to
nginx:1.23.2-arm64
:docker pull --platform linux/arm64 nginx:1.23.2 docker tag nginx:1.23.2 nginx:1.23.2-arm64
Run the following command to build a multi-arch image. Replace the repository address in the command with the address of your image repository:
docker manifest create registry.cn-hangzhou.aliyuncs.com/acs/nginx:1.23.2 \ # --amend nginx:1.23.2-arm64 \ --amend nginx:1.23.2-amd64
Run the following command to push the multi-arch image to Container Registry. Replace the repository address in the command with the address of your image repository:
docker manifest push registry.cn-hangzhou.aliyuncs.com/acs/nginx:1.23.2