
# 将工作负载调度至ARM节点
在CCE集群中，可能同时包含ARM和x86节点，为了确保仅兼容ARM的应用被正确调度，或双架构镜像优先使用ARM节点，您可以通过Kubernetes原生调度特性实现，本文为您提供从"强制调度"到"优先调度"的完整方案。
本文提供三种调度配置，您可以按需选择。
| 场景                   | 调度意图                                     | 推荐配置                                 |
|:---|:---|:---|
| 场景一：纯ARM应用           | **强制调度**到ARM节点，不能调度到x86节点。               | nodeSelector或required类型的nodeAffinity |
| 场景二：双架构应用，优先调度至ARM节点 | **优先调度**到ARM节点，ARM节点资源不足时可调度到x86节点。      | preferred类型的nodeAffinity             |
| 场景三：双架构应用，强制调度至ARM节点 | **必须调度**到ARM节点；若无可用的ARM节点，Pod应保持Pending。 | required类型的nodeAffinity              |
   
#### 创建ARM节点池
1. 登录[CCE控制台](https://console.huaweicloud.com/cce2.0/?#/cce/cluster/list)。
2. 单击集群名称进入集群，在左侧选择"节点管理"，在右侧选择"节点池"页签。
3. 单击右上角"创建节点池"，在**节点配置** 中选择鲲鹏类型的规格，如鲲鹏通用计算增强型。
   
   ![](https://support.huaweicloud.com/bestpractice-cce/public_sys-resources/note_3.0-zh-cn.png)
   鲲鹏实例当前在部分地域及可用区开放，请以控制台实际为准。
   ![](https://support.huaweicloud.com/bestpractice-cce/zh-cn_image_0000002576189054.png "点击放大")
   
   
   
4. 其余配置可根据实际情况填写，完成节点池的创建。关于节点池配置的详细参数说明，请参见[创建节点池](https://support.huaweicloud.com/usermanual-cce/cce_10_0012.html)。
5. 节点池创建完成后，单击节点池名称后的"扩缩容"。
6. 在弹出的"节点池扩缩容"窗口中，填写本次扩容的节点数，例如2。
7. 单击"确定"，等待节点创建完成。
 
#### 工作负载调度至ARM节点
#### 场景一：纯ARM应用
Pod只能运行在ARM节点上，您可以使用nodeSelector或required类型的nodeAffinity调度。
- 方法1：使用nodeSelector 配置示例如下：
  ```
  apiVersion: apps/v1
  kind: Deployment
  metadata:
    name: test
  spec:
    replicas: 1
    selector:
      matchLabels:
        app: test
    template:
      metadata:
        labels:
          app: test
      spec:
        containers:
        - name: test
          image: <your-arm64-only-image:latest>  # 替换为实际镜像地址
        nodeSelector: 
          kubernetes.io/arch: arm64   # 强制调度到ARM节点
        imagePullSecrets:
        - name: default-secret
  ```
  
- 方法2：使用required类型的nodeAffinity 配置示例如下：
  ```
  apiVersion: apps/v1
  kind: Deployment
  metadata:
    name: test
  spec:
    replicas: 1
    selector:
      matchLabels:
        app: test
    template:
      metadata:
        labels:
          app: test
      spec:
        containers:
        - name: test
          image: <your-arm64-only-image:latest>  # 替换为实际镜像地址
        affinity:
          nodeAffinity:
            requiredDuringSchedulingIgnoredDuringExecution:  # 硬约束
              nodeSelectorTerms:
              - matchExpressions:
                - key: kubernetes.io/arch
                  operator: In
                  values:
                  - arm64   # 强制调度到ARM节点
        imagePullSecrets:
        - name: default-secret
  ```
  
 
#### 场景二：双架构应用，优先调度至ARM节点
首选ARM节点，但当ARM节点资源不足时，可允许调度到x86节点以保证业务运行。这是多数双架构应用的最佳实践。
配置示例如下：
```
apiVersion: apps/v1
kind: Deployment
metadata:
  name: test
spec:
  replicas: 1
  selector:
    matchLabels:
      app: test
  template:
    metadata:
      labels:
        app: test
    spec:
      affinity:
        nodeAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:  # 软约束
          - weight: 100                    # 权重越高，优先级越高
            preference:
              matchExpressions:
              - key: kubernetes.io/arch
                operator: In
                values:
                - arm64
      containers:
      - name: test
        image: <your-multi-arch-image:latest>   # 替换为实际镜像地址，镜像需同时支持amd64/arm64
      imagePullSecrets:
      - name: default-secret
```
#### 场景三：双架构应用，强制调度至ARM节点
Pod必须运行在ARM节点上，如果集群中没有可用ARM节点，Pod不调度（保持Pending状态）。
配置示例如下：
```
apiVersion: apps/v1
kind: Deployment
metadata:
  name: test
spec:
  replicas: 1
  selector:
    matchLabels:
      app: test
  template:
    metadata:
      labels:
        app: test
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:  # 硬约束
            nodeSelectorTerms:
            - matchExpressions:
              - key: kubernetes.io/arch
                operator: In
                values:
                - arm64
      containers:
      - name: test
        image: <your-multi-arch-image:latest>   # 替换为实际镜像地址
      imagePullSecrets:
      - name: default-secret
```
该配置与场景一中纯ARM应用的强制调度配置在YAML上完全一样。区别在于镜像：场景三的镜像同时支持双架构，但出于性能或成本原因，仍希望它强制跑在ARM节点上。
#### 常见问题
#### 如何验证Pod是否调度到了ARM节点？
1. 查看Pod所在节点。
   ```
   kubectl get pod <pod-name> -o wide
   ```
   
2. 进一步查看节点架构
   ```
   kubectl get node <node-name> -o jsonpath='{.metadata.labels.kubernetes\.io/arch}'
   ```
   输出arm64表示成功调度到了ARM节点。
   
 
#### 如何构建双架构镜像？
您可以使用Docker的Manifest List功能构建双架构容器镜像，具体操作请参见[CCE中使用x86和ARM双架构镜像](https://support.huaweicloud.com/bestpractice-cce/cce_bestpractice_0305.html)。
