官网:https://github.com/kubernetes-sigs/descheduler#install-using-helm
用户手册:https://github.com/kubernetes-sigs/descheduler/blob/master/docs/user-guide.md
通过descheduler可以定期检测Kubernetes当前节点请求资源request/limit情况,根据制定的策略重新调度pod,减少集群长期运行导致的pod分配不均衡的问题,根据节点实际使用率调度处于TODO开发阶段。
使用descheduler可以解决如下问题:
部分节点利用率不足/过高
最初的调度决策不再成立,因为节点上添加或删除了污染或标签,pod/节点关联需求不再得到满足。
一些节点发生故障,它们的pods转移到其他节点
新增节点加入集群
descheduler决定从一个节点上驱逐pods时,它采用以下通用机制:
关键pods(当priorityClassName设置为system-cluster-critical或system-node-critical时)不会被清除(除非设置了evictSystemCriticalPods: true)。
不属于ReplicationController、ReplicaSet(Deployment)、StatefulSet或Job的Pods(静态或镜像或独立的Pods)不会被移除,因为这些Pods不会被重新创建。(通过设置evictFailedBarePods: true可以清除处于失败状态的独立pod)
与daemonset关联的Pods永远不会被驱逐。
具有本地存储的Pods永远不会被驱逐(除非设置了evictLocalStoragePods: true)。
带有pvc的Pods会被驱逐(除非ignorePvcPods: true设置,如果已经通过label绑定可用区,可以忽略此参数)。
在LowNodeUtilization和RemovePodsViolatingInterPodAntiAffinity中,pods根据优先级从低到高被驱逐,如果它们具有相同的优先级,besteffort pods会在burstable和guaranteed pods之前被驱逐。
具有annotation descheduler.alpha.kubernetes.Io/evict都有资格被驱逐。这个注释用于覆盖防止退出的检查,用户可以选择退出哪个pod。用户应该知道如何以及是否会重新创建pod。
默认情况下,具有非nil DeletionTimestamp的Pods不会被删除。
在Descheduler上设置–v=4或更大的值将记录任何pod不可回收的所有原因。
Policy:
nodeselector 默认为nil,限制被处理的节点
evictlocalstoragepods 默认false 允许删除带有本地存储的pods
evectsystemcriticalpods 默认false 驱逐Kubernetes系统podss
ignorepvcpods 默认为false 设置PVC pods是否应该被移除或忽略
maxnoofpodstoevictpernode 默认无 从每个节点中移除的最大pods数(通过所有策略相加)
maxnoofpodstoevictpernamespace 默认为空 从每个命名空间中移除的最大pods数量(通过所有策略相加)
evectfailedbarepods 默认false 允许在没有所有者参考和失败阶段驱逐pods
apiVersion: "descheduler/v1alpha1"
kind: "DeschedulerPolicy"
nodeSelector: prod=dev
evictFailedBarePods: false
evictLocalStoragePods: true
evictSystemCriticalPods: true
maxNoOfPodsToEvictPerNode: 40
ignorePvcPods: false
strategies:
...
需要设置k8s pdb,保证最小数量/百分比的pod可用性,避免相同pod已经调度到相同节点,驱逐导致的服务不可用。
参考官网:https://kubernetes.io/zh/docs/tasks/run-application/configure-pdb/
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: pdb-demo
spec:
maxUnavailable: 1 # 设置最多不可用的副本数量,或者使用 minAvailable,可以使用整数或百分比
selector:
matchLabels: # 匹配Pod标签
app: demo
默认helm部署使用kind crontab,建议通过参数定义使用Deployment部署,便于后续使用
helm install descheduler descheduler/descheduler --set image.repository=raspbernetes/descheduler,podSecurityPolicy.create=false,kind=Deployment,deschedulerPolicy.strategies -n kube-system
调度策略:
LowNodeUtilization
使用LowNodeUtilization,调度程序将根据内存重新平衡集群,将内存利用率超过70%的节点的pods回收到内存利用率低于20%的节点。
numberOfNodes只有当未利用节点数大于配置值时,才能通过配置该参数激活策略。这在大型集群中很有帮助,其中一些节点可能会频繁或短时间内被利用。默认情况下,numberOfNodes设置为0。
apiVersion: "descheduler/v1alpha1"
kind: "DeschedulerPolicy"
strategies:
"LowNodeUtilization":
enabled: true
params:
nodeResourceUtilizationThresholds:
thresholds:
"memory": 20
targetThresholds:
"memory": 70
numberOfNodes: 3
HighNodeUtilization
HighNodeUtilization发现可被利用的节点,并从节点中移除pods,希望这些pods被紧凑地安排到更少的节点中。此策略与节点自动伸缩(CA)结合使用,旨在帮助触发低利用率节点的缩容。此策略必须与scheduler 评分策略 MostAllocated 一起使用。
apiVersion: "descheduler/v1alpha1"
kind: "DeschedulerPolicy"
strategies:
"HighNodeUtilization":
enabled: true
params:
nodeResourceUtilizationThresholds:
thresholds:
"cpu" : 20
"memory": 20
"pods": 20