Skip to content

Commit 51246b1

Browse files
committed
feat: significantly reduce the number of watches to the Kubernetes API
We now set up only up to 9 watches/informers with the Kubernetes API for the whole cluster instead of up to 9 watches per namespace. For really large clusters this is a great improvement - instead of setting thousands of watches, we only set up to 9, regardless of the cluster size.
1 parent 677998c commit 51246b1

File tree

15 files changed

+482
-94
lines changed

15 files changed

+482
-94
lines changed

src/supervisor/watchers/handlers/cron-job.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { WorkloadKind } from '../../types';
99
import { FALSY_WORKLOAD_NAME_MARKER } from './types';
1010
import { IncomingMessage } from 'http';
1111
import { k8sApi } from '../../cluster';
12-
import { paginatedNamespacedList } from './pagination';
12+
import { paginatedClusterList, paginatedNamespacedList } from './pagination';
1313
import {
1414
deleteWorkloadAlreadyScanned,
1515
deleteWorkloadImagesAlreadyScanned,
@@ -34,6 +34,21 @@ export async function paginatedNamespacedCronJobList(
3434
);
3535
}
3636

37+
export async function paginatedClusterCronJobList(): Promise<{
38+
response: IncomingMessage;
39+
body: V1CronJobList;
40+
}> {
41+
const v1CronJobList = new V1CronJobList();
42+
v1CronJobList.apiVersion = 'batch/v1';
43+
v1CronJobList.kind = 'CronJobList';
44+
v1CronJobList.items = new Array<V1CronJob>();
45+
46+
return await paginatedClusterList(
47+
v1CronJobList,
48+
k8sApi.batchClient.listCronJobForAllNamespaces.bind(k8sApi.batchClient),
49+
);
50+
}
51+
3752
export async function paginatedNamespacedCronJobV1Beta1List(
3853
namespace: string,
3954
): Promise<{
@@ -54,6 +69,23 @@ export async function paginatedNamespacedCronJobV1Beta1List(
5469
);
5570
}
5671

