All Products
Search
Document Center

Container Service for Kubernetes:Configure an ARM-based node pool

Last Updated:May 31, 2023

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

Important
  • 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.

Note

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.

Note

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:

  1. Build an image for AMD64 and an image for ARM. In this example, the images registry.cn-hangzhou.aliyuncs.com/acs/myapp:amd64 and registry.cn-hangzhou.aliyuncs.com/acs/myapp:arm are created.

  2. 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
  3. Run the docker manifest push command to push the multi-arch image registry.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.

  1. 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
  2. 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
  3. 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
  4. 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

References

ARM-based ECS instance families