Skip to content

Commit 07dc652

Browse files
authored
Merge pull request #5975 from bcgov/feat/5934
feat(5879): investigate retrieval of cluster-level resource status on…
2 parents 7adde34 + 65ffeb6 commit 07dc652

File tree

2 files changed

+107
-1
lines changed

2 files changed

+107
-1
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { z } from 'zod';
2+
import { GlobalRole } from '@/constants';
3+
import createApiHandler from '@/core/api-handler';
4+
import { OkResponse } from '@/core/responses';
5+
import { Cluster } from '@/prisma/client';
6+
import { queryCapacity, queryAllocatable, queryCpuRequests, queryCpuUsage } from '@/services/k8s/metrics/core';
7+
8+
const queryParamSchema = z.object({
9+
cluster: z.nativeEnum(Cluster),
10+
});
11+
12+
export const GET = createApiHandler({
13+
roles: [GlobalRole.Admin],
14+
useServiceAccount: true,
15+
validations: { queryParams: queryParamSchema },
16+
})(async ({ queryParams }) => {
17+
const { cluster } = queryParams;
18+
19+
// See https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/nodes/nodes-dashboard-using
20+
const [capacityRes, allocatableRes, requestsRes, usageRes] = await Promise.all([
21+
queryCapacity(cluster),
22+
queryAllocatable(cluster),
23+
queryCpuRequests(cluster),
24+
queryCpuUsage(cluster),
25+
]);
26+
27+
const capacity = Number(capacityRes[0]?.value[1] || 0);
28+
const allocatable = Number(allocatableRes[0]?.value[1] || 0);
29+
const requests = Number(requestsRes[0]?.value[1] || 0);
30+
const usage = Number(usageRes[0]?.value[1] || 0);
31+
32+
// | Term | Meaning |
33+
// | --------------- | ------------------------------------------------------------------ |
34+
// | **Capacity** | The full amount of a resource on the node (e.g., total CPU/memory) |
35+
// | **Allocatable** | The portion of that resource Kubernetes allows for pod scheduling |
36+
// | **Requests** | The amount of resource that pods ask for |
37+
// | **Usage** | The actual usage by running containers |
38+
return OkResponse({
39+
capacity,
40+
allocatable,
41+
requests,
42+
usage,
43+
requestUtilization: (requests / allocatable) * 100,
44+
usageEfficiency: (usage / requests) * 100,
45+
});
46+
});

app/services/k8s/metrics/core.ts

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,68 @@ export async function queryPrometheus(query: string, cluster: Cluster) {
4444

4545
const response = await axios.get<PrometheusQueryResponse>(`${METRICS_URL}/api/v1/query`, {
4646
headers: { Authorization: `Bearer ${METRICS_TOKEN}` },
47-
params: { query },
47+
params: { query: query.trim() },
4848
});
4949

5050
return response.data.data.result;
5151
}
52+
53+
export function queryCapacity(cluster: Cluster) {
54+
return queryPrometheus(
55+
`
56+
sum
57+
(
58+
kube_node_status_capacity{resource="cpu", unit="core"}
59+
and on(node) kube_node_role{role="worker"}
60+
)
61+
`,
62+
cluster,
63+
);
64+
}
65+
66+
export function queryAllocatable(cluster: Cluster) {
67+
return queryPrometheus(
68+
`
69+
sum
70+
(
71+
kube_node_status_allocatable{resource="cpu", unit="core"}
72+
and on(node) kube_node_role{role="worker"}
73+
)
74+
`,
75+
cluster,
76+
);
77+
}
78+
79+
export function queryCpuRequests(cluster: Cluster) {
80+
return queryPrometheus(
81+
`
82+
sum
83+
(
84+
(
85+
kube_pod_container_resource_requests{resource="cpu", unit="core"}
86+
* on(namespace, pod) group_left()
87+
max(kube_pod_status_phase{phase=~"Running|Pending"} == 1) by (namespace, pod)
88+
)
89+
and on(node) kube_node_role{role="worker"}
90+
)
91+
`,
92+
cluster,
93+
);
94+
}
95+
96+
export function queryCpuUsage(cluster: Cluster) {
97+
return queryPrometheus(
98+
`
99+
sum
100+
(
101+
(
102+
rate(container_cpu_usage_seconds_total{container!="", image!=""}[5m])
103+
* on(namespace, pod) group_left()
104+
max(kube_pod_status_phase{phase=~"Running|Pending"} == 1) by (namespace, pod)
105+
)
106+
and on(node) kube_node_role{role="worker"}
107+
)
108+
`,
109+
cluster,
110+
);
111+
}

0 commit comments

Comments
 (0)