从 kube-scheduler 的角度来看,它是通过一系列算法计算出最佳节点运行 Pod,当出现新的 Pod 进行调度时,调度程序会根据其当时对 Kubernetes 集群的资源描述做出最佳调度决定,但是 Kubernetes 集群是非常动态的,由于整个集群范围内的变化,比如一个节点为了维护,我们先执行了驱逐操作,这个节点上的所有 Pod 会被驱逐到其他节点去,但是当我们维护完成后,之前的 Pod 并不会自动回到该节点上来,因为 Pod 一旦被绑定了节点是不会触发重新调度的,由于这些变化,Kubernetes 集群在一段时间内就可能会出现不均衡的状态,所以需要均衡器来重新平衡集群。

当然我们可以去手动做一些集群的平衡,比如手动去删掉某些 Pod,触发重新调度就可以了,但是显然这是一个繁琐的过程,也不是解决问题的方式。为了解决实际运行中集群资源无法充分利用或浪费的问题,可以使用 descheduler 组件对集群的 Pod 进行调度优化,descheduler 可以根据一些规则和配置策略来帮助我们重新平衡集群状态,其核心原理是根据其策略配置找到可以被移除的 Pod 并驱逐它们,其本身并不会进行调度被驱逐的 Pod,而是依靠默认的调度器来实现。

文档参考:github 知乎

遇到的问题:

因为我所管理的集群中无状态应用很多,且更新频繁,常常出现更新后各个节点pod分布不均的问题,常常导致个别节点cpu利用率过高导致程序内部超时的问题,需要每个node都保持在cpu load 在80%左右才能保持较好的性能,但是手工调整很麻烦!所以使用了descheduler这个工具来帮助完成此需求。

下载

  1. 从github下载压缩包
    在这里插入图片描述
    解压缩
    wget https://github.com/kubernetes-sigs/descheduler/archive/refs/heads/master.zip
    unzip descheduler-master.zip

启动

  1. 我这里选择了以deployment的形式部署
    我的配置:configmap.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: descheduler-policy-configmap
  namespace: kube-system
data:
  policy.yaml: |
    apiVersion: "descheduler/v1alpha1"
    kind: "DeschedulerPolicy"
    nodeSelector: descheduler=1 # 只针对有descheduler=1标签的节点发起调度
    evictLocalStoragePods: true # 是否驱逐使用本地挂载(HostPath)的pod
    strategies:
      "RemoveDuplicates":
         enabled: false
      "RemovePodsViolatingInterPodAntiAffinity":
         enabled: false
      "LowNodeUtilization":
         enabled: true
         params:
           thresholdPriorityClassName: "system-cluster-critical" # 优先级为system-cluster-critical及以上的pod不会被调度
           nodeResourceUtilizationThresholds:
             thresholds:
               "cpu" : 70 # 下限
               #"memory": 20
               #"pods": 20
             targetThresholds:
               "cpu" : 85 # 上限
               #"memory": 50
               #"pods": 50

deployment.yaml

# 关键配置部分
    containers:
      - args:
        - --policy-config-file
        - /policy-dir/policy.yaml
        - --descheduling-interval
        - 1h # 检查的频率
        - --log_dir # 日志文件目录
        - /tmp
        - --log_file
        - descheduler.log
        - --v
        - "3" # 日志等级,在遇到不清楚的bug时可改为4

关于descheduler日志文件无法生成的问题,在1.22版本及以后会生效,贴一下我提的issues

cd descheduler-master
kubectl create -f kubernetes/base/rbac.yaml
kubectl create -f kubernetes/base/configmap.yaml
kubectl create -f kubernetes/deployment/deployment.yaml

查看descheduler日志,可以通过日志查看有哪些pod被调度。

kubectl get pod -n kube-system | grep desched | awk '{print $1}' | xargs kubectl logs -f -n kube-system
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