{ "description": "Tier defines the centralized resiliency and scaling policy for a class of\napplications (e.g. critical, standard, best-effort). Workloads opt in by\ncarrying the label `platform.olb42.com/tier: ` \u2014 no per-app\nHPA/PDB/toleration configuration is required. The tier-controller watches\nNode state and applies each Tier's policy to every workload selected by\nthat label.", "properties": { "apiVersion": { "type": "string" }, "kind": { "type": "string" }, "metadata": { "type": "object" }, "spec": { "properties": { "capacity": { "description": "How replica counts for this tier react to a change in ready/schedulable node count.", "properties": { "minReplicasFloor": { "default": 1, "description": "Replica count this tier's workloads are never scaled below by\nthe controller, regardless of how many nodes are lost.", "format": "int32", "minimum": 0, "type": "integer" }, "replicaLossPerNode": { "default": 0, "description": "Replicas to shed per node lost (unexpected loss) or cordoned\n(intentional maintenance), before floor is applied. 0 means the\nworkload's replica count is never reduced by node loss alone.", "format": "int32", "minimum": 0, "type": "integer" }, "scaleToZeroOnCordon": { "default": false, "description": "Same as scaleToZeroOnNodeLoss, but for the intentional\ncordon/drain path.", "type": "boolean" }, "scaleToZeroOnNodeLoss": { "default": false, "description": "If true, workloads in this tier are scaled to 0 replicas on\nunexpected node loss, freeing capacity for higher tiers.\nminReplicasFloor is ignored when this is true.", "type": "boolean" } }, "type": "object", "additionalProperties": false }, "deletionCostBase": { "default": 0, "description": "Baseline value stamped as the\ncontroller.kubernetes.io/pod-deletion-cost annotation on pods of\nthis tier. Higher values are removed later during a voluntary\nscale-down, so this should be set relative to the other tiers'\nvalues (e.g. critical=1000, standard=500, best-effort=0).", "format": "int32", "type": "integer" }, "disruption": { "description": "Voluntary-disruption budget applied to workloads in this tier.", "properties": { "pdbMinAvailable": { "anyOf": [ { "type": "integer" }, { "type": "string" } ], "description": "Value for the PodDisruptionBudget's spec.minAvailable the\ncontroller manages for each workload in this tier. Accepts an\nabsolute number or a percentage string (e.g. \"50%\"), matching\nnative PDB semantics.", "x-kubernetes-int-or-string": true } }, "type": "object", "additionalProperties": false }, "priorityClassName": { "description": "Name of the PriorityClass the controller ensures exists and stamps\nonto pods of workloads carrying this tier. Acts as the native\npreemption safety net independent of the controller's own\nreconcile latency.", "minLength": 1, "type": "string" }, "priorityValue": { "description": "Value used when the controller creates the PriorityClass named\nabove, if it does not already exist. Higher preempts lower.\nIgnored if a PriorityClass with that name already exists.", "format": "int32", "type": "integer" }, "reschedule": { "description": "Controls how quickly pods of this tier are rescheduled off a node\nthat has gone NotReady/Unreachable, overriding the cluster default\n(node.kubernetes.io/not-ready and .../unreachable tolerationSeconds,\nnormally 300s).", "properties": { "fastTolerationSeconds": { "description": "tolerationSeconds the controller stamps for the not-ready and\nunreachable node taints on this tier's pods. Omit to leave the\ncluster default in place.", "format": "int32", "minimum": 0, "type": "integer" } }, "type": "object", "additionalProperties": false }, "resources": { "description": "Optional hook into a resource right-sizing mechanism (e.g. Attune)\nduring a degraded-capacity window. Left empty, this tier's pod\nresource requests are never adjusted by the controller.", "properties": { "resizerRef": { "description": "Reference to the object the controller annotates/patches to request a resize pass (e.g. an AttunePolicy).", "properties": { "apiVersion": { "type": "string" }, "kind": { "type": "string" }, "name": { "type": "string" }, "namespace": { "type": "string" } }, "type": "object", "additionalProperties": false }, "shrinkOnDegradedCapacity": { "default": false, "description": "If true, the controller signals the configured right-sizer\n(see resizerRef) to reduce this tier's resource requests while\ncluster capacity is reduced. Requires in-place pod resize\nsupport (Kubernetes 1.32+) on the cluster.", "type": "boolean" } }, "type": "object", "additionalProperties": false }, "storage": { "description": "Longhorn-specific behavior during the graceful cordon path. No effect on the unexpected node-loss path.", "properties": { "preMigrateLonghorn": { "default": false, "description": "If true, the controller triggers Longhorn replica migration off\nthe cordoning node and waits for volume health before allowing\nthe drain to proceed, for volumes backing this tier's workloads.", "type": "boolean" } }, "type": "object", "additionalProperties": false } }, "required": [ "priorityClassName" ], "type": "object", "additionalProperties": false }, "status": { "properties": { "appliedWorkloadCount": { "description": "Number of workloads currently selected by this tier's label across the cluster.", "format": "int32", "type": "integer" }, "conditions": { "items": { "properties": { "lastTransitionTime": { "format": "date-time", "type": "string" }, "message": { "type": "string" }, "observedGeneration": { "format": "int64", "type": "integer" }, "reason": { "type": "string" }, "status": { "enum": [ "True", "False", "Unknown" ], "type": "string" }, "type": { "type": "string" } }, "required": [ "type", "status" ], "type": "object", "additionalProperties": false }, "type": "array" }, "observedGeneration": { "format": "int64", "type": "integer" } }, "type": "object", "additionalProperties": false } }, "required": [ "spec" ], "type": "object" }