72+
export async function paginatedClusterCronJobV1Beta1List(): Promise<{
73+
response: IncomingMessage;
74+
body: V1beta1CronJobList;
75+
}> {
76+
const cronJobList = new V1beta1CronJobList();
77+
cronJobList.apiVersion = 'batch/v1beta1';
78+
cronJobList.kind = 'CronJobList';
79+
cronJobList.items = new Array<V1beta1CronJob>();
80+
81+
return await paginatedClusterList(
82+
cronJobList,
83+
k8sApi.batchUnstableClient.listCronJobForAllNamespaces.bind(
84+
k8sApi.batchUnstableClient,
85+
),
86+
);
87+
}
88+
5789
export async function cronJobWatchHandler(
5890
cronJob: V1CronJob | V1beta1CronJob,
5991
): Promise<void> {

src/supervisor/watchers/handlers/daemon-set.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { WorkloadKind } from '../../types';
44
import { FALSY_WORKLOAD_NAME_MARKER } from './types';
55
import { IncomingMessage } from 'http';
66
import { k8sApi } from '../../cluster';
7-
import { paginatedNamespacedList } from './pagination';
7+
import { paginatedClusterList, paginatedNamespacedList } from './pagination';
88
import {
99
deleteWorkloadAlreadyScanned,
1010
deleteWorkloadImagesAlreadyScanned,
@@ -29,6 +29,21 @@ export async function paginatedNamespacedDaemonSetList(
2929
);
3030
}
3131

32+
export async function paginatedClusterDaemonSetList(): Promise<{
33+
response: IncomingMessage;
34+
body: V1DaemonSetList;
35+
}> {
36+
const v1DaemonSetList = new V1DaemonSetList();
37+
v1DaemonSetList.apiVersion = 'apps/v1';
38+
v1DaemonSetList.kind = 'DaemonSetList';
39+
v1DaemonSetList.items = new Array<V1DaemonSet>();
40+
41+
return await paginatedClusterList(
42+
v1DaemonSetList,
43+
k8sApi.appsClient.listDaemonSetForAllNamespaces.bind(k8sApi.appsClient),
44+
);
45+
}
46+
3247
export async function daemonSetWatchHandler(
3348
daemonSet: V1DaemonSet,
3449
): Promise<void> {

src/supervisor/watchers/handlers/deployment-config.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
V1DeploymentConfig,
77
V1DeploymentConfigList,
88
} from './types';
9-
import { paginatedNamespacedList } from './pagination';
9+
import { paginatedClusterList, paginatedNamespacedList } from './pagination';
1010
import { k8sApi } from '../../cluster';
1111
import {
1212
deleteWorkloadAlreadyScanned,
@@ -51,6 +51,38 @@ export async function paginatedNamespacedDeploymentConfigList(
5151
);
5252
}
5353

54+
export async function paginatedClusterDeploymentConfigList(): Promise<{
55+
response: IncomingMessage;
56+
body: V1DeploymentConfigList;
57+
}> {
58+
const v1DeploymentConfigList = new V1DeploymentConfigList();
59+
v1DeploymentConfigList.apiVersion = 'apps.openshift.io/v1';
60+
v1DeploymentConfigList.kind = 'DeploymentConfigList';
61+
v1DeploymentConfigList.items = new Array<V1DeploymentConfig>();
62+
63+
return await paginatedClusterList(
64+
v1DeploymentConfigList,
65+
async (
66+
_allowWatchBookmarks?: boolean,
67+
_continue?: string,
68+
fieldSelector?: string,
69+
labelSelector?: string,
70+
limit?: number,
71+
pretty?: string,
72+
) =>
73+
k8sApi.customObjectsClient.listClusterCustomObject(
74+
'apps.openshift.io',
75+
'v1',
76+
'deploymentconfigs',
77+
pretty,
78+
_continue,
79+
fieldSelector,
80+
labelSelector,
81+
limit,
82+
) as any,
83+
);
84+
}
85+
5486
export async function deploymentConfigWatchHandler(
5587
deploymentConfig: V1DeploymentConfig,
5688
): Promise<void> {

src/supervisor/watchers/handlers/deployment.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { WorkloadKind } from '../../types';
44
import { FALSY_WORKLOAD_NAME_MARKER } from './types';
55
import { IncomingMessage } from 'http';
66
import { k8sApi } from '../../cluster';
7-
import { paginatedNamespacedList } from './pagination';
7+
import { paginatedClusterList, paginatedNamespacedList } from './pagination';
88
import {
99
deleteWorkloadAlreadyScanned,
1010
deleteWorkloadImagesAlreadyScanned,
@@ -22,15 +22,28 @@ export async function paginatedNamespacedDeploymentList(
2222
v1DeploymentList.kind = 'DeploymentList';
2323
v1DeploymentList.items = new Array<V1Deployment>();
2424

25-
k8sApi.appsClient.listDeploymentForAllNamespaces();
26-
2725
return await paginatedNamespacedList(
2826
namespace,
2927
v1DeploymentList,
3028
k8sApi.appsClient.listNamespacedDeployment.bind(k8sApi.appsClient),
3129
);
3230
}
3331

32+
export async function paginatedClusterDeploymentList(): Promise<{
33+
response: IncomingMessage;
34+
body: V1DeploymentList;
35+
}> {
36+
const v1DeploymentList = new V1DeploymentList();
37+
v1DeploymentList.apiVersion = 'apps/v1';
38+
v1DeploymentList.kind = 'DeploymentList';
39+
v1DeploymentList.items = new Array<V1Deployment>();
40+
41+
return await paginatedClusterList(
42+
v1DeploymentList,
43+
k8sApi.appsClient.listDeploymentForAllNamespaces.bind(k8sApi.appsClient),
44+
);
45+
}
46+
3447
export async function deploymentWatchHandler(
3548
deployment: V1Deployment,
3649
): Promise<void> {

0 commit comments

Comments
 (0)