本文介绍使用ACK集群调度策略时可能遇到的常见问题及对应的解决方案。

索引

如何防止虚拟交换机IP不足导致Pod启动失败

原生Kubernetes集群调度器无法感知识别节点上IP资源耗尽的情况,这导致即使在集群IP资源不足、Pod启动失败的情况下,系统仍会尝试将Pod调度到这些节点上,短时间内产生大量异常Pod。为了解决这一问题,ACK调度器引入了k8s.aliyun.com/max-available-ip注解来标记每个节点的最大可用IP数量,并据此以及Pod是否需要独立IP地址来限制可调度至该节点的Pod数量。此外,当检测到某个节点出现IP资源耗尽时,通过更新节点状态中的SufficientIP的Condition,阻止进一步向该节点调度需要独立IP地址的新Pod,从而有效避免了因IP资源不足而引发的大规模Pod故障情况。

此功能是kube-scheduler组件自动启用的功能。但您的集群及kube-scheduler组件需满足以下条件:

  • 集群为ACK集群Pro版,且集群网络插件为Terway,Terway版本为v1.5.7及以上。详细信息,请参见创建ACK托管集群

  • kube-scheduler版本需满足如下要求。

    集群版本

    kube-scheduler版本

    1.30

    所有版本均可支持

    1.28

    v1.28.3-aliyun-6.3及以上

    1.26

    v1.26.3-aliyun-6.3及以上

    1.24

    v1.24.6-aliyun-6.3及以上

    1.22

    v1.22.15-aliyun-6.3及以上

如何将ack-descheduler迁移至Koordinator Descheduler

容器服务 Kubernetes 版在应用市场中提供了重调度应用ack-descheduler组件。该组件是对社区Kubernetes Descheduler的封装,目前提供0.20.0和0.27.1两个版本,其功能和使用方法均与社区Kubernetes Descheduler 0.20.0以及0.27.1保持一致。

ack-descheduler已停止维护,建议您迁移至当前维护的组件模块Koordinator Descheduler迁移流程与迁移Kubernetes Descheduler至Koordinator Descheduler的流程类似,请参见迁移Kubernetes Descheduler至Koordinator Descheduler完成迁移。

ACK Scheduler的默认调度策略是什么?

在ACK集群中,ACK Scheduler的默认调度策略与社区Kubernetes调度器保持一致。Kubernetes调度器决定如何将Pod调度到某个节点时,通常包括两个关键步骤:Filter(过滤)和Score(评分)。

  • Filter:过滤哪些节点可以被调度的。如果过滤后的列表为空,则表明Pod当前无法被调度。

  • Score:过滤后,调度器将对可供调度的节点进行打分和排名,从而选择一个最适合放置Pod的节点。

关于ACK Scheduler最新版本中开启的Filter和Score插件,请参见Filter及Score插件介绍

如何在Pod调度过程中,规避利用率热点节点?

在Kubernetes原生调度策略中,调度器主要基于节点资源的分配情况(资源Request)进行调度,并不会参考节点的真实利用率情况。此外,调度器还有多种Filter(过滤)和Score(评分)插件,共同影响着调度结果。推荐您使用ACK集群提供的如下功能,避免Pod被调度到热点节点上。

  • 为每个Pod配置合理的资源Request和Limit,规划资源冗余。您可以使用资源画像功能,基于对资源使用量历史数据的分析获取容器规格的推荐配置。更多信息,请参见资源画像

  • 启用负载感知调度功能。负载感知调度是ACK调度器Kube Scheduler基于Kubernetes Scheduling Framework实现的插件。与Kubernetes原生调度策略不同的是,ACK Scheduler可以感知节点实际的资源使用情况,通过参考节点负载的历史数据并对新调度Pod进行预估,将Pod优先调度到负载较低的节点,实现节点的负载均衡。更多信息,请参见使用负载感知调度

  • 启用负载热点打散重调度功能。节点的利用率会随着时间、集群环境变化、工作负载的流量或请求等动态变化,从而导致集群内节点间原本的负载均衡被打破,ACK Scheduler还提供了重调度能力,防止负载出现极端不均衡的情况。更多信息,请参见使用负载热点打散重调度

集群中新增了一个节点,但Pod为什么始终没有调度到这台节点上去?

此现象可能由多种原因导致。您可以按照如下流程进行排查。

  1. 检查节点状态是否正常。若节点处于NotReady状态,表明节点仍未就绪。

  2. 检查Pod是否设置了不合适的调度策略(NodeSelector、NodeAffinity、PodAffinity)或存在污点等情况,导致Pod无法被调度到新节点。

  3. 评估是否为Kubernetes原生调度策略问题。在Kubernetes原生调度策略中,调度器主要基于节点资源的分配情况(资源Request)进行调度,并不会参考节点的真实利用率情况,所以可能会出现某些节点上运行的Pod很多,某些节点上运行的Pod很少或没有。

    您可以参见如何在Pod调度过程中,规避利用率热点节点?提供的解决方案解决此问题。

集群中CPU或内存使用率不高,但调度时会提示CPU或内存资源不足

在Kubernetes原生调度策略中,调度器主要基于节点资源的分配情况(资源Request)进行调度,并不会参考节点的真实资源使用率,所以即使集群CPU真实使用率不高,但仍有可能出现Pod调度时因CPU、内存资源不足(Insufficient CPU或Insufficient Memory)而调度失败的情况。

您可以参见如何在Pod调度过程中,规避利用率热点节点?提供的解决方案解决此问题。

在ACK中使用重调度功能有哪些注意事项?是否会重启Pod?

ACK通过Koordinator Descheduler提供重调度功能,在使用重调度功能时,有如下注意事项。

  • Koordinator Descheduler只负责驱逐正在运行的Pod,并不负责Pod驱逐后的重建以及调度。Pod被驱逐后的重建由其工作负载对应的Controller实现(例如Deployment、StatefulSet),重建后Pod的调度流程仍然由调度器负责。

  • 重调度在执行过程中会先驱逐旧Pod,再创建新Pod。请确保您的应用有充足的冗余副本(replicas),避免驱逐时影响应用可用性。

更多信息,请参见重调度概述

如何将应用调度到指定的节点上?

您可以为节点设置标签,然后在应用YAML中添加对应的nodeSelector,调度应用到指定节点。具体操作,请参见调度应用至指定节点

在一个Deployment中,如何指定一定数量的Pod调度到ECS,一定数量的Pod调度到ECI?

在ECS、ECI资源混合使用场景的下,您可以通过UnitedDeployment的方式定义Subset,对工作负载进行管理。例如,您可以在UnitedDeployment的YAML中指定subset-ecs中的replicas10,subset-eci中的replicas10。详细信息,请参见基于UnitedDeployment实现工作负载的伸缩

如何让一个工作负载的Pod在调度时满足高可用

您可以通过Pod亲和性的方式,将一个工作负载的Pod打散到不同可用区或节点。例如,您可以参见下方YAML为Pod添加如下字段,声明一个preferredDuringSchedulingIgnoredDuringExecution“偏好”规则,尝试将具有 security=S2 Label的Pod分散调度到不同的可用区(zone)内,并在无法满足此条件时,再次尝试将该Pod调度到其他节点上。

spec:
  affinity:
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: security
              operator: In
              values:
              - S2
          topologyKey: topology.kubernetes.io/zone

详细信息,请参见Kubernetes官方文档podAffinity和podAntiAffinity拓扑分布约束(Topology Spread Constraints)