# =============================================================================
# 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
              # 2026-03-29: 從 20% 調整為 30% (首席架構師建議)
              # 避免小型叢集過度頻繁遷移
              thresholds:
                cpu: 30
                memory: 30
                pods: 30
          - 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
