diff --git a/apps/base/vpa-system/kustomization.yaml b/apps/base/vpa-system/kustomization.yaml new file mode 100644 index 0000000..8c31f43 --- /dev/null +++ b/apps/base/vpa-system/kustomization.yaml @@ -0,0 +1,12 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - namespace.yaml + # VPA CRDs (verticalpodautoscalers + verticalpodautoscalercheckpoints) from + # the kubernetes/autoscaler repo at the pinned release tag, served through the + # artifactapi github remote (pattern allowlisted in terraform-artifactapi#14). + # The recommender deployment lands separately once these CRDs (and their + # kubeconform schemas under schemas/autoscaling.k8s.io/) are in. + - https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/github/kubernetes/autoscaler/raw/vertical-pod-autoscaler-1.7.0/vertical-pod-autoscaler/deploy/vpa-v1-crd-gen.yaml diff --git a/apps/base/vpa-system/namespace.yaml b/apps/base/vpa-system/namespace.yaml new file mode 100644 index 0000000..0e1e632 --- /dev/null +++ b/apps/base/vpa-system/namespace.yaml @@ -0,0 +1,5 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: vpa-system diff --git a/apps/overlays/au-syd1/vpa-system/kustomization.yaml b/apps/overlays/au-syd1/vpa-system/kustomization.yaml new file mode 100644 index 0000000..5be9008 --- /dev/null +++ b/apps/overlays/au-syd1/vpa-system/kustomization.yaml @@ -0,0 +1,6 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - ../../../base/vpa-system diff --git a/argocd/applicationsets/platform.yaml b/argocd/applicationsets/platform.yaml index 28174aa..84f67c7 100644 --- a/argocd/applicationsets/platform.yaml +++ b/argocd/applicationsets/platform.yaml @@ -38,6 +38,7 @@ spec: - path: apps/overlays/*/reposync - path: apps/overlays/*/traefik-system - path: apps/overlays/*/vm-system + - path: apps/overlays/*/vpa-system - path: apps/overlays/*/vault - path: apps/overlays/*/vso-system - path: apps/overlays/*/woodpecker diff --git a/schemas/autoscaling.k8s.io/verticalpodautoscaler_v1.json b/schemas/autoscaling.k8s.io/verticalpodautoscaler_v1.json new file mode 100644 index 0000000..5757549 --- /dev/null +++ b/schemas/autoscaling.k8s.io/verticalpodautoscaler_v1.json @@ -0,0 +1,431 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "apiVersion": { + "type": "string" + }, + "kind": { + "type": "string" + }, + "metadata": { + "type": "object" + }, + "spec": { + "properties": { + "recommenders": { + "items": { + "properties": { + "name": { + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "type": "array" + }, + "resourcePolicy": { + "properties": { + "containerPolicies": { + "items": { + "properties": { + "containerName": { + "type": "string" + }, + "controlledResources": { + "items": { + "type": "string" + }, + "type": "array" + }, + "controlledValues": { + "enum": [ + "RequestsAndLimits", + "RequestsOnly" + ], + "type": "string" + }, + "maxAllowed": { + "additionalProperties": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "x-kubernetes-int-or-string": true + }, + "type": "object" + }, + "memoryAggregationIntervalCount": { + "format": "int64", + "minimum": 1, + "type": "integer" + }, + "memoryAggregationIntervalSeconds": { + "format": "int32", + "minimum": 1, + "type": "integer" + }, + "minAllowed": { + "additionalProperties": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "x-kubernetes-int-or-string": true + }, + "type": "object" + }, + "mode": { + "enum": [ + "Auto", + "Off" + ], + "type": "string" + }, + "oomBumpUpRatio": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "x-kubernetes-int-or-string": true + }, + "oomMinBumpUp": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "x-kubernetes-int-or-string": true + }, + "startupBoost": { + "properties": { + "cpu": { + "properties": { + "durationSeconds": { + "format": "int32", + "type": "integer" + }, + "factor": { + "format": "int32", + "type": "integer" + }, + "quantity": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "x-kubernetes-int-or-string": true + }, + "type": { + "enum": [ + "Factor", + "Quantity" + ], + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object", + "x-kubernetes-validations": [ + { + "message": "factor is required when type is Factor and forbidden otherwise", + "rule": "(self.type == 'Factor') == has(self.factor)" + }, + { + "message": "quantity is required when type is Quantity and forbidden otherwise", + "rule": "(self.type == 'Quantity') == has(self.quantity)" + } + ] + } + }, + "type": "object" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, + "startupBoost": { + "properties": { + "cpu": { + "properties": { + "durationSeconds": { + "format": "int32", + "type": "integer" + }, + "factor": { + "format": "int32", + "type": "integer" + }, + "quantity": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "x-kubernetes-int-or-string": true + }, + "type": { + "enum": [ + "Factor", + "Quantity" + ], + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object", + "x-kubernetes-validations": [ + { + "message": "factor is required when type is Factor and forbidden otherwise", + "rule": "(self.type == 'Factor') == has(self.factor)" + }, + { + "message": "quantity is required when type is Quantity and forbidden otherwise", + "rule": "(self.type == 'Quantity') == has(self.quantity)" + } + ] + } + }, + "type": "object" + }, + "targetRef": { + "properties": { + "apiVersion": { + "type": "string" + }, + "kind": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "required": [ + "kind", + "name" + ], + "type": "object", + "x-kubernetes-map-type": "atomic" + }, + "updatePolicy": { + "properties": { + "evictAfterOOMSeconds": { + "format": "int32", + "minimum": 1, + "type": "integer" + }, + "evictionRequirements": { + "items": { + "properties": { + "changeRequirement": { + "enum": [ + "TargetHigherThanRequests", + "TargetLowerThanRequests" + ], + "type": "string" + }, + "resources": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "changeRequirement", + "resources" + ], + "type": "object" + }, + "type": "array" + }, + "minReplicas": { + "format": "int32", + "type": "integer" + }, + "updateMode": { + "enum": [ + "Off", + "Initial", + "Recreate", + "InPlaceOrRecreate", + "InPlace", + "Auto" + ], + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "targetRef" + ], + "type": "object" + }, + "status": { + "properties": { + "conditions": { + "items": { + "properties": { + "lastTransitionTime": { + "format": "date-time", + "type": "string" + }, + "message": { + "type": "string" + }, + "observedGeneration": { + "format": "int64", + "minimum": 0, + "type": "integer" + }, + "reason": { + "type": "string" + }, + "status": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "status", + "type" + ], + "type": "object" + }, + "type": "array" + }, + "observedGeneration": { + "format": "int64", + "minimum": 0, + "type": "integer" + }, + "recommendation": { + "properties": { + "containerRecommendations": { + "items": { + "properties": { + "containerName": { + "type": "string" + }, + "lowerBound": { + "additionalProperties": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "x-kubernetes-int-or-string": true + }, + "type": "object" + }, + "target": { + "additionalProperties": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "x-kubernetes-int-or-string": true + }, + "type": "object" + }, + "uncappedTarget": { + "additionalProperties": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "x-kubernetes-int-or-string": true + }, + "type": "object" + }, + "upperBound": { + "additionalProperties": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "x-kubernetes-int-or-string": true + }, + "type": "object" + } + }, + "required": [ + "target" + ], + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "required": [ + "spec" + ], + "type": "object" +} diff --git a/schemas/autoscaling.k8s.io/verticalpodautoscaler_v1beta2.json b/schemas/autoscaling.k8s.io/verticalpodautoscaler_v1beta2.json new file mode 100644 index 0000000..e081d0f --- /dev/null +++ b/schemas/autoscaling.k8s.io/verticalpodautoscaler_v1beta2.json @@ -0,0 +1,224 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "apiVersion": { + "type": "string" + }, + "kind": { + "type": "string" + }, + "metadata": { + "type": "object" + }, + "spec": { + "properties": { + "resourcePolicy": { + "properties": { + "containerPolicies": { + "items": { + "properties": { + "containerName": { + "type": "string" + }, + "maxAllowed": { + "additionalProperties": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "x-kubernetes-int-or-string": true + }, + "type": "object" + }, + "minAllowed": { + "additionalProperties": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "x-kubernetes-int-or-string": true + }, + "type": "object" + }, + "mode": { + "enum": [ + "Auto", + "Off" + ], + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, + "targetRef": { + "properties": { + "apiVersion": { + "type": "string" + }, + "kind": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "required": [ + "kind", + "name" + ], + "type": "object", + "x-kubernetes-map-type": "atomic" + }, + "updatePolicy": { + "properties": { + "updateMode": { + "enum": [ + "Off", + "Initial", + "Recreate", + "Auto" + ], + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "targetRef" + ], + "type": "object" + }, + "status": { + "properties": { + "conditions": { + "items": { + "properties": { + "lastTransitionTime": { + "format": "date-time", + "type": "string" + }, + "message": { + "type": "string" + }, + "reason": { + "type": "string" + }, + "status": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "status", + "type" + ], + "type": "object" + }, + "type": "array" + }, + "recommendation": { + "properties": { + "containerRecommendations": { + "items": { + "properties": { + "containerName": { + "type": "string" + }, + "lowerBound": { + "additionalProperties": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "x-kubernetes-int-or-string": true + }, + "type": "object" + }, + "target": { + "additionalProperties": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "x-kubernetes-int-or-string": true + }, + "type": "object" + }, + "uncappedTarget": { + "additionalProperties": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "x-kubernetes-int-or-string": true + }, + "type": "object" + }, + "upperBound": { + "additionalProperties": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "x-kubernetes-int-or-string": true + }, + "type": "object" + } + }, + "required": [ + "target" + ], + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "required": [ + "spec" + ], + "type": "object" +} diff --git a/schemas/autoscaling.k8s.io/verticalpodautoscalercheckpoint_v1.json b/schemas/autoscaling.k8s.io/verticalpodautoscalercheckpoint_v1.json new file mode 100644 index 0000000..004dec6 --- /dev/null +++ b/schemas/autoscaling.k8s.io/verticalpodautoscalercheckpoint_v1.json @@ -0,0 +1,86 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "apiVersion": { + "type": "string" + }, + "kind": { + "type": "string" + }, + "metadata": { + "type": "object" + }, + "spec": { + "properties": { + "containerName": { + "type": "string" + }, + "vpaObjectName": { + "type": "string" + } + }, + "type": "object" + }, + "status": { + "properties": { + "cpuHistogram": { + "properties": { + "bucketWeights": { + "type": "object", + "x-kubernetes-preserve-unknown-fields": true + }, + "referenceTimestamp": { + "format": "date-time", + "nullable": true, + "type": "string" + }, + "totalWeight": { + "type": "number" + } + }, + "type": "object" + }, + "firstSampleStart": { + "format": "date-time", + "nullable": true, + "type": "string" + }, + "lastSampleStart": { + "format": "date-time", + "nullable": true, + "type": "string" + }, + "lastUpdateTime": { + "format": "date-time", + "nullable": true, + "type": "string" + }, + "memoryHistogram": { + "properties": { + "bucketWeights": { + "type": "object", + "x-kubernetes-preserve-unknown-fields": true + }, + "referenceTimestamp": { + "format": "date-time", + "nullable": true, + "type": "string" + }, + "totalWeight": { + "type": "number" + } + }, + "type": "object" + }, + "totalSamplesCount": { + "type": "integer" + }, + "version": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" +} diff --git a/schemas/autoscaling.k8s.io/verticalpodautoscalercheckpoint_v1beta2.json b/schemas/autoscaling.k8s.io/verticalpodautoscalercheckpoint_v1beta2.json new file mode 100644 index 0000000..004dec6 --- /dev/null +++ b/schemas/autoscaling.k8s.io/verticalpodautoscalercheckpoint_v1beta2.json @@ -0,0 +1,86 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "apiVersion": { + "type": "string" + }, + "kind": { + "type": "string" + }, + "metadata": { + "type": "object" + }, + "spec": { + "properties": { + "containerName": { + "type": "string" + }, + "vpaObjectName": { + "type": "string" + } + }, + "type": "object" + }, + "status": { + "properties": { + "cpuHistogram": { + "properties": { + "bucketWeights": { + "type": "object", + "x-kubernetes-preserve-unknown-fields": true + }, + "referenceTimestamp": { + "format": "date-time", + "nullable": true, + "type": "string" + }, + "totalWeight": { + "type": "number" + } + }, + "type": "object" + }, + "firstSampleStart": { + "format": "date-time", + "nullable": true, + "type": "string" + }, + "lastSampleStart": { + "format": "date-time", + "nullable": true, + "type": "string" + }, + "lastUpdateTime": { + "format": "date-time", + "nullable": true, + "type": "string" + }, + "memoryHistogram": { + "properties": { + "bucketWeights": { + "type": "object", + "x-kubernetes-preserve-unknown-fields": true + }, + "referenceTimestamp": { + "format": "date-time", + "nullable": true, + "type": "string" + }, + "totalWeight": { + "type": "number" + } + }, + "type": "object" + }, + "totalSamplesCount": { + "type": "integer" + }, + "version": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" +}