
# 节点池高可用最佳实践
在使用节点池部署业务时，为提高可用性和容灾能力，您可以通过以下两个方面进行优化：在节点层面，利用节点池的云服务器组和可用区策略实现物理隔离；在Pod层面，通过亲和性调度和拓扑分布约束确保业务均匀分布在不同的节点上。
#### 节点层面：实现物理机与可用区反亲和
**物理机反亲和：使用云服务器组**
云服务器组是华为云ECS提供的功能，用于控制云服务器实例的部署位置。
创建反亲和性云服务器组：在ECS控制台创建组时，选择"反亲和性"策略。组内的实例会由系统调度到不同的物理主机上。详情请参见[管理云服务器组](https://support.huaweicloud.com/usermanual-ecs/ecs_03_0150.html)。
**在节点池中关联云服务器组：**
创建节点池时：在CCE控制台创建或编辑节点池，展开"高级设置"，在"云服务器组"选项中选择已创建的反亲和性云服务器组。
效果：该节点池扩容出的所有新节点都会自动加入该组，并严格分散在不同物理机上。
![](https://support.huaweicloud.com/bestpractice-cce/zh-cn_image_0000002543953681.png "点击放大")
**可用区反亲和：创建多AZ节点池**
这是构建跨可用区高可用架构的基础。
配置方法：在创建节点池时，选择勾选多个可用区的节点规格。
节点池会按配置在指定可用区内创建节点，实现了AZ级别的分布。即使单个AZ整体故障，其他AZ的节点仍可维持服务。
![](https://support.huaweicloud.com/bestpractice-cce/zh-cn_image_0000002543912089.png "点击放大")
#### Pod层面：通过调度策略实现精细分布
在节点资源就绪后，需要利用Kubernetes原生调度规则，将Pod均匀、合理地调度到这些高可用节点上。
**Pod亲和与反亲和调度**
Pod反亲和：常用于将同一服务的多个副本分散开，避免"把所有鸡蛋放在一个篮子里"。
示例：实现一个节点只运行一个Pod副本
以下YAML示例利用podAntiAffinity的requiredDuringSchedulingIgnoredDuringExecution（硬约束），确保带有app: nginx-ha标签的Pod不会被调度到同一主机上。
```
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-ha
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-ha
  template:
    metadata:
      labels:
        app: nginx-ha
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - nginx-ha
            topologyKey: kubernetes.io/hostname  # 以“主机名”作为拓扑域，确保调度到不同节点
      containers:
      - name: nginx
        image: nginx:latest
      imagePullSecrets:
        - name: default-secret
```
**Pod拓扑分布约束**
拓扑分布约束是比反亲和性更灵活、功能更强的打散调度策略，可以定义在多个拓扑域（如主机、可用区）上的最大不均衡程度。
核心概念：
- topologyKey：定义拓扑域的节点标签，如kubernetes.io/hostname（节点）、topology.kubernetes.io/zone（可用区）。
- maxSkew：定义Pod分布不均衡的最大程度，必须大于0。
- whenUnsatisfiable：定义条件不满足时的处理策略（DoNotSchedule 不调度 / ScheduleAnyway 尽量调度）。
示例：跨可用区和节点均匀打散Pod
以下YAML示例通过两条约束，要求Pod在节点和可用区两个维度上都尽可能均匀分布。
```
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-topo
spec:
  replicas: 4
  selector:
    matchLabels:
      app: nginx-topo
  template:
    metadata:
      labels:
        app: nginx-topo
    spec:
      topologySpreadConstraints:
      - maxSkew: 1  # 在同一个拓扑域中，不同Selector的Pod数量差最大为1
        topologyKey: kubernetes.io/hostname  # 拓扑域为节点
        whenUnsatisfiable: DoNotSchedule
        labelSelector:
          matchLabels:
            app: nginx-topo
      - maxSkew: 1
        topologyKey: topology.kubernetes.io/zone  # 拓扑域为可用区
        whenUnsatisfiable: DoNotSchedule
        labelSelector:
          matchLabels:
            app: nginx-topo
      containers:
      - name: nginx
        image: nginx:latest
      imagePullSecrets:
        - name: default-secret
```
