From 541565de483e58a365a50f99c39f3520b06acf22 Mon Sep 17 00:00:00 2001 From: OG T Date: Sat, 28 Mar 2026 22:03:54 +0800 Subject: [PATCH] feat(k4.2): Descheduler for pod rebalancing - Deploy Descheduler v0.30.1 as CronJob - Schedule: Every 2 hours - Policies enabled: - LowNodeUtilization: rebalance when node < 20% usage - RemoveDuplicates: spread replicas across nodes - RemovePodsViolatingNodeAffinity: enforce affinity rules Co-Authored-By: Claude Opus 4.5 --- k8s/descheduler/descheduler.yaml | 135 +++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 k8s/descheduler/descheduler.yaml diff --git a/k8s/descheduler/descheduler.yaml b/k8s/descheduler/descheduler.yaml new file mode 100644 index 000000000..61b6485bd --- /dev/null +++ b/k8s/descheduler/descheduler.yaml @@ -0,0 +1,135 @@ +# ============================================================================= +# Descheduler +# ============================================================================= +# K4.2 2026-03-28: Pod rebalancing for load distribution +# Deployed by: Claude Code (首席架構師) +# Schedule: Every 2 hours (cron) +# ============================================================================= +--- +apiVersion: v1 +kind: Namespace +metadata: + name: descheduler + labels: + app.kubernetes.io/name: descheduler +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: descheduler + namespace: descheduler +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: descheduler +rules: + - apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "watch", "list"] + - apiGroups: [""] + resources: ["pods"] + verbs: ["get", "watch", "list", "delete"] + - apiGroups: [""] + resources: ["pods/eviction"] + verbs: ["create"] + - apiGroups: ["scheduling.k8s.io"] + resources: ["priorityclasses"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: descheduler +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: descheduler +subjects: + - kind: ServiceAccount + name: descheduler + namespace: descheduler +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: descheduler-policy + namespace: descheduler +data: + policy.yaml: | + apiVersion: descheduler/v1alpha2 + kind: DeschedulerPolicy + profiles: + - name: default + pluginConfig: + - name: LowNodeUtilization + args: + targetThresholds: + cpu: 50 + memory: 50 + pods: 50 + thresholds: + cpu: 20 + memory: 20 + pods: 20 + - name: RemovePodsViolatingNodeAffinity + args: + nodeAffinityType: + - requiredDuringSchedulingIgnoredDuringExecution + - name: RemoveDuplicates + args: + excludeOwnerKinds: + - DaemonSet + plugins: + balance: + enabled: + - LowNodeUtilization + - RemoveDuplicates + deschedule: + enabled: + - RemovePodsViolatingNodeAffinity +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: descheduler + namespace: descheduler + labels: + app.kubernetes.io/name: descheduler + app.kubernetes.io/version: "0.30.1" +spec: + schedule: "0 */2 * * *" # Every 2 hours + concurrencyPolicy: Forbid + successfulJobsHistoryLimit: 3 + failedJobsHistoryLimit: 3 + jobTemplate: + spec: + template: + metadata: + labels: + app.kubernetes.io/name: descheduler + spec: + serviceAccountName: descheduler + restartPolicy: Never + containers: + - name: descheduler + image: registry.k8s.io/descheduler/descheduler:v0.30.1 + imagePullPolicy: IfNotPresent + command: + - /bin/descheduler + - --policy-config-file=/policy-dir/policy.yaml + - --v=3 + resources: + limits: + cpu: 200m + memory: 128Mi + requests: + cpu: 100m + memory: 64Mi + volumeMounts: + - name: policy-volume + mountPath: /policy-dir + volumes: + - name: policy-volume + configMap: + name: descheduler-policy