HorizontalPodAutoscaler
Does ZopNight manage HorizontalPodAutoscaler?
HorizontalPodAutoscalers move replicas between minReplicas and maxReplicas, and the minimum is a cost floor that holds capacity at 3 a.m. ZopNight records target, bounds, current and desired replicas, and conditions, flagging saturation only when ScalingLimited reports TooManyReplicas, since desiredReplicas is clamped and can never exceed the max.
Rules that fire on HorizontalPodAutoscaler
A HorizontalPodAutoscaler moves a workload’s replica count between a floor and a ceiling based on observed metrics. Both bounds are cost decisions: the floor is capacity you pay for at 3 a.m., and the ceiling is where saturation hides.
minReplicas is a spending floor
Discovery records the target workload (targetRef and kind), minReplicas, maxReplicas, current and desired replicas, the configured metrics, current metric readings, conditions, and the last scale time. The floor deserves the most scrutiny: an HPA with a generous minimum keeps that many pods, and the node capacity beneath them, running through every quiet hour, which is over-provisioning wearing an autoscaling costume.
Why at-max detection reads a condition, not a comparison
Kubernetes clamps desiredReplicas to maxReplicas, so the intuitive check (desired above max) can never be observed on real data. The HPA At Max Capacity rule (RC-1717 / RC-1817 / RC-1917, high severity) instead reads the HPA’s own ScalingLimited condition and fires only when it is True with reason TooManyReplicas: the controller’s first-hand record that it wanted more replicas than the ceiling allowed. A workload that merely happens to run at exactly max is left alone, and missing or unparseable conditions cause the rule to abstain rather than guess.
Removed and recreated around scheduled downtime
An HPA will fight any external scale-to-zero, because it exists to restore replicas. So when a namespace schedule stops an environment, ZopNight deletes the HPAs along with scaling the workloads down, then recreates them at resume with their original spec. Deleting rather than editing means there is no window where a half-configured autoscaler can act on stale metrics.
kubectl get hpa -A -o custom-columns=NS:.metadata.namespace,NAME:.metadata.name,TARGET:.spec.scaleTargetRef.name,MIN:.spec.minReplicas,MAX:.spec.maxReplicas,CURRENT:.status.currentReplicasReading an HPA in review
Three questions cover most audits: does the floor reflect real overnight demand or just caution; has ScalingLimited been true recently, meaning the ceiling is throttling real traffic; and does the target workload still exist? The recorded conditions and last scale time answer all three without touching the cluster.