From 387683603990d172d4d28f0bb4bcf8c8e4937fa3 Mon Sep 17 00:00:00 2001 From: Alex Savanovich <40720931+savme@users.noreply.github.com> Date: Wed, 5 Aug 2026 13:32:39 +0200 Subject: [PATCH 1/2] feat: add prometheus-adapter metrics component --- .../components/prometheus-adapter/README.md | 29 +++++++ .../prometheus-adapter/apiservice.yaml | 18 ++++ .../components/prometheus-adapter/config.yaml | 48 +++++++++++ .../prometheus-adapter/deployment.yaml | 85 +++++++++++++++++++ .../prometheus-adapter/kustomization.yaml | 11 +++ .../components/prometheus-adapter/rbac.yaml | 72 ++++++++++++++++ .../prometheus-adapter/service.yaml | 16 ++++ .../prometheus-adapter/service_account.yaml | 8 ++ .../prometheus-adapter/serving-cert.yaml | 18 ++++ 9 files changed, 305 insertions(+) create mode 100644 config/components/prometheus-adapter/README.md create mode 100644 config/components/prometheus-adapter/apiservice.yaml create mode 100644 config/components/prometheus-adapter/config.yaml create mode 100644 config/components/prometheus-adapter/deployment.yaml create mode 100644 config/components/prometheus-adapter/kustomization.yaml create mode 100644 config/components/prometheus-adapter/rbac.yaml create mode 100644 config/components/prometheus-adapter/service.yaml create mode 100644 config/components/prometheus-adapter/service_account.yaml create mode 100644 config/components/prometheus-adapter/serving-cert.yaml diff --git a/config/components/prometheus-adapter/README.md b/config/components/prometheus-adapter/README.md new file mode 100644 index 00000000..63f41282 --- /dev/null +++ b/config/components/prometheus-adapter/README.md @@ -0,0 +1,29 @@ +# Prometheus Adapter Resource Metrics + +Experimental `metrics.k8s.io` implementation backed by Prometheus Adapter. +Enable only in clusters where Prometheus or VictoriaMetrics is the source of +truth for Pod and Node CPU/memory usage. + +This component owns the cluster-wide `v1beta1.metrics.k8s.io` APIService when +installed. Do not install it alongside another owner of the same APIService. + +The adapter expects resource metrics with cAdvisor-compatible names and labels: + +- `container_cpu_usage_seconds_total{namespace, pod, container, node}` +- `container_memory_working_set_bytes{namespace, pod, container, node}` + +Runtime-specific producers, such as Unikraft telemetry, should translate their +local measurements into that shape before ingestion. The adapter then exposes +those samples through the standard Kubernetes Resource Metrics API used by HPA. + +Infrastructure overlays must patch before enabling this component: + +- `PROMETHEUS_URL` should point at the local Prometheus or VictoriaMetrics query + endpoint. +- `Certificate.spec.issuerRef` should point at the cluster's serving certificate + issuer. The default value is a placeholder `ClusterIssuer` named + `placeholder-issuer`. +- The component defaults to `compute-system`. If an overlay deploys it in a + different namespace, patch the `Certificate.spec.dnsNames` and the + `APIService` service namespace / `cert-manager.io/inject-ca-from` annotation + in the consuming overlay. diff --git a/config/components/prometheus-adapter/apiservice.yaml b/config/components/prometheus-adapter/apiservice.yaml new file mode 100644 index 00000000..4341d8c2 --- /dev/null +++ b/config/components/prometheus-adapter/apiservice.yaml @@ -0,0 +1,18 @@ +apiVersion: apiregistration.k8s.io/v1 +kind: APIService +metadata: + name: v1beta1.metrics.k8s.io + labels: + app.kubernetes.io/name: compute-prometheus-adapter + app.kubernetes.io/part-of: compute + annotations: + cert-manager.io/inject-ca-from: compute-system/compute-prometheus-adapter-serving-cert +spec: + group: metrics.k8s.io + groupPriorityMinimum: 100 + service: + name: compute-prometheus-adapter + namespace: compute-system + port: 443 + version: v1beta1 + versionPriority: 100 diff --git a/config/components/prometheus-adapter/config.yaml b/config/components/prometheus-adapter/config.yaml new file mode 100644 index 00000000..6162692b --- /dev/null +++ b/config/components/prometheus-adapter/config.yaml @@ -0,0 +1,48 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: compute-prometheus-adapter-config + namespace: compute-system + labels: + app.kubernetes.io/name: compute-prometheus-adapter + app.kubernetes.io/part-of: compute +data: + config.yaml: | + resourceRules: + cpu: + containerQuery: | + sum by (<<.GroupBy>>) ( + rate(container_cpu_usage_seconds_total{<<.LabelMatchers>>,container!="",container!="POD"}[2m]) + ) + nodeQuery: | + sum by (<<.GroupBy>>) ( + rate(container_cpu_usage_seconds_total{<<.LabelMatchers>>,id="/"}[2m]) + ) + resources: + overrides: + namespace: + resource: namespace + pod: + resource: pod + node: + resource: node + containerLabel: container + memory: + containerQuery: | + sum by (<<.GroupBy>>) ( + container_memory_working_set_bytes{<<.LabelMatchers>>,container!="",container!="POD"} + ) + nodeQuery: | + sum by (<<.GroupBy>>) ( + container_memory_working_set_bytes{<<.LabelMatchers>>,id="/"} + ) + resources: + overrides: + namespace: + resource: namespace + pod: + resource: pod + node: + resource: node + containerLabel: container + window: 2m diff --git a/config/components/prometheus-adapter/deployment.yaml b/config/components/prometheus-adapter/deployment.yaml new file mode 100644 index 00000000..cb48899d --- /dev/null +++ b/config/components/prometheus-adapter/deployment.yaml @@ -0,0 +1,85 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: compute-prometheus-adapter + namespace: compute-system + labels: + app.kubernetes.io/name: compute-prometheus-adapter + app.kubernetes.io/part-of: compute +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: compute-prometheus-adapter + template: + metadata: + labels: + app.kubernetes.io/name: compute-prometheus-adapter + app.kubernetes.io/part-of: compute + spec: + serviceAccountName: compute-prometheus-adapter + securityContext: + runAsNonRoot: true + runAsUser: 65532 + runAsGroup: 65532 + seccompProfile: + type: RuntimeDefault + containers: + - name: adapter + image: registry.k8s.io/prometheus-adapter/prometheus-adapter:v0.12.0 + args: + - --secure-port=8443 + - --tls-cert-file=/certs/tls.crt + - --tls-private-key-file=/certs/tls.key + - --prometheus-url=$(PROMETHEUS_URL) + - --config=/etc/adapter/config.yaml + - --metrics-relist-interval=1m + - --metrics-max-age=2m + env: + - name: PROMETHEUS_URL + value: http://prometheus-operated.monitoring.svc:9090 + ports: + - containerPort: 8443 + name: https + protocol: TCP + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + livenessProbe: + httpGet: + path: /livez + port: 8443 + scheme: HTTPS + initialDelaySeconds: 15 + periodSeconds: 20 + readinessProbe: + httpGet: + path: /readyz + port: 8443 + scheme: HTTPS + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 10m + memory: 64Mi + volumeMounts: + - name: config + mountPath: /etc/adapter + readOnly: true + - name: serving-cert + mountPath: /certs + readOnly: true + volumes: + - name: config + configMap: + name: compute-prometheus-adapter-config + - name: serving-cert + secret: + secretName: compute-prometheus-adapter-serving-cert diff --git a/config/components/prometheus-adapter/kustomization.yaml b/config/components/prometheus-adapter/kustomization.yaml new file mode 100644 index 00000000..2970a04a --- /dev/null +++ b/config/components/prometheus-adapter/kustomization.yaml @@ -0,0 +1,11 @@ +apiVersion: kustomize.config.k8s.io/v1alpha1 +kind: Component + +resources: + - service_account.yaml + - rbac.yaml + - serving-cert.yaml + - config.yaml + - deployment.yaml + - service.yaml + - apiservice.yaml diff --git a/config/components/prometheus-adapter/rbac.yaml b/config/components/prometheus-adapter/rbac.yaml new file mode 100644 index 00000000..9879c6a2 --- /dev/null +++ b/config/components/prometheus-adapter/rbac.yaml @@ -0,0 +1,72 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: compute-prometheus-adapter-resource-reader + labels: + app.kubernetes.io/name: compute-prometheus-adapter + app.kubernetes.io/part-of: compute +rules: + - apiGroups: [""] + resources: [nodes, pods, namespaces] + verbs: [get, list, watch] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: compute-prometheus-adapter-resource-reader + labels: + app.kubernetes.io/name: compute-prometheus-adapter + app.kubernetes.io/part-of: compute +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: compute-prometheus-adapter-resource-reader +subjects: + - kind: ServiceAccount + name: compute-prometheus-adapter + namespace: compute-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: compute-prometheus-adapter-auth-delegator + labels: + app.kubernetes.io/name: compute-prometheus-adapter + app.kubernetes.io/part-of: compute +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:auth-delegator +subjects: + - kind: ServiceAccount + name: compute-prometheus-adapter + namespace: compute-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: compute-prometheus-adapter-authentication-reader + labels: + app.kubernetes.io/name: compute-prometheus-adapter + app.kubernetes.io/part-of: compute +rules: + - apiGroups: [""] + resources: [configmaps] + resourceNames: [extension-apiserver-authentication] + verbs: [get] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: compute-prometheus-adapter-authentication-reader + labels: + app.kubernetes.io/name: compute-prometheus-adapter + app.kubernetes.io/part-of: compute +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: compute-prometheus-adapter-authentication-reader +subjects: + - kind: ServiceAccount + name: compute-prometheus-adapter + namespace: compute-system diff --git a/config/components/prometheus-adapter/service.yaml b/config/components/prometheus-adapter/service.yaml new file mode 100644 index 00000000..e2a4817c --- /dev/null +++ b/config/components/prometheus-adapter/service.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Service +metadata: + name: compute-prometheus-adapter + namespace: compute-system + labels: + app.kubernetes.io/name: compute-prometheus-adapter + app.kubernetes.io/part-of: compute +spec: + selector: + app.kubernetes.io/name: compute-prometheus-adapter + ports: + - name: https + port: 443 + protocol: TCP + targetPort: https diff --git a/config/components/prometheus-adapter/service_account.yaml b/config/components/prometheus-adapter/service_account.yaml new file mode 100644 index 00000000..3879c733 --- /dev/null +++ b/config/components/prometheus-adapter/service_account.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: compute-prometheus-adapter + namespace: compute-system + labels: + app.kubernetes.io/name: compute-prometheus-adapter + app.kubernetes.io/part-of: compute diff --git a/config/components/prometheus-adapter/serving-cert.yaml b/config/components/prometheus-adapter/serving-cert.yaml new file mode 100644 index 00000000..4c5de321 --- /dev/null +++ b/config/components/prometheus-adapter/serving-cert.yaml @@ -0,0 +1,18 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: compute-prometheus-adapter-serving-cert + namespace: compute-system + labels: + app.kubernetes.io/name: compute-prometheus-adapter + app.kubernetes.io/part-of: compute +spec: + dnsNames: + - compute-prometheus-adapter.compute-system.svc + - compute-prometheus-adapter.compute-system.svc.cluster.local + issuerRef: + # Placeholder. Infra overlays must patch this issuer. + group: cert-manager.io + kind: ClusterIssuer + name: placeholder-issuer + secretName: compute-prometheus-adapter-serving-cert From 2d1c25283d8f7d624a8aa4a32470130cd4c4e254 Mon Sep 17 00:00:00 2001 From: Alex Savanovich <40720931+savme@users.noreply.github.com> Date: Wed, 5 Aug 2026 16:10:26 +0200 Subject: [PATCH 2/2] feat: change metric naming to datum_compute_* --- config/components/prometheus-adapter/README.md | 7 ++++--- config/components/prometheus-adapter/config.yaml | 8 ++++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/config/components/prometheus-adapter/README.md b/config/components/prometheus-adapter/README.md index 63f41282..0104fd5b 100644 --- a/config/components/prometheus-adapter/README.md +++ b/config/components/prometheus-adapter/README.md @@ -7,10 +7,11 @@ truth for Pod and Node CPU/memory usage. This component owns the cluster-wide `v1beta1.metrics.k8s.io` APIService when installed. Do not install it alongside another owner of the same APIService. -The adapter expects resource metrics with cAdvisor-compatible names and labels: +The adapter expects Datum instance resource metrics with Kubernetes identity +labels: -- `container_cpu_usage_seconds_total{namespace, pod, container, node}` -- `container_memory_working_set_bytes{namespace, pod, container, node}` +- `datum_compute_instance_cpu_usage_seconds_total{namespace, pod, container, node}` +- `datum_compute_instance_memory_working_set_bytes{namespace, pod, container, node}` Runtime-specific producers, such as Unikraft telemetry, should translate their local measurements into that shape before ingestion. The adapter then exposes diff --git a/config/components/prometheus-adapter/config.yaml b/config/components/prometheus-adapter/config.yaml index 6162692b..300266e3 100644 --- a/config/components/prometheus-adapter/config.yaml +++ b/config/components/prometheus-adapter/config.yaml @@ -12,11 +12,11 @@ data: cpu: containerQuery: | sum by (<<.GroupBy>>) ( - rate(container_cpu_usage_seconds_total{<<.LabelMatchers>>,container!="",container!="POD"}[2m]) + rate(datum_compute_instance_cpu_usage_seconds_total{<<.LabelMatchers>>,container!=""}[2m]) ) nodeQuery: | sum by (<<.GroupBy>>) ( - rate(container_cpu_usage_seconds_total{<<.LabelMatchers>>,id="/"}[2m]) + rate(datum_compute_instance_cpu_usage_seconds_total{<<.LabelMatchers>>}[2m]) ) resources: overrides: @@ -30,11 +30,11 @@ data: memory: containerQuery: | sum by (<<.GroupBy>>) ( - container_memory_working_set_bytes{<<.LabelMatchers>>,container!="",container!="POD"} + datum_compute_instance_memory_working_set_bytes{<<.LabelMatchers>>,container!=""} ) nodeQuery: | sum by (<<.GroupBy>>) ( - container_memory_working_set_bytes{<<.LabelMatchers>>,id="/"} + datum_compute_instance_memory_working_set_bytes{<<.LabelMatchers>>} ) resources: overrides: