Fetch only the required podMetrics for the given component (#17489)
The `PodMetrics` are now limited by `labelSelector` like already done for pods and probably other requests to Kubernetes. This limits the amount of data that is fetched. Tested locally by modifying `app-config.yaml` and an example component to use an internal cluster, which leads to the following request size improvements: Before: 344.71 kB compressed, 6.89 MB uncompressed After: 12.01 kB compressed, 238.86 kB uncompressed For the POST http://localhost:7007/api/kubernetes/services/playback-order call, in a Kubernetes cluster with ~500 pods. Fixes #17450. Signed-off-by: Luna Stadler <luc@spreadshirt.net>
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
---
|
||||
'@backstage/plugin-kubernetes-backend': minor
|
||||
---
|
||||
|
||||
Allow fetching pod metrics limited by a `labelSelector`.
|
||||
|
||||
This is used by the Kubernetes tab on a components' page and leads to much smaller responses being received from Kubernetes, especially with larger Kubernetes clusters.
|
||||
@@ -918,7 +918,7 @@ describe('getKubernetesObjectsByEntity', () => {
|
||||
{
|
||||
errorType: 'FETCH_ERROR',
|
||||
message:
|
||||
'request to https://fails/api/v1/pods?labelSelector=backstage.io/kubernetes-id=test-component failed, reason: socket error',
|
||||
'request to https://fails/api/v1/pods?labelSelector=backstage.io%2Fkubernetes-id%3Dtest-component failed, reason: socket error',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -283,7 +283,9 @@ export class KubernetesFanOutHandler {
|
||||
})),
|
||||
namespace,
|
||||
})
|
||||
.then(result => this.getMetricsForPods(clusterDetailsItem, result))
|
||||
.then(result =>
|
||||
this.getMetricsForPods(clusterDetailsItem, labelSelector, result),
|
||||
)
|
||||
.catch(
|
||||
(e): Promise<responseWithMetrics> =>
|
||||
e.name === 'FetchError'
|
||||
@@ -365,6 +367,7 @@ export class KubernetesFanOutHandler {
|
||||
|
||||
async getMetricsForPods(
|
||||
clusterDetails: ClusterDetails,
|
||||
labelSelector: string,
|
||||
result: FetchResponseWrapper,
|
||||
): Promise<responseWithMetrics> {
|
||||
if (clusterDetails.skipMetricsLookup) {
|
||||
@@ -385,6 +388,7 @@ export class KubernetesFanOutHandler {
|
||||
const podMetrics = await this.fetcher.fetchPodMetricsByNamespaces(
|
||||
clusterDetails,
|
||||
namespaces,
|
||||
labelSelector,
|
||||
);
|
||||
|
||||
result.errors.push(...podMetrics.errors);
|
||||
|
||||
@@ -119,6 +119,7 @@ export class KubernetesClientBasedFetcher implements KubernetesFetcher {
|
||||
fetchPodMetricsByNamespaces(
|
||||
clusterDetails: ClusterDetails,
|
||||
namespaces: Set<string>,
|
||||
labelSelector?: string,
|
||||
): Promise<FetchResponseWrapper> {
|
||||
const fetchResults = Array.from(namespaces).map(async ns => {
|
||||
const [podMetrics, podList] = await Promise.all([
|
||||
@@ -128,8 +129,9 @@ export class KubernetesClientBasedFetcher implements KubernetesFetcher {
|
||||
'v1beta1',
|
||||
'pods',
|
||||
ns,
|
||||
labelSelector,
|
||||
),
|
||||
this.fetchResource(clusterDetails, '', 'v1', 'pods', ns),
|
||||
this.fetchResource(clusterDetails, '', 'v1', 'pods', ns, labelSelector),
|
||||
]);
|
||||
if (podMetrics.ok && podList.ok) {
|
||||
return topPods(
|
||||
@@ -213,7 +215,7 @@ export class KubernetesClientBasedFetcher implements KubernetesFetcher {
|
||||
}
|
||||
|
||||
if (labelSelector) {
|
||||
url.search = `labelSelector=${labelSelector}`;
|
||||
url.search = `labelSelector=${encode(labelSelector)}`;
|
||||
}
|
||||
|
||||
return fetch(url, requestInit);
|
||||
|
||||
@@ -56,6 +56,7 @@ export interface KubernetesFetcher {
|
||||
fetchPodMetricsByNamespaces(
|
||||
clusterDetails: ClusterDetails,
|
||||
namespaces: Set<string>,
|
||||
labelSelector?: string,
|
||||
): Promise<FetchResponseWrapper>;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user