kubernetes – 利用descheduler均衡POD分布

kube-scheduler调度POD是一次性决策的,一旦POD选定node运行起来,除非人工干预否则POD将永远运行在该node。

那么一个典型的问题就来了,当我们向集群新加入一个node时,POD并不会自动均衡到这个node,除非我们主动滚动发布以便让kube-scheduler做出新的决策。

类似的问题还有,我们通常希望同一个deployment的POD可以分布到不同的node上,然而集群中的资源碎片很有可能导致2个POD分布到一个node上,随着集群资源的自然变动,我们希望能有合适的机会重新进行打散。

那么,上述实际问题就需要引入一个新的组件叫做descheduler,由它来辅助kube-scheduler,对POD进行定期的二次打散整理,确保集群尽量调度均衡。

使用方法

descheduler配置与使用非常简单,也是K8S官方的准预备项目,理论上是可靠的。

项目地址:https://github.com/kubernetes-sigs/descheduler,把项目下载下来即可。

创建rbac

因为descheduler需要获取集群的pod/node等资源信息,以便做出决策,所以第一步就是配置rbac相关的东西,简单说就是创建serviceaccount与role,然后做一下两者的binding。

执行如下命令直接生效:

kubectl apply -f kubernetes/rbac.yaml

会得到一个kube-system命名空间下面的descheduler-sa账号,已经做好了资源授权。

创建configmap

descheduler的配置文件,通过configmap配置并挂载。

打开kubernetes/configmap.yaml,看一下descheduler支持的几个均衡策略:

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: descheduler-policy-configmap
  namespace: kube-system
data:
  policy.yaml: |
    apiVersion: "descheduler/v1alpha1"
    kind: "DeschedulerPolicy"
    strategies:
      "RemoveDuplicates":
         enabled: true
      "RemovePodsViolatingInterPodAntiAffinity":
         enabled: true
      "LowNodeUtilization":
         enabled: true
         params:
           nodeResourceUtilizationThresholds:
             thresholds:
               "cpu" : 20
               "memory": 20
               "pods": 20
             targetThresholds:
               "cpu" : 50
               "memory": 50
               "pods": 50

它最多支持5种策略共同工作,每一个策略有独立的开关选项。

该配置文件只写了3个策略,也是比较好用的几个策略:

  • RemoveDuplicates:如果deployment的多个pod在同1个node上,那么就试图打散。
  • RemovePodsViolatingInterPodAntiAffinity:pod曾经与node亲和,而现在不再亲和了,那么对该pod尝试做迁移。
  • LowNodeUtilization:如果node上的cpu/memory/pods的request超过targetThresholds阈值,则认为该node负载太高,会尝试将其上的pod进行迁移,迁移的目标node需要低于thresholds阈值,这些node被认为是负载太低。

针对LowNodeUtilization策略,根据github中的说明:

1)thresholds的判断是必须cpu+mem+pod三个条件(都是百分比)同时满足才算作”低负载node”,其cpu/memory依据是request值。

2)targetThresholds判断依据是cpu or mem or pod任意一个超过阈值才算作”高负载node”。

pod会从”高负载node” 迁移至 “低负载node”,不满足2个条件的node不会做均衡处理。

有需要则调整,然后直接提交即可:

kubectl apply -f kubernetes/configmap.yaml

运行

理论上来说,descheduler还是凌晨业务低峰期执行比较靠谱,因此descheduler也被设计为一种一次性的JOB。

为了自动执行,我们使用cronjob来定时运行它。

打开kubernetes/cronjob.yaml:

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: descheduler-cronjob
  namespace: kube-system
spec:
  schedule: "*/2 * * * *"
  concurrencyPolicy: "Forbid"
  jobTemplate:
    spec:
      template:
        metadata:
          name: descheduler-pod
        spec:
          priorityClassName: system-cluster-critical
          containers:
          - name: descheduler
            image: us.gcr.io/k8s-artifacts-prod/descheduler/descheduler:v0.18.0
            volumeMounts:
            - mountPath: /policy-dir
              name: policy-volume
            command:
              - "/bin/descheduler"
            args:
              - "--policy-config-file"
              - "/policy-dir/policy.yaml"
              - "--v"
              - "3"
          restartPolicy: "Never"
          serviceAccountName: descheduler-sa
          volumes:
          - name: policy-volume
            configMap:
              name: descheduler-policy-configmap

可见,它挂载了configmap作为配置文件,配置了descheduler-sa的serviceaccount,并且禁止了并发执行。

默认是2分钟调度一次,我们根据自己修改cron表达式即可,比如改成每天凌晨执行。

镜像已经被墙,大家可以使用海外服务器下载镜像然后推送到dockerhub作替代,或者直接使用我备份的版本:owenliang1990/descheduler:v0.18.0。

直接提交它即可:

kubectl apply -f kubernetes/cronjob.yaml

日志

cronjob会定时拉起一个Pod,我们可以修改Descheduler启动参数的日志级别调整–v 5,通过kubectl logs查看pod具体做了哪些决策。

调试

为了降低使用descheduler的风险(比如大面积的踢出POD),测试时使用启动参数–dry-run,令其仅做决策不做真正的POD驱逐,根据日志验证在不同集群上的具体表现,辅助我们调整驱逐的阈值参数。

我认为正常情况下,仅仅基于CPU指标来做均衡即可,不需要考虑Mem/POD个数,否则低负载节点的多个thresholds条件比较难以同时成立。

实测下来,descheduler会扫描每个node,先判断node的cpu/mem/pods是否同时小于thresholds,如果成立则认为该node是低负载的;如果不成立则进一步判断cpu/mem/pods是否任意指标大于targetThresholds,如果成立则认为是高负载的;其他情况node什么也不是,不参与调度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

0X码上链

你的鼓将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值