Skip to content

ROX-28976: Optimize berserker load in long running cluster - #64

Merged
JoukoVirtanen merged 16 commits into
mainfrom
jv-ROX-28976-optimize-berserker-load-in-long-running-cluster
Oct 6, 2025
Merged

ROX-28976: Optimize berserker load in long running cluster#64
JoukoVirtanen merged 16 commits into
mainfrom
jv-ROX-28976-optimize-berserker-load-in-long-running-cluster

Conversation

@JoukoVirtanen

@JoukoVirtanenJoukoVirtanen commented Sep 5, 2025

Copy link
Copy Markdown
Contributor

Recently there were changes to the berserker load for the long running cluster. One of the changes was an increase in the number of berserker pods. Currently Prometheus scrapes metrics on all of the pods in the long running cluster including berserker pods. With the increased number of berserker pods, Prometheus began to OOM. To fix this Prometheus is switched to a different config that filters out some, but not all of the metrics for berserker pods. The memory requests and limits are also increased.

The changes to the berserker load is already merged and was used for testing this PR. stackrox/stackrox#15886

Changes were made here after testing the above PR. A new tag, 0.0.51, was created based off of a recent master, and was used to test the changes here.

@JoukoVirtanen
JoukoVirtanen requested a review from a team as a code ownerSeptember 5, 2025 15:07
@JoukoVirtanen
JoukoVirtanen marked this pull request as draft September 13, 2025 18:28
@JoukoVirtanenJoukoVirtanen changed the title Jv rox 28976 optimize berserker load in long running clusterROX-28976: Optimize berserker load in long running clusterSep 29, 2025
@JoukoVirtanen
JoukoVirtanen marked this pull request as ready for review September 29, 2025 04:39
"name": "prometheus",
"resources": {
"requests": {
"memory": "2Gi",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about we request 8Gi to prevent OOMKills because the node runs out of memory, if it is overcommitted?

If you change this here, please verify in another long-running cluster that Prometheus is starting (as I am unsure if there are 8Gi available on each node with ACS' requirements too).

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

tommartensen
tommartensen previously requested changes Sep 29, 2025

# Replace the prometheus ConfigMap with one that doesn't scrape as much info from berserker containers
kubectl -n stackrox delete configmap prometheus
kubectl create -f "${SCRIPT_DIR}"/prometheus.yaml

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer if we can override the offending values in the monitoring chart. Can you check if that is possible? Same with the update to the monitoring deploment.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean you want me to make the changes in stackrox/stackrox? I feel like 8Gi is too much for every case that the monitoring pod is used. I could make the changes to prometheus.yaml in stackrox/stackrox, but didn't want to pollute it with references to berserker.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I now use yq to set memory limit and request to 8Gi.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would simply copy the ../charts/monitoring/values.yaml and create a berserker-values.yaml to later use it directly, but the approach with yq is okay for me.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tommartensen Requested the use of yq in a private conversation and it is okay with me too.

@JoukoVirtanen
JoukoVirtanenforce-pushed the jv-ROX-28976-optimize-berserker-load-in-long-running-cluster branch from 7d3f49d to 04a2cb7CompareSeptember 30, 2025 04:37
@JoukoVirtanen
JoukoVirtanen requested review from tommartensen and vikin91 and removed request for vikin91October 1, 2025 03:00
sed '/captureStart/d' "${KUBE_BURNER_METRICS_FILE}" > "$temp_metrics_file"
kubectl create configmap --from-file="$temp_metrics_file" kube-burner-metrics-config -n kube-burner

kubectl create configmap --from-file="$KUBE_BURNER_METRICS_FILE" kube-burner-metrics-config -n kube-burner

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we don't need that anymore?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We didn't need it in the first place. It is redundant with the line above it.

@tommartensen

Copy link
Copy Markdown
Collaborator

I believe we're running in circles here and on Slack, so here is my (untested) counterproposal:

What I would like to avoid is duplicating much of the Prometheus config (it might change) and have changes to the configuration obscured. I believe that it is cleaner to use the Helm built-in capabilities for overrides than to update values files with yq or deleting and re-creating Configmaps outside of the Helm cycle.

@JoukoVirtanen

JoukoVirtanen commented Oct 2, 2025

Copy link
Copy Markdown
ContributorAuthor

I believe we're running in circles here and on Slack, so here is my (untested) counterproposal:

What I would like to avoid is duplicating much of the Prometheus config (it might change) and have changes to the configuration obscured. I believe that it is cleaner to use the Helm built-in capabilities for overrides than to update values files with yq or deleting and re-creating Configmaps outside of the Helm cycle.

Thank you for putting together this counter proposal. I really like it when reviewers make the effort to create new branches and PRs. However, I think there might be a flaw in your proposal. Your proposal requires changes in both stackrox/stackrox and here. The problem with that is sometimes long running clusters are created for the release branches. If we go with your approach we would also need backports for the release branches in stackrox/stackrox, otherwise the code here would be incompatible with the helm charts for the monitoring deployment in stackrox/stackrox. Perhaps we can merge this as is and create a ticket to go with your approach. I will test your approach and let you know how it goes.

@tommartensen

tommartensen commented Oct 2, 2025

Copy link
Copy Markdown
Collaborator

Your proposal requires changes in both stackrox/stackrox and here.

I think that is a fundamental flaw in how this berserker thing is setup and should be addressed separately.

The problem with that is sometimes long running clusters are created for the release branches.

That shouldn't happen, can you point me to instances where this led to a problem?

Perhaps we can merge this as is and create a ticket to go with your approach.

I will be out-of-office in the next days. Please create a ticket to follow-up on this PR with the values improvements in ROX-10657 and work with someone in @stackrox/release-improvers to get this PR merged.

@JoukoVirtanen

JoukoVirtanen commented Oct 2, 2025

Copy link
Copy Markdown
ContributorAuthor

Your proposal requires changes in both stackrox/stackrox and here.

I think that is a fundamental flaw in how this berserker thing is setup and should be addressed separately.

I agree. I am not sure what the solution is. Though, I have a mini design proposal with some ideas on preventing breaking changes to the long running cluster https://docs.google.com/document/d/1Vfq1piBebKwAE9EvjNdb7P_TTO1kAgZvCzcPTqx-Nvg/edit?usp=sharing

It hasn't gotten much attention and hasn't gone anywhere.

The problem with that is sometimes long running clusters are created for the release branches.

That shouldn't happen, can you point me to instances where this led to a problem?

Sometimes long running clusters are needed for patch releases. In one case there was a release that had a memory leak which was fixed in a patch. The long running cluster was helpful with that.

One case in which problems occurred for patch releases was when metrics were sent to OpenSearch. There were changes in stackrox/stackrox that had to be made to get to work. Initially changes were made in stackrox/actions to detect what version of stackrox/stackrox was using and use different scripts based off of that. An old script was used for old release branches and a new script was for the current release. The changes to stackrox/stackrox were backported to older release branches. In the time between when the backports were merged and the logic of which script to use in stackrox/actions was updated, a long running cluster for an old release branch was created. That long running cluster failed. stackrox/actions had to be updated and then another long running cluster was successfully created for the patch release.

Perhaps we can merge this as is and create a ticket to go with your approach.

I will be out-of-office in the next days. Please create a ticket to follow-up on this PR with the values improvements in ROX-10657 and work with someone in @stackrox/release-improvers to get this PR merged.

I have created the following ticket https://issues.redhat.com/browse/ROX-31149

@JoukoVirtanen

Copy link
Copy Markdown
ContributorAuthor

@tommartensen I have tested your PRs. It didn't work. I think your idea is sound. There might just be some small mistake somewhere. I ran the following test.

I created a branch from stackrox/stackrox#17105 and tagged it 0.0.52. I then created a new branch in stackrox/test-gh-actions. In that branch I changed the refs in .github/workflows/create-clusters.yml to tm/override-helm-values-berserker. I then created a new long running cluster at https://github.com/stackrox/test-gh-actions/actions/workflows/create-clusters.yml with the branch set to the one I created in stackrox/test-gh-actions and the version set to 0.0.52. When I checked the long running cluster the monitoring pod was in a crash loop. I checked the logs and found the following

$ ks logs monitoring-5b657c9fc5-6kstf -c prometheus
ts=2025-10-03T03:30:11.087Z caller=main.go:438 level=error msg="Error loading config (--config.file=/etc/prometheus/prometheus.yml)" file=/etc/prometheus/prometheus.yml err="parsing YAML file /etc/prometheus/prometheus.yml: yaml: unmarshal errors:\n line 14: cannot unmarshal !!str `- job_n...` into []*config.ScrapeConfig"

The Prometheus ConfigMap had the following

$ ks get configmap prometheus -o yaml
apiVersion: v1
data:
prometheus.yml: "global:\n scrape_interval: 30s\n\nalerting:\n alertmanagers:\n
\ - static_configs:\n - targets:\n - stackrox-monitoring-alertmanager:9093\n\nrule_files:\n
\ - /etc/prometheus/rules_*.yml\n\nscrape_configs:\n |-\n - job_name: \"kubernetes-pods\"\n
\ tls_config:\n insecure_skip_verify: false\n kubernetes_sd_configs:\n
\ - role: pod\n namespaces:\n own_namespace: true\n
\ relabel_configs:\n - action: labelmap\n regex: __meta_kubernetes_pod_label_(.+)\n
\ - source_labels: [__meta_kubernetes_namespace]\n action: replace\n
\ target_label: namespace\n - source_labels: [__meta_kubernetes_pod_name]\n
\ action: replace\n target_label: pod\n - source_labels:
[__meta_kubernetes_pod_node_name]\n action: replace\n target_label:
node_name\n \n - job_name: \"kubernetes-cadvisor\"\n scheme: https\n
\ metrics_path: /metrics/cadvisor\n tls_config:\n ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt\n
\ insecure_skip_verify: true\n authorization:\n credentials_file:
/var/run/secrets/kubernetes.io/serviceaccount/token\n kubernetes_sd_configs:\n
\ - role: node\n relabel_configs:\n - action: labelmap\n regex:
__meta_kubernetes_node_label_(.+)\n \n - job_name: stackrox\n tls_config:\n
\ insecure_skip_verify: false\n kubernetes_sd_configs:\n - role:
endpoints\n namespaces:\n own_namespace: true\n relabel_configs:\n
\ - source_labels: [__meta_kubernetes_endpoint_port_name]\n action:
keep\n regex: monitoring\n - source_labels: [__meta_kubernetes_endpoints_name]\n
\ action: replace\n target_label: job\n - source_labels:
[__meta_kubernetes_namespace]\n action: replace\n target_label:
namespace\n - source_labels: [__meta_kubernetes_endpoint_node_name]\n action:
replace\n target_label: node_name"
rules_custom.yml: |-
|-
groups:
- name: Kubernetes
rules:
- alert: KubernetesContainerOomKiller
expr: (kube_pod_container_status_restarts_total - kube_pod_container_status_restarts_total offset 10m >= 1) and ignoring (reason) min_over_time(kube_pod_container_status_last_terminated_reason{reason="OOMKilled"}[10m]) == 1
for: 0m
labels:
severity: warning
annotations:
summary: Kubernetes container OOM killer (pod {{ "{{" }} .exported_pod {{ "}}" }})
description: "Container {{ "{{" }} .container {{ "}}" }} in pod {{ "{{" }} .exported_namespace {{ "}}" }}/{{ "{{" }} .exported_pod {{ "}}" }} has been OOMKilled {{ "{{" }} {{ "}}" }} times in the last 10 minutes."
- alert: KubernetesPodCrashLooping
expr: increase(kube_pod_container_status_restarts_total[5m]) > 0
for: 2m
labels:
severity: warning
annotations:
summary: Kubernetes pod crash looping (pod {{ "{{" }} .exported_pod {{ "}}" }})
description: "Pod {{ "{{" }} .exported_namespace {{ "}}" }}/{{ "{{" }} .exported_pod {{ "}}" }} is crash looping."
- alert: KubernetesReplicaSetMismatch
expr: kube_replicaset_spec_replicas != kube_replicaset_status_ready_replicas
for: 10m
labels:
severity: warning
annotations:
summary: Kubernetes ReplicaSet mismatch (replicaset {{ "{{" }} .replicaset {{ "}}" }})
description: "Replicas mismatch in ReplicaSet {{ "{{" }} .exported_namespace {{ "}}" }}/{{ "{{" }} .replicaset {{ "}}" }}"
kind: ConfigMap
metadata:
annotations:
meta.helm.sh/release-name: stackrox-monitoring
meta.helm.sh/release-namespace: stackrox
creationTimestamp: "2025-10-03T00:00:19Z"
labels:
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: stackrox
name: prometheus
namespace: stackrox
resourceVersion: "1759449619961263014"
uid: e2acf091-fe60-4ba3-9c91-b49dc5096827

@vikin91vikin91 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes look good!

I tried testing this branch with stackrox/stackrox#17146 but in the action execution, I saw that the code from the actions repository is hardcoded to main:

Download action repository 'stackrox/actions@main' (SHA:cc8a9579ba6de41d3b77b32403bf0f5e8809649d)

See: https://github.com/stackrox/stackrox/actions/runs/18283349491/job/52051757197

I will give you then a token of trust in regard that this has been tested and works correctly.

@JoukoVirtanen

Copy link
Copy Markdown
ContributorAuthor

The changes look good!

I tried testing this branch with stackrox/stackrox#17146 but in the action execution, I saw that the code from the actions repository is hardcoded to main:

Download action repository 'stackrox/actions@main' (SHA:cc8a9579ba6de41d3b77b32403bf0f5e8809649d)

See: https://github.com/stackrox/stackrox/actions/runs/18283349491/job/52051757197

I will give you then a token of trust in regard that this has been tested and works correctly.

To test this I created a branch in stackrox/test-gh-actions. In that branch I changed the occurrences of v1 in .github/workflows/create-clusters.yml to this branch. That makes it so that the actions in this branch are used.

You need to change

uses: stackrox/actions/.github/workflows/create-demo-clusters.yml@v1

and

workflow-ref: v1

@JoukoVirtanen
JoukoVirtanen dismissed tommartensen’s stale reviewOctober 6, 2025 22:51

He is on vacation and this should go in before the long running cluster is created for 4.9.

@JoukoVirtanen
JoukoVirtanen merged commit 09b66ab into mainOct 6, 2025
3 checks passed
@JoukoVirtanen
JoukoVirtanen deleted the jv-ROX-28976-optimize-berserker-load-in-long-running-cluster branch October 6, 2025 22:51
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@JoukoVirtanen@tommartensen@vikin91
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
ROX-28976: Optimize berserker load in long running cluster by JoukoVirtanen · Pull Request #64 · stackrox/actions · GitHub
Skip to content

ROX-28976: Optimize berserker load in long running cluster - #64

Merged
JoukoVirtanen merged 16 commits into
mainfrom
jv-ROX-28976-optimize-berserker-load-in-long-running-cluster
Oct 6, 2025
Merged

ROX-28976: Optimize berserker load in long running cluster#64
JoukoVirtanen merged 16 commits into
mainfrom
jv-ROX-28976-optimize-berserker-load-in-long-running-cluster

Conversation

@JoukoVirtanen

@JoukoVirtanenJoukoVirtanen commented Sep 5, 2025

Copy link
Copy Markdown
Contributor

Recently there were changes to the berserker load for the long running cluster. One of the changes was an increase in the number of berserker pods. Currently Prometheus scrapes metrics on all of the pods in the long running cluster including berserker pods. With the increased number of berserker pods, Prometheus began to OOM. To fix this Prometheus is switched to a different config that filters out some, but not all of the metrics for berserker pods. The memory requests and limits are also increased.

The changes to the berserker load is already merged and was used for testing this PR. stackrox/stackrox#15886

Changes were made here after testing the above PR. A new tag, 0.0.51, was created based off of a recent master, and was used to test the changes here.

@JoukoVirtanen
JoukoVirtanen requested a review from a team as a code ownerSeptember 5, 2025 15:07
@JoukoVirtanen
JoukoVirtanen marked this pull request as draft September 13, 2025 18:28
@JoukoVirtanenJoukoVirtanen changed the title Jv rox 28976 optimize berserker load in long running clusterROX-28976: Optimize berserker load in long running clusterSep 29, 2025
@JoukoVirtanen
JoukoVirtanen marked this pull request as ready for review September 29, 2025 04:39
"name": "prometheus",
"resources": {
"requests": {
"memory": "2Gi",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about we request 8Gi to prevent OOMKills because the node runs out of memory, if it is overcommitted?

If you change this here, please verify in another long-running cluster that Prometheus is starting (as I am unsure if there are 8Gi available on each node with ACS' requirements too).

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

tommartensen
tommartensen previously requested changes Sep 29, 2025

# Replace the prometheus ConfigMap with one that doesn't scrape as much info from berserker containers
kubectl -n stackrox delete configmap prometheus
kubectl create -f "${SCRIPT_DIR}"/prometheus.yaml

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer if we can override the offending values in the monitoring chart. Can you check if that is possible? Same with the update to the monitoring deploment.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean you want me to make the changes in stackrox/stackrox? I feel like 8Gi is too much for every case that the monitoring pod is used. I could make the changes to prometheus.yaml in stackrox/stackrox, but didn't want to pollute it with references to berserker.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I now use yq to set memory limit and request to 8Gi.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would simply copy the ../charts/monitoring/values.yaml and create a berserker-values.yaml to later use it directly, but the approach with yq is okay for me.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tommartensen Requested the use of yq in a private conversation and it is okay with me too.

@JoukoVirtanen
JoukoVirtanenforce-pushed the jv-ROX-28976-optimize-berserker-load-in-long-running-cluster branch from 7d3f49d to 04a2cb7CompareSeptember 30, 2025 04:37
@JoukoVirtanen
JoukoVirtanen requested review from tommartensen and vikin91 and removed request for vikin91October 1, 2025 03:00
sed '/captureStart/d' "${KUBE_BURNER_METRICS_FILE}" > "$temp_metrics_file"
kubectl create configmap --from-file="$temp_metrics_file" kube-burner-metrics-config -n kube-burner

kubectl create configmap --from-file="$KUBE_BURNER_METRICS_FILE" kube-burner-metrics-config -n kube-burner

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we don't need that anymore?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We didn't need it in the first place. It is redundant with the line above it.

@tommartensen

Copy link
Copy Markdown
Collaborator

I believe we're running in circles here and on Slack, so here is my (untested) counterproposal:

What I would like to avoid is duplicating much of the Prometheus config (it might change) and have changes to the configuration obscured. I believe that it is cleaner to use the Helm built-in capabilities for overrides than to update values files with yq or deleting and re-creating Configmaps outside of the Helm cycle.

@JoukoVirtanen

JoukoVirtanen commented Oct 2, 2025

Copy link
Copy Markdown
ContributorAuthor

I believe we're running in circles here and on Slack, so here is my (untested) counterproposal:

What I would like to avoid is duplicating much of the Prometheus config (it might change) and have changes to the configuration obscured. I believe that it is cleaner to use the Helm built-in capabilities for overrides than to update values files with yq or deleting and re-creating Configmaps outside of the Helm cycle.

Thank you for putting together this counter proposal. I really like it when reviewers make the effort to create new branches and PRs. However, I think there might be a flaw in your proposal. Your proposal requires changes in both stackrox/stackrox and here. The problem with that is sometimes long running clusters are created for the release branches. If we go with your approach we would also need backports for the release branches in stackrox/stackrox, otherwise the code here would be incompatible with the helm charts for the monitoring deployment in stackrox/stackrox. Perhaps we can merge this as is and create a ticket to go with your approach. I will test your approach and let you know how it goes.

@tommartensen

tommartensen commented Oct 2, 2025

Copy link
Copy Markdown
Collaborator

Your proposal requires changes in both stackrox/stackrox and here.

I think that is a fundamental flaw in how this berserker thing is setup and should be addressed separately.

The problem with that is sometimes long running clusters are created for the release branches.

That shouldn't happen, can you point me to instances where this led to a problem?

Perhaps we can merge this as is and create a ticket to go with your approach.

I will be out-of-office in the next days. Please create a ticket to follow-up on this PR with the values improvements in ROX-10657 and work with someone in @stackrox/release-improvers to get this PR merged.

@JoukoVirtanen

JoukoVirtanen commented Oct 2, 2025

Copy link
Copy Markdown
ContributorAuthor

Your proposal requires changes in both stackrox/stackrox and here.

I think that is a fundamental flaw in how this berserker thing is setup and should be addressed separately.

I agree. I am not sure what the solution is. Though, I have a mini design proposal with some ideas on preventing breaking changes to the long running cluster https://docs.google.com/document/d/1Vfq1piBebKwAE9EvjNdb7P_TTO1kAgZvCzcPTqx-Nvg/edit?usp=sharing

It hasn't gotten much attention and hasn't gone anywhere.

The problem with that is sometimes long running clusters are created for the release branches.

That shouldn't happen, can you point me to instances where this led to a problem?

Sometimes long running clusters are needed for patch releases. In one case there was a release that had a memory leak which was fixed in a patch. The long running cluster was helpful with that.

One case in which problems occurred for patch releases was when metrics were sent to OpenSearch. There were changes in stackrox/stackrox that had to be made to get to work. Initially changes were made in stackrox/actions to detect what version of stackrox/stackrox was using and use different scripts based off of that. An old script was used for old release branches and a new script was for the current release. The changes to stackrox/stackrox were backported to older release branches. In the time between when the backports were merged and the logic of which script to use in stackrox/actions was updated, a long running cluster for an old release branch was created. That long running cluster failed. stackrox/actions had to be updated and then another long running cluster was successfully created for the patch release.

Perhaps we can merge this as is and create a ticket to go with your approach.

I will be out-of-office in the next days. Please create a ticket to follow-up on this PR with the values improvements in ROX-10657 and work with someone in @stackrox/release-improvers to get this PR merged.

I have created the following ticket https://issues.redhat.com/browse/ROX-31149

@JoukoVirtanen

Copy link
Copy Markdown
ContributorAuthor

@tommartensen I have tested your PRs. It didn't work. I think your idea is sound. There might just be some small mistake somewhere. I ran the following test.

I created a branch from stackrox/stackrox#17105 and tagged it 0.0.52. I then created a new branch in stackrox/test-gh-actions. In that branch I changed the refs in .github/workflows/create-clusters.yml to tm/override-helm-values-berserker. I then created a new long running cluster at https://github.com/stackrox/test-gh-actions/actions/workflows/create-clusters.yml with the branch set to the one I created in stackrox/test-gh-actions and the version set to 0.0.52. When I checked the long running cluster the monitoring pod was in a crash loop. I checked the logs and found the following

$ ks logs monitoring-5b657c9fc5-6kstf -c prometheus
ts=2025-10-03T03:30:11.087Z caller=main.go:438 level=error msg="Error loading config (--config.file=/etc/prometheus/prometheus.yml)" file=/etc/prometheus/prometheus.yml err="parsing YAML file /etc/prometheus/prometheus.yml: yaml: unmarshal errors:\n line 14: cannot unmarshal !!str `- job_n...` into []*config.ScrapeConfig"

The Prometheus ConfigMap had the following

$ ks get configmap prometheus -o yaml
apiVersion: v1
data:
prometheus.yml: "global:\n scrape_interval: 30s\n\nalerting:\n alertmanagers:\n
\ - static_configs:\n - targets:\n - stackrox-monitoring-alertmanager:9093\n\nrule_files:\n
\ - /etc/prometheus/rules_*.yml\n\nscrape_configs:\n |-\n - job_name: \"kubernetes-pods\"\n
\ tls_config:\n insecure_skip_verify: false\n kubernetes_sd_configs:\n
\ - role: pod\n namespaces:\n own_namespace: true\n
\ relabel_configs:\n - action: labelmap\n regex: __meta_kubernetes_pod_label_(.+)\n
\ - source_labels: [__meta_kubernetes_namespace]\n action: replace\n
\ target_label: namespace\n - source_labels: [__meta_kubernetes_pod_name]\n
\ action: replace\n target_label: pod\n - source_labels:
[__meta_kubernetes_pod_node_name]\n action: replace\n target_label:
node_name\n \n - job_name: \"kubernetes-cadvisor\"\n scheme: https\n
\ metrics_path: /metrics/cadvisor\n tls_config:\n ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt\n
\ insecure_skip_verify: true\n authorization:\n credentials_file:
/var/run/secrets/kubernetes.io/serviceaccount/token\n kubernetes_sd_configs:\n
\ - role: node\n relabel_configs:\n - action: labelmap\n regex:
__meta_kubernetes_node_label_(.+)\n \n - job_name: stackrox\n tls_config:\n
\ insecure_skip_verify: false\n kubernetes_sd_configs:\n - role:
endpoints\n namespaces:\n own_namespace: true\n relabel_configs:\n
\ - source_labels: [__meta_kubernetes_endpoint_port_name]\n action:
keep\n regex: monitoring\n - source_labels: [__meta_kubernetes_endpoints_name]\n
\ action: replace\n target_label: job\n - source_labels:
[__meta_kubernetes_namespace]\n action: replace\n target_label:
namespace\n - source_labels: [__meta_kubernetes_endpoint_node_name]\n action:
replace\n target_label: node_name"
rules_custom.yml: |-
|-
groups:
- name: Kubernetes
rules:
- alert: KubernetesContainerOomKiller
expr: (kube_pod_container_status_restarts_total - kube_pod_container_status_restarts_total offset 10m >= 1) and ignoring (reason) min_over_time(kube_pod_container_status_last_terminated_reason{reason="OOMKilled"}[10m]) == 1
for: 0m
labels:
severity: warning
annotations:
summary: Kubernetes container OOM killer (pod {{ "{{" }} .exported_pod {{ "}}" }})
description: "Container {{ "{{" }} .container {{ "}}" }} in pod {{ "{{" }} .exported_namespace {{ "}}" }}/{{ "{{" }} .exported_pod {{ "}}" }} has been OOMKilled {{ "{{" }} {{ "}}" }} times in the last 10 minutes."
- alert: KubernetesPodCrashLooping
expr: increase(kube_pod_container_status_restarts_total[5m]) > 0
for: 2m
labels:
severity: warning
annotations:
summary: Kubernetes pod crash looping (pod {{ "{{" }} .exported_pod {{ "}}" }})
description: "Pod {{ "{{" }} .exported_namespace {{ "}}" }}/{{ "{{" }} .exported_pod {{ "}}" }} is crash looping."
- alert: KubernetesReplicaSetMismatch
expr: kube_replicaset_spec_replicas != kube_replicaset_status_ready_replicas
for: 10m
labels:
severity: warning
annotations:
summary: Kubernetes ReplicaSet mismatch (replicaset {{ "{{" }} .replicaset {{ "}}" }})
description: "Replicas mismatch in ReplicaSet {{ "{{" }} .exported_namespace {{ "}}" }}/{{ "{{" }} .replicaset {{ "}}" }}"
kind: ConfigMap
metadata:
annotations:
meta.helm.sh/release-name: stackrox-monitoring
meta.helm.sh/release-namespace: stackrox
creationTimestamp: "2025-10-03T00:00:19Z"
labels:
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: stackrox
name: prometheus
namespace: stackrox
resourceVersion: "1759449619961263014"
uid: e2acf091-fe60-4ba3-9c91-b49dc5096827

@vikin91vikin91 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes look good!

I tried testing this branch with stackrox/stackrox#17146 but in the action execution, I saw that the code from the actions repository is hardcoded to main:

Download action repository 'stackrox/actions@main' (SHA:cc8a9579ba6de41d3b77b32403bf0f5e8809649d)

See: https://github.com/stackrox/stackrox/actions/runs/18283349491/job/52051757197

I will give you then a token of trust in regard that this has been tested and works correctly.

@JoukoVirtanen

Copy link
Copy Markdown
ContributorAuthor

The changes look good!

I tried testing this branch with stackrox/stackrox#17146 but in the action execution, I saw that the code from the actions repository is hardcoded to main:

Download action repository 'stackrox/actions@main' (SHA:cc8a9579ba6de41d3b77b32403bf0f5e8809649d)

See: https://github.com/stackrox/stackrox/actions/runs/18283349491/job/52051757197

I will give you then a token of trust in regard that this has been tested and works correctly.

To test this I created a branch in stackrox/test-gh-actions. In that branch I changed the occurrences of v1 in .github/workflows/create-clusters.yml to this branch. That makes it so that the actions in this branch are used.

You need to change

uses: stackrox/actions/.github/workflows/create-demo-clusters.yml@v1

and

workflow-ref: v1

@JoukoVirtanen
JoukoVirtanen dismissed tommartensen’s stale reviewOctober 6, 2025 22:51

He is on vacation and this should go in before the long running cluster is created for 4.9.

@JoukoVirtanen
JoukoVirtanen merged commit 09b66ab into mainOct 6, 2025
3 checks passed
@JoukoVirtanen
JoukoVirtanen deleted the jv-ROX-28976-optimize-berserker-load-in-long-running-cluster branch October 6, 2025 22:51
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@JoukoVirtanen@tommartensen@vikin91
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' ROX-28976: Optimize berserker load in long running cluster by JoukoVirtanen · Pull Request #64 · stackrox/actions · GitHub
Skip to content

ROX-28976: Optimize berserker load in long running cluster - #64

Merged
JoukoVirtanen merged 16 commits into
mainfrom
jv-ROX-28976-optimize-berserker-load-in-long-running-cluster
Oct 6, 2025
Merged

ROX-28976: Optimize berserker load in long running cluster#64
JoukoVirtanen merged 16 commits into
mainfrom
jv-ROX-28976-optimize-berserker-load-in-long-running-cluster

Conversation

@JoukoVirtanen

@JoukoVirtanenJoukoVirtanen commented Sep 5, 2025

Copy link
Copy Markdown
Contributor

Recently there were changes to the berserker load for the long running cluster. One of the changes was an increase in the number of berserker pods. Currently Prometheus scrapes metrics on all of the pods in the long running cluster including berserker pods. With the increased number of berserker pods, Prometheus began to OOM. To fix this Prometheus is switched to a different config that filters out some, but not all of the metrics for berserker pods. The memory requests and limits are also increased.

The changes to the berserker load is already merged and was used for testing this PR. stackrox/stackrox#15886

Changes were made here after testing the above PR. A new tag, 0.0.51, was created based off of a recent master, and was used to test the changes here.

@JoukoVirtanen
JoukoVirtanen requested a review from a team as a code ownerSeptember 5, 2025 15:07
@JoukoVirtanen
JoukoVirtanen marked this pull request as draft September 13, 2025 18:28
@JoukoVirtanenJoukoVirtanen changed the title Jv rox 28976 optimize berserker load in long running clusterROX-28976: Optimize berserker load in long running clusterSep 29, 2025
@JoukoVirtanen
JoukoVirtanen marked this pull request as ready for review September 29, 2025 04:39
"name": "prometheus",
"resources": {
"requests": {
"memory": "2Gi",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about we request 8Gi to prevent OOMKills because the node runs out of memory, if it is overcommitted?

If you change this here, please verify in another long-running cluster that Prometheus is starting (as I am unsure if there are 8Gi available on each node with ACS' requirements too).

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

tommartensen
tommartensen previously requested changes Sep 29, 2025

# Replace the prometheus ConfigMap with one that doesn't scrape as much info from berserker containers
kubectl -n stackrox delete configmap prometheus
kubectl create -f "${SCRIPT_DIR}"/prometheus.yaml

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer if we can override the offending values in the monitoring chart. Can you check if that is possible? Same with the update to the monitoring deploment.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean you want me to make the changes in stackrox/stackrox? I feel like 8Gi is too much for every case that the monitoring pod is used. I could make the changes to prometheus.yaml in stackrox/stackrox, but didn't want to pollute it with references to berserker.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I now use yq to set memory limit and request to 8Gi.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would simply copy the ../charts/monitoring/values.yaml and create a berserker-values.yaml to later use it directly, but the approach with yq is okay for me.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tommartensen Requested the use of yq in a private conversation and it is okay with me too.

@JoukoVirtanen
JoukoVirtanenforce-pushed the jv-ROX-28976-optimize-berserker-load-in-long-running-cluster branch from 7d3f49d to 04a2cb7CompareSeptember 30, 2025 04:37
@JoukoVirtanen
JoukoVirtanen requested review from tommartensen and vikin91 and removed request for vikin91October 1, 2025 03:00
sed '/captureStart/d' "${KUBE_BURNER_METRICS_FILE}" > "$temp_metrics_file"
kubectl create configmap --from-file="$temp_metrics_file" kube-burner-metrics-config -n kube-burner

kubectl create configmap --from-file="$KUBE_BURNER_METRICS_FILE" kube-burner-metrics-config -n kube-burner

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we don't need that anymore?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We didn't need it in the first place. It is redundant with the line above it.

@tommartensen

Copy link
Copy Markdown
Collaborator

I believe we're running in circles here and on Slack, so here is my (untested) counterproposal:

What I would like to avoid is duplicating much of the Prometheus config (it might change) and have changes to the configuration obscured. I believe that it is cleaner to use the Helm built-in capabilities for overrides than to update values files with yq or deleting and re-creating Configmaps outside of the Helm cycle.

@JoukoVirtanen

JoukoVirtanen commented Oct 2, 2025

Copy link
Copy Markdown
ContributorAuthor

I believe we're running in circles here and on Slack, so here is my (untested) counterproposal:

What I would like to avoid is duplicating much of the Prometheus config (it might change) and have changes to the configuration obscured. I believe that it is cleaner to use the Helm built-in capabilities for overrides than to update values files with yq or deleting and re-creating Configmaps outside of the Helm cycle.

Thank you for putting together this counter proposal. I really like it when reviewers make the effort to create new branches and PRs. However, I think there might be a flaw in your proposal. Your proposal requires changes in both stackrox/stackrox and here. The problem with that is sometimes long running clusters are created for the release branches. If we go with your approach we would also need backports for the release branches in stackrox/stackrox, otherwise the code here would be incompatible with the helm charts for the monitoring deployment in stackrox/stackrox. Perhaps we can merge this as is and create a ticket to go with your approach. I will test your approach and let you know how it goes.

@tommartensen

tommartensen commented Oct 2, 2025

Copy link
Copy Markdown
Collaborator

Your proposal requires changes in both stackrox/stackrox and here.

I think that is a fundamental flaw in how this berserker thing is setup and should be addressed separately.

The problem with that is sometimes long running clusters are created for the release branches.

That shouldn't happen, can you point me to instances where this led to a problem?

Perhaps we can merge this as is and create a ticket to go with your approach.

I will be out-of-office in the next days. Please create a ticket to follow-up on this PR with the values improvements in ROX-10657 and work with someone in @stackrox/release-improvers to get this PR merged.

@JoukoVirtanen

JoukoVirtanen commented Oct 2, 2025

Copy link
Copy Markdown
ContributorAuthor

Your proposal requires changes in both stackrox/stackrox and here.

I think that is a fundamental flaw in how this berserker thing is setup and should be addressed separately.

I agree. I am not sure what the solution is. Though, I have a mini design proposal with some ideas on preventing breaking changes to the long running cluster https://docs.google.com/document/d/1Vfq1piBebKwAE9EvjNdb7P_TTO1kAgZvCzcPTqx-Nvg/edit?usp=sharing

It hasn't gotten much attention and hasn't gone anywhere.

The problem with that is sometimes long running clusters are created for the release branches.

That shouldn't happen, can you point me to instances where this led to a problem?

Sometimes long running clusters are needed for patch releases. In one case there was a release that had a memory leak which was fixed in a patch. The long running cluster was helpful with that.

One case in which problems occurred for patch releases was when metrics were sent to OpenSearch. There were changes in stackrox/stackrox that had to be made to get to work. Initially changes were made in stackrox/actions to detect what version of stackrox/stackrox was using and use different scripts based off of that. An old script was used for old release branches and a new script was for the current release. The changes to stackrox/stackrox were backported to older release branches. In the time between when the backports were merged and the logic of which script to use in stackrox/actions was updated, a long running cluster for an old release branch was created. That long running cluster failed. stackrox/actions had to be updated and then another long running cluster was successfully created for the patch release.

Perhaps we can merge this as is and create a ticket to go with your approach.

I will be out-of-office in the next days. Please create a ticket to follow-up on this PR with the values improvements in ROX-10657 and work with someone in @stackrox/release-improvers to get this PR merged.

I have created the following ticket https://issues.redhat.com/browse/ROX-31149

@JoukoVirtanen

Copy link
Copy Markdown
ContributorAuthor

@tommartensen I have tested your PRs. It didn't work. I think your idea is sound. There might just be some small mistake somewhere. I ran the following test.

I created a branch from stackrox/stackrox#17105 and tagged it 0.0.52. I then created a new branch in stackrox/test-gh-actions. In that branch I changed the refs in .github/workflows/create-clusters.yml to tm/override-helm-values-berserker. I then created a new long running cluster at https://github.com/stackrox/test-gh-actions/actions/workflows/create-clusters.yml with the branch set to the one I created in stackrox/test-gh-actions and the version set to 0.0.52. When I checked the long running cluster the monitoring pod was in a crash loop. I checked the logs and found the following

$ ks logs monitoring-5b657c9fc5-6kstf -c prometheus
ts=2025-10-03T03:30:11.087Z caller=main.go:438 level=error msg="Error loading config (--config.file=/etc/prometheus/prometheus.yml)" file=/etc/prometheus/prometheus.yml err="parsing YAML file /etc/prometheus/prometheus.yml: yaml: unmarshal errors:\n line 14: cannot unmarshal !!str `- job_n...` into []*config.ScrapeConfig"

The Prometheus ConfigMap had the following

$ ks get configmap prometheus -o yaml
apiVersion: v1
data:
prometheus.yml: "global:\n scrape_interval: 30s\n\nalerting:\n alertmanagers:\n
\ - static_configs:\n - targets:\n - stackrox-monitoring-alertmanager:9093\n\nrule_files:\n
\ - /etc/prometheus/rules_*.yml\n\nscrape_configs:\n |-\n - job_name: \"kubernetes-pods\"\n
\ tls_config:\n insecure_skip_verify: false\n kubernetes_sd_configs:\n
\ - role: pod\n namespaces:\n own_namespace: true\n
\ relabel_configs:\n - action: labelmap\n regex: __meta_kubernetes_pod_label_(.+)\n
\ - source_labels: [__meta_kubernetes_namespace]\n action: replace\n
\ target_label: namespace\n - source_labels: [__meta_kubernetes_pod_name]\n
\ action: replace\n target_label: pod\n - source_labels:
[__meta_kubernetes_pod_node_name]\n action: replace\n target_label:
node_name\n \n - job_name: \"kubernetes-cadvisor\"\n scheme: https\n
\ metrics_path: /metrics/cadvisor\n tls_config:\n ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt\n
\ insecure_skip_verify: true\n authorization:\n credentials_file:
/var/run/secrets/kubernetes.io/serviceaccount/token\n kubernetes_sd_configs:\n
\ - role: node\n relabel_configs:\n - action: labelmap\n regex:
__meta_kubernetes_node_label_(.+)\n \n - job_name: stackrox\n tls_config:\n
\ insecure_skip_verify: false\n kubernetes_sd_configs:\n - role:
endpoints\n namespaces:\n own_namespace: true\n relabel_configs:\n
\ - source_labels: [__meta_kubernetes_endpoint_port_name]\n action:
keep\n regex: monitoring\n - source_labels: [__meta_kubernetes_endpoints_name]\n
\ action: replace\n target_label: job\n - source_labels:
[__meta_kubernetes_namespace]\n action: replace\n target_label:
namespace\n - source_labels: [__meta_kubernetes_endpoint_node_name]\n action:
replace\n target_label: node_name"
rules_custom.yml: |-
|-
groups:
- name: Kubernetes
rules:
- alert: KubernetesContainerOomKiller
expr: (kube_pod_container_status_restarts_total - kube_pod_container_status_restarts_total offset 10m >= 1) and ignoring (reason) min_over_time(kube_pod_container_status_last_terminated_reason{reason="OOMKilled"}[10m]) == 1
for: 0m
labels:
severity: warning
annotations:
summary: Kubernetes container OOM killer (pod {{ "{{" }} .exported_pod {{ "}}" }})
description: "Container {{ "{{" }} .container {{ "}}" }} in pod {{ "{{" }} .exported_namespace {{ "}}" }}/{{ "{{" }} .exported_pod {{ "}}" }} has been OOMKilled {{ "{{" }} {{ "}}" }} times in the last 10 minutes."
- alert: KubernetesPodCrashLooping
expr: increase(kube_pod_container_status_restarts_total[5m]) > 0
for: 2m
labels:
severity: warning
annotations:
summary: Kubernetes pod crash looping (pod {{ "{{" }} .exported_pod {{ "}}" }})
description: "Pod {{ "{{" }} .exported_namespace {{ "}}" }}/{{ "{{" }} .exported_pod {{ "}}" }} is crash looping."
- alert: KubernetesReplicaSetMismatch
expr: kube_replicaset_spec_replicas != kube_replicaset_status_ready_replicas
for: 10m
labels:
severity: warning
annotations:
summary: Kubernetes ReplicaSet mismatch (replicaset {{ "{{" }} .replicaset {{ "}}" }})
description: "Replicas mismatch in ReplicaSet {{ "{{" }} .exported_namespace {{ "}}" }}/{{ "{{" }} .replicaset {{ "}}" }}"
kind: ConfigMap
metadata:
annotations:
meta.helm.sh/release-name: stackrox-monitoring
meta.helm.sh/release-namespace: stackrox
creationTimestamp: "2025-10-03T00:00:19Z"
labels:
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: stackrox
name: prometheus
namespace: stackrox
resourceVersion: "1759449619961263014"
uid: e2acf091-fe60-4ba3-9c91-b49dc5096827

@vikin91vikin91 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes look good!

I tried testing this branch with stackrox/stackrox#17146 but in the action execution, I saw that the code from the actions repository is hardcoded to main:

Download action repository 'stackrox/actions@main' (SHA:cc8a9579ba6de41d3b77b32403bf0f5e8809649d)

See: https://github.com/stackrox/stackrox/actions/runs/18283349491/job/52051757197

I will give you then a token of trust in regard that this has been tested and works correctly.

@JoukoVirtanen

Copy link
Copy Markdown
ContributorAuthor

The changes look good!

I tried testing this branch with stackrox/stackrox#17146 but in the action execution, I saw that the code from the actions repository is hardcoded to main:

Download action repository 'stackrox/actions@main' (SHA:cc8a9579ba6de41d3b77b32403bf0f5e8809649d)

See: https://github.com/stackrox/stackrox/actions/runs/18283349491/job/52051757197

I will give you then a token of trust in regard that this has been tested and works correctly.

To test this I created a branch in stackrox/test-gh-actions. In that branch I changed the occurrences of v1 in .github/workflows/create-clusters.yml to this branch. That makes it so that the actions in this branch are used.

You need to change

uses: stackrox/actions/.github/workflows/create-demo-clusters.yml@v1

and

workflow-ref: v1

@JoukoVirtanen
JoukoVirtanen dismissed tommartensen’s stale reviewOctober 6, 2025 22:51

He is on vacation and this should go in before the long running cluster is created for 4.9.

@JoukoVirtanen
JoukoVirtanen merged commit 09b66ab into mainOct 6, 2025
3 checks passed
@JoukoVirtanen
JoukoVirtanen deleted the jv-ROX-28976-optimize-berserker-load-in-long-running-cluster branch October 6, 2025 22:51
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@JoukoVirtanen@tommartensen@vikin91
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' ROX-28976: Optimize berserker load in long running cluster by JoukoVirtanen · Pull Request #64 · stackrox/actions · GitHub
Skip to content

ROX-28976: Optimize berserker load in long running cluster - #64

Merged
JoukoVirtanen merged 16 commits into
mainfrom
jv-ROX-28976-optimize-berserker-load-in-long-running-cluster
Oct 6, 2025
Merged

ROX-28976: Optimize berserker load in long running cluster#64
JoukoVirtanen merged 16 commits into
mainfrom
jv-ROX-28976-optimize-berserker-load-in-long-running-cluster

Conversation

@JoukoVirtanen

@JoukoVirtanenJoukoVirtanen commented Sep 5, 2025

Copy link
Copy Markdown
Contributor

Recently there were changes to the berserker load for the long running cluster. One of the changes was an increase in the number of berserker pods. Currently Prometheus scrapes metrics on all of the pods in the long running cluster including berserker pods. With the increased number of berserker pods, Prometheus began to OOM. To fix this Prometheus is switched to a different config that filters out some, but not all of the metrics for berserker pods. The memory requests and limits are also increased.

The changes to the berserker load is already merged and was used for testing this PR. stackrox/stackrox#15886

Changes were made here after testing the above PR. A new tag, 0.0.51, was created based off of a recent master, and was used to test the changes here.

@JoukoVirtanen
JoukoVirtanen requested a review from a team as a code ownerSeptember 5, 2025 15:07
@JoukoVirtanen
JoukoVirtanen marked this pull request as draft September 13, 2025 18:28
@JoukoVirtanenJoukoVirtanen changed the title Jv rox 28976 optimize berserker load in long running clusterROX-28976: Optimize berserker load in long running clusterSep 29, 2025
@JoukoVirtanen
JoukoVirtanen marked this pull request as ready for review September 29, 2025 04:39
"name": "prometheus",
"resources": {
"requests": {
"memory": "2Gi",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about we request 8Gi to prevent OOMKills because the node runs out of memory, if it is overcommitted?

If you change this here, please verify in another long-running cluster that Prometheus is starting (as I am unsure if there are 8Gi available on each node with ACS' requirements too).

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

tommartensen
tommartensen previously requested changes Sep 29, 2025

# Replace the prometheus ConfigMap with one that doesn't scrape as much info from berserker containers
kubectl -n stackrox delete configmap prometheus
kubectl create -f "${SCRIPT_DIR}"/prometheus.yaml

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer if we can override the offending values in the monitoring chart. Can you check if that is possible? Same with the update to the monitoring deploment.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean you want me to make the changes in stackrox/stackrox? I feel like 8Gi is too much for every case that the monitoring pod is used. I could make the changes to prometheus.yaml in stackrox/stackrox, but didn't want to pollute it with references to berserker.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I now use yq to set memory limit and request to 8Gi.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would simply copy the ../charts/monitoring/values.yaml and create a berserker-values.yaml to later use it directly, but the approach with yq is okay for me.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tommartensen Requested the use of yq in a private conversation and it is okay with me too.

@JoukoVirtanen
JoukoVirtanenforce-pushed the jv-ROX-28976-optimize-berserker-load-in-long-running-cluster branch from 7d3f49d to 04a2cb7CompareSeptember 30, 2025 04:37
@JoukoVirtanen
JoukoVirtanen requested review from tommartensen and vikin91 and removed request for vikin91October 1, 2025 03:00
sed '/captureStart/d' "${KUBE_BURNER_METRICS_FILE}" > "$temp_metrics_file"
kubectl create configmap --from-file="$temp_metrics_file" kube-burner-metrics-config -n kube-burner

kubectl create configmap --from-file="$KUBE_BURNER_METRICS_FILE" kube-burner-metrics-config -n kube-burner

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we don't need that anymore?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We didn't need it in the first place. It is redundant with the line above it.

@tommartensen

Copy link
Copy Markdown
Collaborator

I believe we're running in circles here and on Slack, so here is my (untested) counterproposal:

What I would like to avoid is duplicating much of the Prometheus config (it might change) and have changes to the configuration obscured. I believe that it is cleaner to use the Helm built-in capabilities for overrides than to update values files with yq or deleting and re-creating Configmaps outside of the Helm cycle.

@JoukoVirtanen

JoukoVirtanen commented Oct 2, 2025

Copy link
Copy Markdown
ContributorAuthor

I believe we're running in circles here and on Slack, so here is my (untested) counterproposal:

What I would like to avoid is duplicating much of the Prometheus config (it might change) and have changes to the configuration obscured. I believe that it is cleaner to use the Helm built-in capabilities for overrides than to update values files with yq or deleting and re-creating Configmaps outside of the Helm cycle.

Thank you for putting together this counter proposal. I really like it when reviewers make the effort to create new branches and PRs. However, I think there might be a flaw in your proposal. Your proposal requires changes in both stackrox/stackrox and here. The problem with that is sometimes long running clusters are created for the release branches. If we go with your approach we would also need backports for the release branches in stackrox/stackrox, otherwise the code here would be incompatible with the helm charts for the monitoring deployment in stackrox/stackrox. Perhaps we can merge this as is and create a ticket to go with your approach. I will test your approach and let you know how it goes.

@tommartensen

tommartensen commented Oct 2, 2025

Copy link
Copy Markdown
Collaborator

Your proposal requires changes in both stackrox/stackrox and here.

I think that is a fundamental flaw in how this berserker thing is setup and should be addressed separately.

The problem with that is sometimes long running clusters are created for the release branches.

That shouldn't happen, can you point me to instances where this led to a problem?

Perhaps we can merge this as is and create a ticket to go with your approach.

I will be out-of-office in the next days. Please create a ticket to follow-up on this PR with the values improvements in ROX-10657 and work with someone in @stackrox/release-improvers to get this PR merged.

@JoukoVirtanen

JoukoVirtanen commented Oct 2, 2025

Copy link
Copy Markdown
ContributorAuthor

Your proposal requires changes in both stackrox/stackrox and here.

I think that is a fundamental flaw in how this berserker thing is setup and should be addressed separately.

I agree. I am not sure what the solution is. Though, I have a mini design proposal with some ideas on preventing breaking changes to the long running cluster https://docs.google.com/document/d/1Vfq1piBebKwAE9EvjNdb7P_TTO1kAgZvCzcPTqx-Nvg/edit?usp=sharing

It hasn't gotten much attention and hasn't gone anywhere.

The problem with that is sometimes long running clusters are created for the release branches.

That shouldn't happen, can you point me to instances where this led to a problem?

Sometimes long running clusters are needed for patch releases. In one case there was a release that had a memory leak which was fixed in a patch. The long running cluster was helpful with that.

One case in which problems occurred for patch releases was when metrics were sent to OpenSearch. There were changes in stackrox/stackrox that had to be made to get to work. Initially changes were made in stackrox/actions to detect what version of stackrox/stackrox was using and use different scripts based off of that. An old script was used for old release branches and a new script was for the current release. The changes to stackrox/stackrox were backported to older release branches. In the time between when the backports were merged and the logic of which script to use in stackrox/actions was updated, a long running cluster for an old release branch was created. That long running cluster failed. stackrox/actions had to be updated and then another long running cluster was successfully created for the patch release.

Perhaps we can merge this as is and create a ticket to go with your approach.

I will be out-of-office in the next days. Please create a ticket to follow-up on this PR with the values improvements in ROX-10657 and work with someone in @stackrox/release-improvers to get this PR merged.

I have created the following ticket https://issues.redhat.com/browse/ROX-31149

@JoukoVirtanen

Copy link
Copy Markdown
ContributorAuthor

@tommartensen I have tested your PRs. It didn't work. I think your idea is sound. There might just be some small mistake somewhere. I ran the following test.

I created a branch from stackrox/stackrox#17105 and tagged it 0.0.52. I then created a new branch in stackrox/test-gh-actions. In that branch I changed the refs in .github/workflows/create-clusters.yml to tm/override-helm-values-berserker. I then created a new long running cluster at https://github.com/stackrox/test-gh-actions/actions/workflows/create-clusters.yml with the branch set to the one I created in stackrox/test-gh-actions and the version set to 0.0.52. When I checked the long running cluster the monitoring pod was in a crash loop. I checked the logs and found the following

$ ks logs monitoring-5b657c9fc5-6kstf -c prometheus
ts=2025-10-03T03:30:11.087Z caller=main.go:438 level=error msg="Error loading config (--config.file=/etc/prometheus/prometheus.yml)" file=/etc/prometheus/prometheus.yml err="parsing YAML file /etc/prometheus/prometheus.yml: yaml: unmarshal errors:\n line 14: cannot unmarshal !!str `- job_n...` into []*config.ScrapeConfig"

The Prometheus ConfigMap had the following

$ ks get configmap prometheus -o yaml
apiVersion: v1
data:
prometheus.yml: "global:\n scrape_interval: 30s\n\nalerting:\n alertmanagers:\n
\ - static_configs:\n - targets:\n - stackrox-monitoring-alertmanager:9093\n\nrule_files:\n
\ - /etc/prometheus/rules_*.yml\n\nscrape_configs:\n |-\n - job_name: \"kubernetes-pods\"\n
\ tls_config:\n insecure_skip_verify: false\n kubernetes_sd_configs:\n
\ - role: pod\n namespaces:\n own_namespace: true\n
\ relabel_configs:\n - action: labelmap\n regex: __meta_kubernetes_pod_label_(.+)\n
\ - source_labels: [__meta_kubernetes_namespace]\n action: replace\n
\ target_label: namespace\n - source_labels: [__meta_kubernetes_pod_name]\n
\ action: replace\n target_label: pod\n - source_labels:
[__meta_kubernetes_pod_node_name]\n action: replace\n target_label:
node_name\n \n - job_name: \"kubernetes-cadvisor\"\n scheme: https\n
\ metrics_path: /metrics/cadvisor\n tls_config:\n ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt\n
\ insecure_skip_verify: true\n authorization:\n credentials_file:
/var/run/secrets/kubernetes.io/serviceaccount/token\n kubernetes_sd_configs:\n
\ - role: node\n relabel_configs:\n - action: labelmap\n regex:
__meta_kubernetes_node_label_(.+)\n \n - job_name: stackrox\n tls_config:\n
\ insecure_skip_verify: false\n kubernetes_sd_configs:\n - role:
endpoints\n namespaces:\n own_namespace: true\n relabel_configs:\n
\ - source_labels: [__meta_kubernetes_endpoint_port_name]\n action:
keep\n regex: monitoring\n - source_labels: [__meta_kubernetes_endpoints_name]\n
\ action: replace\n target_label: job\n - source_labels:
[__meta_kubernetes_namespace]\n action: replace\n target_label:
namespace\n - source_labels: [__meta_kubernetes_endpoint_node_name]\n action:
replace\n target_label: node_name"
rules_custom.yml: |-
|-
groups:
- name: Kubernetes
rules:
- alert: KubernetesContainerOomKiller
expr: (kube_pod_container_status_restarts_total - kube_pod_container_status_restarts_total offset 10m >= 1) and ignoring (reason) min_over_time(kube_pod_container_status_last_terminated_reason{reason="OOMKilled"}[10m]) == 1
for: 0m
labels:
severity: warning
annotations:
summary: Kubernetes container OOM killer (pod {{ "{{" }} .exported_pod {{ "}}" }})
description: "Container {{ "{{" }} .container {{ "}}" }} in pod {{ "{{" }} .exported_namespace {{ "}}" }}/{{ "{{" }} .exported_pod {{ "}}" }} has been OOMKilled {{ "{{" }} {{ "}}" }} times in the last 10 minutes."
- alert: KubernetesPodCrashLooping
expr: increase(kube_pod_container_status_restarts_total[5m]) > 0
for: 2m
labels:
severity: warning
annotations:
summary: Kubernetes pod crash looping (pod {{ "{{" }} .exported_pod {{ "}}" }})
description: "Pod {{ "{{" }} .exported_namespace {{ "}}" }}/{{ "{{" }} .exported_pod {{ "}}" }} is crash looping."
- alert: KubernetesReplicaSetMismatch
expr: kube_replicaset_spec_replicas != kube_replicaset_status_ready_replicas
for: 10m
labels:
severity: warning
annotations:
summary: Kubernetes ReplicaSet mismatch (replicaset {{ "{{" }} .replicaset {{ "}}" }})
description: "Replicas mismatch in ReplicaSet {{ "{{" }} .exported_namespace {{ "}}" }}/{{ "{{" }} .replicaset {{ "}}" }}"
kind: ConfigMap
metadata:
annotations:
meta.helm.sh/release-name: stackrox-monitoring
meta.helm.sh/release-namespace: stackrox
creationTimestamp: "2025-10-03T00:00:19Z"
labels:
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: stackrox
name: prometheus
namespace: stackrox
resourceVersion: "1759449619961263014"
uid: e2acf091-fe60-4ba3-9c91-b49dc5096827

@vikin91vikin91 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes look good!

I tried testing this branch with stackrox/stackrox#17146 but in the action execution, I saw that the code from the actions repository is hardcoded to main:

Download action repository 'stackrox/actions@main' (SHA:cc8a9579ba6de41d3b77b32403bf0f5e8809649d)

See: https://github.com/stackrox/stackrox/actions/runs/18283349491/job/52051757197

I will give you then a token of trust in regard that this has been tested and works correctly.

@JoukoVirtanen

Copy link
Copy Markdown
ContributorAuthor

The changes look good!

I tried testing this branch with stackrox/stackrox#17146 but in the action execution, I saw that the code from the actions repository is hardcoded to main:

Download action repository 'stackrox/actions@main' (SHA:cc8a9579ba6de41d3b77b32403bf0f5e8809649d)

See: https://github.com/stackrox/stackrox/actions/runs/18283349491/job/52051757197

I will give you then a token of trust in regard that this has been tested and works correctly.

To test this I created a branch in stackrox/test-gh-actions. In that branch I changed the occurrences of v1 in .github/workflows/create-clusters.yml to this branch. That makes it so that the actions in this branch are used.

You need to change

uses: stackrox/actions/.github/workflows/create-demo-clusters.yml@v1

and

workflow-ref: v1

@JoukoVirtanen
JoukoVirtanen dismissed tommartensen’s stale reviewOctober 6, 2025 22:51

He is on vacation and this should go in before the long running cluster is created for 4.9.

@JoukoVirtanen
JoukoVirtanen merged commit 09b66ab into mainOct 6, 2025
3 checks passed
@JoukoVirtanen
JoukoVirtanen deleted the jv-ROX-28976-optimize-berserker-load-in-long-running-cluster branch October 6, 2025 22:51
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@JoukoVirtanen@tommartensen@vikin91
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' ROX-28976: Optimize berserker load in long running cluster by JoukoVirtanen · Pull Request #64 · stackrox/actions · GitHub
Skip to content

ROX-28976: Optimize berserker load in long running cluster - #64

Merged
JoukoVirtanen merged 16 commits into
mainfrom
jv-ROX-28976-optimize-berserker-load-in-long-running-cluster
Oct 6, 2025
Merged

ROX-28976: Optimize berserker load in long running cluster#64
JoukoVirtanen merged 16 commits into
mainfrom
jv-ROX-28976-optimize-berserker-load-in-long-running-cluster

Conversation

@JoukoVirtanen

@JoukoVirtanenJoukoVirtanen commented Sep 5, 2025

Copy link
Copy Markdown
Contributor

Recently there were changes to the berserker load for the long running cluster. One of the changes was an increase in the number of berserker pods. Currently Prometheus scrapes metrics on all of the pods in the long running cluster including berserker pods. With the increased number of berserker pods, Prometheus began to OOM. To fix this Prometheus is switched to a different config that filters out some, but not all of the metrics for berserker pods. The memory requests and limits are also increased.

The changes to the berserker load is already merged and was used for testing this PR. stackrox/stackrox#15886

Changes were made here after testing the above PR. A new tag, 0.0.51, was created based off of a recent master, and was used to test the changes here.

@JoukoVirtanen
JoukoVirtanen requested a review from a team as a code ownerSeptember 5, 2025 15:07
@JoukoVirtanen
JoukoVirtanen marked this pull request as draft September 13, 2025 18:28
@JoukoVirtanenJoukoVirtanen changed the title Jv rox 28976 optimize berserker load in long running clusterROX-28976: Optimize berserker load in long running clusterSep 29, 2025
@JoukoVirtanen
JoukoVirtanen marked this pull request as ready for review September 29, 2025 04:39
"name": "prometheus",
"resources": {
"requests": {
"memory": "2Gi",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about we request 8Gi to prevent OOMKills because the node runs out of memory, if it is overcommitted?

If you change this here, please verify in another long-running cluster that Prometheus is starting (as I am unsure if there are 8Gi available on each node with ACS' requirements too).

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

tommartensen
tommartensen previously requested changes Sep 29, 2025

# Replace the prometheus ConfigMap with one that doesn't scrape as much info from berserker containers
kubectl -n stackrox delete configmap prometheus
kubectl create -f "${SCRIPT_DIR}"/prometheus.yaml

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer if we can override the offending values in the monitoring chart. Can you check if that is possible? Same with the update to the monitoring deploment.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean you want me to make the changes in stackrox/stackrox? I feel like 8Gi is too much for every case that the monitoring pod is used. I could make the changes to prometheus.yaml in stackrox/stackrox, but didn't want to pollute it with references to berserker.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I now use yq to set memory limit and request to 8Gi.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would simply copy the ../charts/monitoring/values.yaml and create a berserker-values.yaml to later use it directly, but the approach with yq is okay for me.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tommartensen Requested the use of yq in a private conversation and it is okay with me too.

@JoukoVirtanen
JoukoVirtanenforce-pushed the jv-ROX-28976-optimize-berserker-load-in-long-running-cluster branch from 7d3f49d to 04a2cb7CompareSeptember 30, 2025 04:37
@JoukoVirtanen
JoukoVirtanen requested review from tommartensen and vikin91 and removed request for vikin91October 1, 2025 03:00
sed '/captureStart/d' "${KUBE_BURNER_METRICS_FILE}" > "$temp_metrics_file"
kubectl create configmap --from-file="$temp_metrics_file" kube-burner-metrics-config -n kube-burner

kubectl create configmap --from-file="$KUBE_BURNER_METRICS_FILE" kube-burner-metrics-config -n kube-burner

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we don't need that anymore?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We didn't need it in the first place. It is redundant with the line above it.

@tommartensen

Copy link
Copy Markdown
Collaborator

I believe we're running in circles here and on Slack, so here is my (untested) counterproposal:

What I would like to avoid is duplicating much of the Prometheus config (it might change) and have changes to the configuration obscured. I believe that it is cleaner to use the Helm built-in capabilities for overrides than to update values files with yq or deleting and re-creating Configmaps outside of the Helm cycle.

@JoukoVirtanen

JoukoVirtanen commented Oct 2, 2025

Copy link
Copy Markdown
ContributorAuthor

I believe we're running in circles here and on Slack, so here is my (untested) counterproposal:

What I would like to avoid is duplicating much of the Prometheus config (it might change) and have changes to the configuration obscured. I believe that it is cleaner to use the Helm built-in capabilities for overrides than to update values files with yq or deleting and re-creating Configmaps outside of the Helm cycle.

Thank you for putting together this counter proposal. I really like it when reviewers make the effort to create new branches and PRs. However, I think there might be a flaw in your proposal. Your proposal requires changes in both stackrox/stackrox and here. The problem with that is sometimes long running clusters are created for the release branches. If we go with your approach we would also need backports for the release branches in stackrox/stackrox, otherwise the code here would be incompatible with the helm charts for the monitoring deployment in stackrox/stackrox. Perhaps we can merge this as is and create a ticket to go with your approach. I will test your approach and let you know how it goes.

@tommartensen

tommartensen commented Oct 2, 2025

Copy link
Copy Markdown
Collaborator

Your proposal requires changes in both stackrox/stackrox and here.

I think that is a fundamental flaw in how this berserker thing is setup and should be addressed separately.

The problem with that is sometimes long running clusters are created for the release branches.

That shouldn't happen, can you point me to instances where this led to a problem?

Perhaps we can merge this as is and create a ticket to go with your approach.

I will be out-of-office in the next days. Please create a ticket to follow-up on this PR with the values improvements in ROX-10657 and work with someone in @stackrox/release-improvers to get this PR merged.

@JoukoVirtanen

JoukoVirtanen commented Oct 2, 2025

Copy link
Copy Markdown
ContributorAuthor

Your proposal requires changes in both stackrox/stackrox and here.

I think that is a fundamental flaw in how this berserker thing is setup and should be addressed separately.

I agree. I am not sure what the solution is. Though, I have a mini design proposal with some ideas on preventing breaking changes to the long running cluster https://docs.google.com/document/d/1Vfq1piBebKwAE9EvjNdb7P_TTO1kAgZvCzcPTqx-Nvg/edit?usp=sharing

It hasn't gotten much attention and hasn't gone anywhere.

The problem with that is sometimes long running clusters are created for the release branches.

That shouldn't happen, can you point me to instances where this led to a problem?

Sometimes long running clusters are needed for patch releases. In one case there was a release that had a memory leak which was fixed in a patch. The long running cluster was helpful with that.

One case in which problems occurred for patch releases was when metrics were sent to OpenSearch. There were changes in stackrox/stackrox that had to be made to get to work. Initially changes were made in stackrox/actions to detect what version of stackrox/stackrox was using and use different scripts based off of that. An old script was used for old release branches and a new script was for the current release. The changes to stackrox/stackrox were backported to older release branches. In the time between when the backports were merged and the logic of which script to use in stackrox/actions was updated, a long running cluster for an old release branch was created. That long running cluster failed. stackrox/actions had to be updated and then another long running cluster was successfully created for the patch release.

Perhaps we can merge this as is and create a ticket to go with your approach.

I will be out-of-office in the next days. Please create a ticket to follow-up on this PR with the values improvements in ROX-10657 and work with someone in @stackrox/release-improvers to get this PR merged.

I have created the following ticket https://issues.redhat.com/browse/ROX-31149

@JoukoVirtanen

Copy link
Copy Markdown
ContributorAuthor

@tommartensen I have tested your PRs. It didn't work. I think your idea is sound. There might just be some small mistake somewhere. I ran the following test.

I created a branch from stackrox/stackrox#17105 and tagged it 0.0.52. I then created a new branch in stackrox/test-gh-actions. In that branch I changed the refs in .github/workflows/create-clusters.yml to tm/override-helm-values-berserker. I then created a new long running cluster at https://github.com/stackrox/test-gh-actions/actions/workflows/create-clusters.yml with the branch set to the one I created in stackrox/test-gh-actions and the version set to 0.0.52. When I checked the long running cluster the monitoring pod was in a crash loop. I checked the logs and found the following

$ ks logs monitoring-5b657c9fc5-6kstf -c prometheus
ts=2025-10-03T03:30:11.087Z caller=main.go:438 level=error msg="Error loading config (--config.file=/etc/prometheus/prometheus.yml)" file=/etc/prometheus/prometheus.yml err="parsing YAML file /etc/prometheus/prometheus.yml: yaml: unmarshal errors:\n line 14: cannot unmarshal !!str `- job_n...` into []*config.ScrapeConfig"

The Prometheus ConfigMap had the following

$ ks get configmap prometheus -o yaml
apiVersion: v1
data:
prometheus.yml: "global:\n scrape_interval: 30s\n\nalerting:\n alertmanagers:\n
\ - static_configs:\n - targets:\n - stackrox-monitoring-alertmanager:9093\n\nrule_files:\n
\ - /etc/prometheus/rules_*.yml\n\nscrape_configs:\n |-\n - job_name: \"kubernetes-pods\"\n
\ tls_config:\n insecure_skip_verify: false\n kubernetes_sd_configs:\n
\ - role: pod\n namespaces:\n own_namespace: true\n
\ relabel_configs:\n - action: labelmap\n regex: __meta_kubernetes_pod_label_(.+)\n
\ - source_labels: [__meta_kubernetes_namespace]\n action: replace\n
\ target_label: namespace\n - source_labels: [__meta_kubernetes_pod_name]\n
\ action: replace\n target_label: pod\n - source_labels:
[__meta_kubernetes_pod_node_name]\n action: replace\n target_label:
node_name\n \n - job_name: \"kubernetes-cadvisor\"\n scheme: https\n
\ metrics_path: /metrics/cadvisor\n tls_config:\n ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt\n
\ insecure_skip_verify: true\n authorization:\n credentials_file:
/var/run/secrets/kubernetes.io/serviceaccount/token\n kubernetes_sd_configs:\n
\ - role: node\n relabel_configs:\n - action: labelmap\n regex:
__meta_kubernetes_node_label_(.+)\n \n - job_name: stackrox\n tls_config:\n
\ insecure_skip_verify: false\n kubernetes_sd_configs:\n - role:
endpoints\n namespaces:\n own_namespace: true\n relabel_configs:\n
\ - source_labels: [__meta_kubernetes_endpoint_port_name]\n action:
keep\n regex: monitoring\n - source_labels: [__meta_kubernetes_endpoints_name]\n
\ action: replace\n target_label: job\n - source_labels:
[__meta_kubernetes_namespace]\n action: replace\n target_label:
namespace\n - source_labels: [__meta_kubernetes_endpoint_node_name]\n action:
replace\n target_label: node_name"
rules_custom.yml: |-
|-
groups:
- name: Kubernetes
rules:
- alert: KubernetesContainerOomKiller
expr: (kube_pod_container_status_restarts_total - kube_pod_container_status_restarts_total offset 10m >= 1) and ignoring (reason) min_over_time(kube_pod_container_status_last_terminated_reason{reason="OOMKilled"}[10m]) == 1
for: 0m
labels:
severity: warning
annotations:
summary: Kubernetes container OOM killer (pod {{ "{{" }} .exported_pod {{ "}}" }})
description: "Container {{ "{{" }} .container {{ "}}" }} in pod {{ "{{" }} .exported_namespace {{ "}}" }}/{{ "{{" }} .exported_pod {{ "}}" }} has been OOMKilled {{ "{{" }} {{ "}}" }} times in the last 10 minutes."
- alert: KubernetesPodCrashLooping
expr: increase(kube_pod_container_status_restarts_total[5m]) > 0
for: 2m
labels:
severity: warning
annotations:
summary: Kubernetes pod crash looping (pod {{ "{{" }} .exported_pod {{ "}}" }})
description: "Pod {{ "{{" }} .exported_namespace {{ "}}" }}/{{ "{{" }} .exported_pod {{ "}}" }} is crash looping."
- alert: KubernetesReplicaSetMismatch
expr: kube_replicaset_spec_replicas != kube_replicaset_status_ready_replicas
for: 10m
labels:
severity: warning
annotations:
summary: Kubernetes ReplicaSet mismatch (replicaset {{ "{{" }} .replicaset {{ "}}" }})
description: "Replicas mismatch in ReplicaSet {{ "{{" }} .exported_namespace {{ "}}" }}/{{ "{{" }} .replicaset {{ "}}" }}"
kind: ConfigMap
metadata:
annotations:
meta.helm.sh/release-name: stackrox-monitoring
meta.helm.sh/release-namespace: stackrox
creationTimestamp: "2025-10-03T00:00:19Z"
labels:
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: stackrox
name: prometheus
namespace: stackrox
resourceVersion: "1759449619961263014"
uid: e2acf091-fe60-4ba3-9c91-b49dc5096827

@vikin91vikin91 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes look good!

I tried testing this branch with stackrox/stackrox#17146 but in the action execution, I saw that the code from the actions repository is hardcoded to main:

Download action repository 'stackrox/actions@main' (SHA:cc8a9579ba6de41d3b77b32403bf0f5e8809649d)

See: https://github.com/stackrox/stackrox/actions/runs/18283349491/job/52051757197

I will give you then a token of trust in regard that this has been tested and works correctly.

@JoukoVirtanen

Copy link
Copy Markdown
ContributorAuthor

The changes look good!

I tried testing this branch with stackrox/stackrox#17146 but in the action execution, I saw that the code from the actions repository is hardcoded to main:

Download action repository 'stackrox/actions@main' (SHA:cc8a9579ba6de41d3b77b32403bf0f5e8809649d)

See: https://github.com/stackrox/stackrox/actions/runs/18283349491/job/52051757197

I will give you then a token of trust in regard that this has been tested and works correctly.

To test this I created a branch in stackrox/test-gh-actions. In that branch I changed the occurrences of v1 in .github/workflows/create-clusters.yml to this branch. That makes it so that the actions in this branch are used.

You need to change

uses: stackrox/actions/.github/workflows/create-demo-clusters.yml@v1

and

workflow-ref: v1

@JoukoVirtanen
JoukoVirtanen dismissed tommartensen’s stale reviewOctober 6, 2025 22:51

He is on vacation and this should go in before the long running cluster is created for 4.9.

@JoukoVirtanen
JoukoVirtanen merged commit 09b66ab into mainOct 6, 2025
3 checks passed
@JoukoVirtanen
JoukoVirtanen deleted the jv-ROX-28976-optimize-berserker-load-in-long-running-cluster branch October 6, 2025 22:51
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@JoukoVirtanen@tommartensen@vikin91
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' ROX-28976: Optimize berserker load in long running cluster by JoukoVirtanen · Pull Request #64 · stackrox/actions · GitHub
Skip to content

ROX-28976: Optimize berserker load in long running cluster - #64

Merged
JoukoVirtanen merged 16 commits into
mainfrom
jv-ROX-28976-optimize-berserker-load-in-long-running-cluster
Oct 6, 2025
Merged

ROX-28976: Optimize berserker load in long running cluster#64
JoukoVirtanen merged 16 commits into
mainfrom
jv-ROX-28976-optimize-berserker-load-in-long-running-cluster

Conversation

@JoukoVirtanen

@JoukoVirtanenJoukoVirtanen commented Sep 5, 2025

Copy link
Copy Markdown
Contributor

Recently there were changes to the berserker load for the long running cluster. One of the changes was an increase in the number of berserker pods. Currently Prometheus scrapes metrics on all of the pods in the long running cluster including berserker pods. With the increased number of berserker pods, Prometheus began to OOM. To fix this Prometheus is switched to a different config that filters out some, but not all of the metrics for berserker pods. The memory requests and limits are also increased.

The changes to the berserker load is already merged and was used for testing this PR. stackrox/stackrox#15886

Changes were made here after testing the above PR. A new tag, 0.0.51, was created based off of a recent master, and was used to test the changes here.

@JoukoVirtanen
JoukoVirtanen requested a review from a team as a code ownerSeptember 5, 2025 15:07
@JoukoVirtanen
JoukoVirtanen marked this pull request as draft September 13, 2025 18:28
@JoukoVirtanenJoukoVirtanen changed the title Jv rox 28976 optimize berserker load in long running clusterROX-28976: Optimize berserker load in long running clusterSep 29, 2025
@JoukoVirtanen
JoukoVirtanen marked this pull request as ready for review September 29, 2025 04:39
"name": "prometheus",
"resources": {
"requests": {
"memory": "2Gi",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about we request 8Gi to prevent OOMKills because the node runs out of memory, if it is overcommitted?

If you change this here, please verify in another long-running cluster that Prometheus is starting (as I am unsure if there are 8Gi available on each node with ACS' requirements too).

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

tommartensen
tommartensen previously requested changes Sep 29, 2025

# Replace the prometheus ConfigMap with one that doesn't scrape as much info from berserker containers
kubectl -n stackrox delete configmap prometheus
kubectl create -f "${SCRIPT_DIR}"/prometheus.yaml

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer if we can override the offending values in the monitoring chart. Can you check if that is possible? Same with the update to the monitoring deploment.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean you want me to make the changes in stackrox/stackrox? I feel like 8Gi is too much for every case that the monitoring pod is used. I could make the changes to prometheus.yaml in stackrox/stackrox, but didn't want to pollute it with references to berserker.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I now use yq to set memory limit and request to 8Gi.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would simply copy the ../charts/monitoring/values.yaml and create a berserker-values.yaml to later use it directly, but the approach with yq is okay for me.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tommartensen Requested the use of yq in a private conversation and it is okay with me too.

@JoukoVirtanen
JoukoVirtanenforce-pushed the jv-ROX-28976-optimize-berserker-load-in-long-running-cluster branch from 7d3f49d to 04a2cb7CompareSeptember 30, 2025 04:37
@JoukoVirtanen
JoukoVirtanen requested review from tommartensen and vikin91 and removed request for vikin91October 1, 2025 03:00
sed '/captureStart/d' "${KUBE_BURNER_METRICS_FILE}" > "$temp_metrics_file"
kubectl create configmap --from-file="$temp_metrics_file" kube-burner-metrics-config -n kube-burner

kubectl create configmap --from-file="$KUBE_BURNER_METRICS_FILE" kube-burner-metrics-config -n kube-burner

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we don't need that anymore?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We didn't need it in the first place. It is redundant with the line above it.

@tommartensen

Copy link
Copy Markdown
Collaborator

I believe we're running in circles here and on Slack, so here is my (untested) counterproposal:

What I would like to avoid is duplicating much of the Prometheus config (it might change) and have changes to the configuration obscured. I believe that it is cleaner to use the Helm built-in capabilities for overrides than to update values files with yq or deleting and re-creating Configmaps outside of the Helm cycle.

@JoukoVirtanen

JoukoVirtanen commented Oct 2, 2025

Copy link
Copy Markdown
ContributorAuthor

I believe we're running in circles here and on Slack, so here is my (untested) counterproposal:

What I would like to avoid is duplicating much of the Prometheus config (it might change) and have changes to the configuration obscured. I believe that it is cleaner to use the Helm built-in capabilities for overrides than to update values files with yq or deleting and re-creating Configmaps outside of the Helm cycle.

Thank you for putting together this counter proposal. I really like it when reviewers make the effort to create new branches and PRs. However, I think there might be a flaw in your proposal. Your proposal requires changes in both stackrox/stackrox and here. The problem with that is sometimes long running clusters are created for the release branches. If we go with your approach we would also need backports for the release branches in stackrox/stackrox, otherwise the code here would be incompatible with the helm charts for the monitoring deployment in stackrox/stackrox. Perhaps we can merge this as is and create a ticket to go with your approach. I will test your approach and let you know how it goes.

@tommartensen

tommartensen commented Oct 2, 2025

Copy link
Copy Markdown
Collaborator

Your proposal requires changes in both stackrox/stackrox and here.

I think that is a fundamental flaw in how this berserker thing is setup and should be addressed separately.

The problem with that is sometimes long running clusters are created for the release branches.

That shouldn't happen, can you point me to instances where this led to a problem?

Perhaps we can merge this as is and create a ticket to go with your approach.

I will be out-of-office in the next days. Please create a ticket to follow-up on this PR with the values improvements in ROX-10657 and work with someone in @stackrox/release-improvers to get this PR merged.

@JoukoVirtanen

JoukoVirtanen commented Oct 2, 2025

Copy link
Copy Markdown
ContributorAuthor

Your proposal requires changes in both stackrox/stackrox and here.

I think that is a fundamental flaw in how this berserker thing is setup and should be addressed separately.

I agree. I am not sure what the solution is. Though, I have a mini design proposal with some ideas on preventing breaking changes to the long running cluster https://docs.google.com/document/d/1Vfq1piBebKwAE9EvjNdb7P_TTO1kAgZvCzcPTqx-Nvg/edit?usp=sharing

It hasn't gotten much attention and hasn't gone anywhere.

The problem with that is sometimes long running clusters are created for the release branches.

That shouldn't happen, can you point me to instances where this led to a problem?

Sometimes long running clusters are needed for patch releases. In one case there was a release that had a memory leak which was fixed in a patch. The long running cluster was helpful with that.

One case in which problems occurred for patch releases was when metrics were sent to OpenSearch. There were changes in stackrox/stackrox that had to be made to get to work. Initially changes were made in stackrox/actions to detect what version of stackrox/stackrox was using and use different scripts based off of that. An old script was used for old release branches and a new script was for the current release. The changes to stackrox/stackrox were backported to older release branches. In the time between when the backports were merged and the logic of which script to use in stackrox/actions was updated, a long running cluster for an old release branch was created. That long running cluster failed. stackrox/actions had to be updated and then another long running cluster was successfully created for the patch release.

Perhaps we can merge this as is and create a ticket to go with your approach.

I will be out-of-office in the next days. Please create a ticket to follow-up on this PR with the values improvements in ROX-10657 and work with someone in @stackrox/release-improvers to get this PR merged.

I have created the following ticket https://issues.redhat.com/browse/ROX-31149

@JoukoVirtanen

Copy link
Copy Markdown
ContributorAuthor

@tommartensen I have tested your PRs. It didn't work. I think your idea is sound. There might just be some small mistake somewhere. I ran the following test.

I created a branch from stackrox/stackrox#17105 and tagged it 0.0.52. I then created a new branch in stackrox/test-gh-actions. In that branch I changed the refs in .github/workflows/create-clusters.yml to tm/override-helm-values-berserker. I then created a new long running cluster at https://github.com/stackrox/test-gh-actions/actions/workflows/create-clusters.yml with the branch set to the one I created in stackrox/test-gh-actions and the version set to 0.0.52. When I checked the long running cluster the monitoring pod was in a crash loop. I checked the logs and found the following

$ ks logs monitoring-5b657c9fc5-6kstf -c prometheus
ts=2025-10-03T03:30:11.087Z caller=main.go:438 level=error msg="Error loading config (--config.file=/etc/prometheus/prometheus.yml)" file=/etc/prometheus/prometheus.yml err="parsing YAML file /etc/prometheus/prometheus.yml: yaml: unmarshal errors:\n line 14: cannot unmarshal !!str `- job_n...` into []*config.ScrapeConfig"

The Prometheus ConfigMap had the following

$ ks get configmap prometheus -o yaml
apiVersion: v1
data:
prometheus.yml: "global:\n scrape_interval: 30s\n\nalerting:\n alertmanagers:\n
\ - static_configs:\n - targets:\n - stackrox-monitoring-alertmanager:9093\n\nrule_files:\n
\ - /etc/prometheus/rules_*.yml\n\nscrape_configs:\n |-\n - job_name: \"kubernetes-pods\"\n
\ tls_config:\n insecure_skip_verify: false\n kubernetes_sd_configs:\n
\ - role: pod\n namespaces:\n own_namespace: true\n
\ relabel_configs:\n - action: labelmap\n regex: __meta_kubernetes_pod_label_(.+)\n
\ - source_labels: [__meta_kubernetes_namespace]\n action: replace\n
\ target_label: namespace\n - source_labels: [__meta_kubernetes_pod_name]\n
\ action: replace\n target_label: pod\n - source_labels:
[__meta_kubernetes_pod_node_name]\n action: replace\n target_label:
node_name\n \n - job_name: \"kubernetes-cadvisor\"\n scheme: https\n
\ metrics_path: /metrics/cadvisor\n tls_config:\n ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt\n
\ insecure_skip_verify: true\n authorization:\n credentials_file:
/var/run/secrets/kubernetes.io/serviceaccount/token\n kubernetes_sd_configs:\n
\ - role: node\n relabel_configs:\n - action: labelmap\n regex:
__meta_kubernetes_node_label_(.+)\n \n - job_name: stackrox\n tls_config:\n
\ insecure_skip_verify: false\n kubernetes_sd_configs:\n - role:
endpoints\n namespaces:\n own_namespace: true\n relabel_configs:\n
\ - source_labels: [__meta_kubernetes_endpoint_port_name]\n action:
keep\n regex: monitoring\n - source_labels: [__meta_kubernetes_endpoints_name]\n
\ action: replace\n target_label: job\n - source_labels:
[__meta_kubernetes_namespace]\n action: replace\n target_label:
namespace\n - source_labels: [__meta_kubernetes_endpoint_node_name]\n action:
replace\n target_label: node_name"
rules_custom.yml: |-
|-
groups:
- name: Kubernetes
rules:
- alert: KubernetesContainerOomKiller
expr: (kube_pod_container_status_restarts_total - kube_pod_container_status_restarts_total offset 10m >= 1) and ignoring (reason) min_over_time(kube_pod_container_status_last_terminated_reason{reason="OOMKilled"}[10m]) == 1
for: 0m
labels:
severity: warning
annotations:
summary: Kubernetes container OOM killer (pod {{ "{{" }} .exported_pod {{ "}}" }})
description: "Container {{ "{{" }} .container {{ "}}" }} in pod {{ "{{" }} .exported_namespace {{ "}}" }}/{{ "{{" }} .exported_pod {{ "}}" }} has been OOMKilled {{ "{{" }} {{ "}}" }} times in the last 10 minutes."
- alert: KubernetesPodCrashLooping
expr: increase(kube_pod_container_status_restarts_total[5m]) > 0
for: 2m
labels:
severity: warning
annotations:
summary: Kubernetes pod crash looping (pod {{ "{{" }} .exported_pod {{ "}}" }})
description: "Pod {{ "{{" }} .exported_namespace {{ "}}" }}/{{ "{{" }} .exported_pod {{ "}}" }} is crash looping."
- alert: KubernetesReplicaSetMismatch
expr: kube_replicaset_spec_replicas != kube_replicaset_status_ready_replicas
for: 10m
labels:
severity: warning
annotations:
summary: Kubernetes ReplicaSet mismatch (replicaset {{ "{{" }} .replicaset {{ "}}" }})
description: "Replicas mismatch in ReplicaSet {{ "{{" }} .exported_namespace {{ "}}" }}/{{ "{{" }} .replicaset {{ "}}" }}"
kind: ConfigMap
metadata:
annotations:
meta.helm.sh/release-name: stackrox-monitoring
meta.helm.sh/release-namespace: stackrox
creationTimestamp: "2025-10-03T00:00:19Z"
labels:
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: stackrox
name: prometheus
namespace: stackrox
resourceVersion: "1759449619961263014"
uid: e2acf091-fe60-4ba3-9c91-b49dc5096827

@vikin91vikin91 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes look good!

I tried testing this branch with stackrox/stackrox#17146 but in the action execution, I saw that the code from the actions repository is hardcoded to main:

Download action repository 'stackrox/actions@main' (SHA:cc8a9579ba6de41d3b77b32403bf0f5e8809649d)

See: https://github.com/stackrox/stackrox/actions/runs/18283349491/job/52051757197

I will give you then a token of trust in regard that this has been tested and works correctly.

@JoukoVirtanen

Copy link
Copy Markdown
ContributorAuthor

The changes look good!

I tried testing this branch with stackrox/stackrox#17146 but in the action execution, I saw that the code from the actions repository is hardcoded to main:

Download action repository 'stackrox/actions@main' (SHA:cc8a9579ba6de41d3b77b32403bf0f5e8809649d)

See: https://github.com/stackrox/stackrox/actions/runs/18283349491/job/52051757197

I will give you then a token of trust in regard that this has been tested and works correctly.

To test this I created a branch in stackrox/test-gh-actions. In that branch I changed the occurrences of v1 in .github/workflows/create-clusters.yml to this branch. That makes it so that the actions in this branch are used.

You need to change

uses: stackrox/actions/.github/workflows/create-demo-clusters.yml@v1

and

workflow-ref: v1

@JoukoVirtanen
JoukoVirtanen dismissed tommartensen’s stale reviewOctober 6, 2025 22:51

He is on vacation and this should go in before the long running cluster is created for 4.9.

@JoukoVirtanen
JoukoVirtanen merged commit 09b66ab into mainOct 6, 2025
3 checks passed
@JoukoVirtanen
JoukoVirtanen deleted the jv-ROX-28976-optimize-berserker-load-in-long-running-cluster branch October 6, 2025 22:51
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@JoukoVirtanen@tommartensen@vikin91
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' ROX-28976: Optimize berserker load in long running cluster by JoukoVirtanen · Pull Request #64 · stackrox/actions · GitHub
Skip to content

ROX-28976: Optimize berserker load in long running cluster - #64

Merged
JoukoVirtanen merged 16 commits into
mainfrom
jv-ROX-28976-optimize-berserker-load-in-long-running-cluster
Oct 6, 2025
Merged

ROX-28976: Optimize berserker load in long running cluster#64
JoukoVirtanen merged 16 commits into
mainfrom
jv-ROX-28976-optimize-berserker-load-in-long-running-cluster

Conversation

@JoukoVirtanen

@JoukoVirtanenJoukoVirtanen commented Sep 5, 2025

Copy link
Copy Markdown
Contributor

Recently there were changes to the berserker load for the long running cluster. One of the changes was an increase in the number of berserker pods. Currently Prometheus scrapes metrics on all of the pods in the long running cluster including berserker pods. With the increased number of berserker pods, Prometheus began to OOM. To fix this Prometheus is switched to a different config that filters out some, but not all of the metrics for berserker pods. The memory requests and limits are also increased.

The changes to the berserker load is already merged and was used for testing this PR. stackrox/stackrox#15886

Changes were made here after testing the above PR. A new tag, 0.0.51, was created based off of a recent master, and was used to test the changes here.

@JoukoVirtanen
JoukoVirtanen requested a review from a team as a code ownerSeptember 5, 2025 15:07
@JoukoVirtanen
JoukoVirtanen marked this pull request as draft September 13, 2025 18:28
@JoukoVirtanenJoukoVirtanen changed the title Jv rox 28976 optimize berserker load in long running clusterROX-28976: Optimize berserker load in long running clusterSep 29, 2025
@JoukoVirtanen
JoukoVirtanen marked this pull request as ready for review September 29, 2025 04:39
"name": "prometheus",
"resources": {
"requests": {
"memory": "2Gi",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about we request 8Gi to prevent OOMKills because the node runs out of memory, if it is overcommitted?

If you change this here, please verify in another long-running cluster that Prometheus is starting (as I am unsure if there are 8Gi available on each node with ACS' requirements too).

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

tommartensen
tommartensen previously requested changes Sep 29, 2025

# Replace the prometheus ConfigMap with one that doesn't scrape as much info from berserker containers
kubectl -n stackrox delete configmap prometheus
kubectl create -f "${SCRIPT_DIR}"/prometheus.yaml

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer if we can override the offending values in the monitoring chart. Can you check if that is possible? Same with the update to the monitoring deploment.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean you want me to make the changes in stackrox/stackrox? I feel like 8Gi is too much for every case that the monitoring pod is used. I could make the changes to prometheus.yaml in stackrox/stackrox, but didn't want to pollute it with references to berserker.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I now use yq to set memory limit and request to 8Gi.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would simply copy the ../charts/monitoring/values.yaml and create a berserker-values.yaml to later use it directly, but the approach with yq is okay for me.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tommartensen Requested the use of yq in a private conversation and it is okay with me too.

@JoukoVirtanen
JoukoVirtanenforce-pushed the jv-ROX-28976-optimize-berserker-load-in-long-running-cluster branch from 7d3f49d to 04a2cb7CompareSeptember 30, 2025 04:37
@JoukoVirtanen
JoukoVirtanen requested review from tommartensen and vikin91 and removed request for vikin91October 1, 2025 03:00
sed '/captureStart/d' "${KUBE_BURNER_METRICS_FILE}" > "$temp_metrics_file"
kubectl create configmap --from-file="$temp_metrics_file" kube-burner-metrics-config -n kube-burner

kubectl create configmap --from-file="$KUBE_BURNER_METRICS_FILE" kube-burner-metrics-config -n kube-burner

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we don't need that anymore?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We didn't need it in the first place. It is redundant with the line above it.

@tommartensen

Copy link
Copy Markdown
Collaborator

I believe we're running in circles here and on Slack, so here is my (untested) counterproposal:

What I would like to avoid is duplicating much of the Prometheus config (it might change) and have changes to the configuration obscured. I believe that it is cleaner to use the Helm built-in capabilities for overrides than to update values files with yq or deleting and re-creating Configmaps outside of the Helm cycle.

@JoukoVirtanen

JoukoVirtanen commented Oct 2, 2025

Copy link
Copy Markdown
ContributorAuthor

I believe we're running in circles here and on Slack, so here is my (untested) counterproposal:

What I would like to avoid is duplicating much of the Prometheus config (it might change) and have changes to the configuration obscured. I believe that it is cleaner to use the Helm built-in capabilities for overrides than to update values files with yq or deleting and re-creating Configmaps outside of the Helm cycle.

Thank you for putting together this counter proposal. I really like it when reviewers make the effort to create new branches and PRs. However, I think there might be a flaw in your proposal. Your proposal requires changes in both stackrox/stackrox and here. The problem with that is sometimes long running clusters are created for the release branches. If we go with your approach we would also need backports for the release branches in stackrox/stackrox, otherwise the code here would be incompatible with the helm charts for the monitoring deployment in stackrox/stackrox. Perhaps we can merge this as is and create a ticket to go with your approach. I will test your approach and let you know how it goes.

@tommartensen

tommartensen commented Oct 2, 2025

Copy link
Copy Markdown
Collaborator

Your proposal requires changes in both stackrox/stackrox and here.

I think that is a fundamental flaw in how this berserker thing is setup and should be addressed separately.

The problem with that is sometimes long running clusters are created for the release branches.

That shouldn't happen, can you point me to instances where this led to a problem?

Perhaps we can merge this as is and create a ticket to go with your approach.

I will be out-of-office in the next days. Please create a ticket to follow-up on this PR with the values improvements in ROX-10657 and work with someone in @stackrox/release-improvers to get this PR merged.

@JoukoVirtanen

JoukoVirtanen commented Oct 2, 2025

Copy link
Copy Markdown
ContributorAuthor

Your proposal requires changes in both stackrox/stackrox and here.

I think that is a fundamental flaw in how this berserker thing is setup and should be addressed separately.

I agree. I am not sure what the solution is. Though, I have a mini design proposal with some ideas on preventing breaking changes to the long running cluster https://docs.google.com/document/d/1Vfq1piBebKwAE9EvjNdb7P_TTO1kAgZvCzcPTqx-Nvg/edit?usp=sharing

It hasn't gotten much attention and hasn't gone anywhere.

The problem with that is sometimes long running clusters are created for the release branches.

That shouldn't happen, can you point me to instances where this led to a problem?

Sometimes long running clusters are needed for patch releases. In one case there was a release that had a memory leak which was fixed in a patch. The long running cluster was helpful with that.

One case in which problems occurred for patch releases was when metrics were sent to OpenSearch. There were changes in stackrox/stackrox that had to be made to get to work. Initially changes were made in stackrox/actions to detect what version of stackrox/stackrox was using and use different scripts based off of that. An old script was used for old release branches and a new script was for the current release. The changes to stackrox/stackrox were backported to older release branches. In the time between when the backports were merged and the logic of which script to use in stackrox/actions was updated, a long running cluster for an old release branch was created. That long running cluster failed. stackrox/actions had to be updated and then another long running cluster was successfully created for the patch release.

Perhaps we can merge this as is and create a ticket to go with your approach.

I will be out-of-office in the next days. Please create a ticket to follow-up on this PR with the values improvements in ROX-10657 and work with someone in @stackrox/release-improvers to get this PR merged.

I have created the following ticket https://issues.redhat.com/browse/ROX-31149

@JoukoVirtanen

Copy link
Copy Markdown
ContributorAuthor

@tommartensen I have tested your PRs. It didn't work. I think your idea is sound. There might just be some small mistake somewhere. I ran the following test.

I created a branch from stackrox/stackrox#17105 and tagged it 0.0.52. I then created a new branch in stackrox/test-gh-actions. In that branch I changed the refs in .github/workflows/create-clusters.yml to tm/override-helm-values-berserker. I then created a new long running cluster at https://github.com/stackrox/test-gh-actions/actions/workflows/create-clusters.yml with the branch set to the one I created in stackrox/test-gh-actions and the version set to 0.0.52. When I checked the long running cluster the monitoring pod was in a crash loop. I checked the logs and found the following

$ ks logs monitoring-5b657c9fc5-6kstf -c prometheus
ts=2025-10-03T03:30:11.087Z caller=main.go:438 level=error msg="Error loading config (--config.file=/etc/prometheus/prometheus.yml)" file=/etc/prometheus/prometheus.yml err="parsing YAML file /etc/prometheus/prometheus.yml: yaml: unmarshal errors:\n line 14: cannot unmarshal !!str `- job_n...` into []*config.ScrapeConfig"

The Prometheus ConfigMap had the following

$ ks get configmap prometheus -o yaml
apiVersion: v1
data:
prometheus.yml: "global:\n scrape_interval: 30s\n\nalerting:\n alertmanagers:\n
\ - static_configs:\n - targets:\n - stackrox-monitoring-alertmanager:9093\n\nrule_files:\n
\ - /etc/prometheus/rules_*.yml\n\nscrape_configs:\n |-\n - job_name: \"kubernetes-pods\"\n
\ tls_config:\n insecure_skip_verify: false\n kubernetes_sd_configs:\n
\ - role: pod\n namespaces:\n own_namespace: true\n
\ relabel_configs:\n - action: labelmap\n regex: __meta_kubernetes_pod_label_(.+)\n
\ - source_labels: [__meta_kubernetes_namespace]\n action: replace\n
\ target_label: namespace\n - source_labels: [__meta_kubernetes_pod_name]\n
\ action: replace\n target_label: pod\n - source_labels:
[__meta_kubernetes_pod_node_name]\n action: replace\n target_label:
node_name\n \n - job_name: \"kubernetes-cadvisor\"\n scheme: https\n
\ metrics_path: /metrics/cadvisor\n tls_config:\n ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt\n
\ insecure_skip_verify: true\n authorization:\n credentials_file:
/var/run/secrets/kubernetes.io/serviceaccount/token\n kubernetes_sd_configs:\n
\ - role: node\n relabel_configs:\n - action: labelmap\n regex:
__meta_kubernetes_node_label_(.+)\n \n - job_name: stackrox\n tls_config:\n
\ insecure_skip_verify: false\n kubernetes_sd_configs:\n - role:
endpoints\n namespaces:\n own_namespace: true\n relabel_configs:\n
\ - source_labels: [__meta_kubernetes_endpoint_port_name]\n action:
keep\n regex: monitoring\n - source_labels: [__meta_kubernetes_endpoints_name]\n
\ action: replace\n target_label: job\n - source_labels:
[__meta_kubernetes_namespace]\n action: replace\n target_label:
namespace\n - source_labels: [__meta_kubernetes_endpoint_node_name]\n action:
replace\n target_label: node_name"
rules_custom.yml: |-
|-
groups:
- name: Kubernetes
rules:
- alert: KubernetesContainerOomKiller
expr: (kube_pod_container_status_restarts_total - kube_pod_container_status_restarts_total offset 10m >= 1) and ignoring (reason) min_over_time(kube_pod_container_status_last_terminated_reason{reason="OOMKilled"}[10m]) == 1
for: 0m
labels:
severity: warning
annotations:
summary: Kubernetes container OOM killer (pod {{ "{{" }} .exported_pod {{ "}}" }})
description: "Container {{ "{{" }} .container {{ "}}" }} in pod {{ "{{" }} .exported_namespace {{ "}}" }}/{{ "{{" }} .exported_pod {{ "}}" }} has been OOMKilled {{ "{{" }} {{ "}}" }} times in the last 10 minutes."
- alert: KubernetesPodCrashLooping
expr: increase(kube_pod_container_status_restarts_total[5m]) > 0
for: 2m
labels:
severity: warning
annotations:
summary: Kubernetes pod crash looping (pod {{ "{{" }} .exported_pod {{ "}}" }})
description: "Pod {{ "{{" }} .exported_namespace {{ "}}" }}/{{ "{{" }} .exported_pod {{ "}}" }} is crash looping."
- alert: KubernetesReplicaSetMismatch
expr: kube_replicaset_spec_replicas != kube_replicaset_status_ready_replicas
for: 10m
labels:
severity: warning
annotations:
summary: Kubernetes ReplicaSet mismatch (replicaset {{ "{{" }} .replicaset {{ "}}" }})
description: "Replicas mismatch in ReplicaSet {{ "{{" }} .exported_namespace {{ "}}" }}/{{ "{{" }} .replicaset {{ "}}" }}"
kind: ConfigMap
metadata:
annotations:
meta.helm.sh/release-name: stackrox-monitoring
meta.helm.sh/release-namespace: stackrox
creationTimestamp: "2025-10-03T00:00:19Z"
labels:
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: stackrox
name: prometheus
namespace: stackrox
resourceVersion: "1759449619961263014"
uid: e2acf091-fe60-4ba3-9c91-b49dc5096827

@vikin91vikin91 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes look good!

I tried testing this branch with stackrox/stackrox#17146 but in the action execution, I saw that the code from the actions repository is hardcoded to main:

Download action repository 'stackrox/actions@main' (SHA:cc8a9579ba6de41d3b77b32403bf0f5e8809649d)

See: https://github.com/stackrox/stackrox/actions/runs/18283349491/job/52051757197

I will give you then a token of trust in regard that this has been tested and works correctly.

@JoukoVirtanen

Copy link
Copy Markdown
ContributorAuthor

The changes look good!

I tried testing this branch with stackrox/stackrox#17146 but in the action execution, I saw that the code from the actions repository is hardcoded to main:

Download action repository 'stackrox/actions@main' (SHA:cc8a9579ba6de41d3b77b32403bf0f5e8809649d)

See: https://github.com/stackrox/stackrox/actions/runs/18283349491/job/52051757197

I will give you then a token of trust in regard that this has been tested and works correctly.

To test this I created a branch in stackrox/test-gh-actions. In that branch I changed the occurrences of v1 in .github/workflows/create-clusters.yml to this branch. That makes it so that the actions in this branch are used.

You need to change

uses: stackrox/actions/.github/workflows/create-demo-clusters.yml@v1

and

workflow-ref: v1

@JoukoVirtanen
JoukoVirtanen dismissed tommartensen’s stale reviewOctober 6, 2025 22:51

He is on vacation and this should go in before the long running cluster is created for 4.9.

@JoukoVirtanen
JoukoVirtanen merged commit 09b66ab into mainOct 6, 2025
3 checks passed
@JoukoVirtanen
JoukoVirtanen deleted the jv-ROX-28976-optimize-berserker-load-in-long-running-cluster branch October 6, 2025 22:51
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@JoukoVirtanen@tommartensen@vikin91
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); ROX-28976: Optimize berserker load in long running cluster by JoukoVirtanen · Pull Request #64 · stackrox/actions · GitHub
Skip to content

ROX-28976: Optimize berserker load in long running cluster - #64

Merged
JoukoVirtanen merged 16 commits into
mainfrom
jv-ROX-28976-optimize-berserker-load-in-long-running-cluster
Oct 6, 2025
Merged

ROX-28976: Optimize berserker load in long running cluster#64
JoukoVirtanen merged 16 commits into
mainfrom
jv-ROX-28976-optimize-berserker-load-in-long-running-cluster

Conversation

@JoukoVirtanen

@JoukoVirtanenJoukoVirtanen commented Sep 5, 2025

Copy link
Copy Markdown
Contributor

Recently there were changes to the berserker load for the long running cluster. One of the changes was an increase in the number of berserker pods. Currently Prometheus scrapes metrics on all of the pods in the long running cluster including berserker pods. With the increased number of berserker pods, Prometheus began to OOM. To fix this Prometheus is switched to a different config that filters out some, but not all of the metrics for berserker pods. The memory requests and limits are also increased.

The changes to the berserker load is already merged and was used for testing this PR. stackrox/stackrox#15886

Changes were made here after testing the above PR. A new tag, 0.0.51, was created based off of a recent master, and was used to test the changes here.

@JoukoVirtanen
JoukoVirtanen requested a review from a team as a code ownerSeptember 5, 2025 15:07
@JoukoVirtanen
JoukoVirtanen marked this pull request as draft September 13, 2025 18:28
@JoukoVirtanenJoukoVirtanen changed the title Jv rox 28976 optimize berserker load in long running clusterROX-28976: Optimize berserker load in long running clusterSep 29, 2025
@JoukoVirtanen
JoukoVirtanen marked this pull request as ready for review September 29, 2025 04:39
"name": "prometheus",
"resources": {
"requests": {
"memory": "2Gi",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about we request 8Gi to prevent OOMKills because the node runs out of memory, if it is overcommitted?

If you change this here, please verify in another long-running cluster that Prometheus is starting (as I am unsure if there are 8Gi available on each node with ACS' requirements too).

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

tommartensen
tommartensen previously requested changes Sep 29, 2025

# Replace the prometheus ConfigMap with one that doesn't scrape as much info from berserker containers
kubectl -n stackrox delete configmap prometheus
kubectl create -f "${SCRIPT_DIR}"/prometheus.yaml

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer if we can override the offending values in the monitoring chart. Can you check if that is possible? Same with the update to the monitoring deploment.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean you want me to make the changes in stackrox/stackrox? I feel like 8Gi is too much for every case that the monitoring pod is used. I could make the changes to prometheus.yaml in stackrox/stackrox, but didn't want to pollute it with references to berserker.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I now use yq to set memory limit and request to 8Gi.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would simply copy the ../charts/monitoring/values.yaml and create a berserker-values.yaml to later use it directly, but the approach with yq is okay for me.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tommartensen Requested the use of yq in a private conversation and it is okay with me too.

@JoukoVirtanen
JoukoVirtanenforce-pushed the jv-ROX-28976-optimize-berserker-load-in-long-running-cluster branch from 7d3f49d to 04a2cb7CompareSeptember 30, 2025 04:37
@JoukoVirtanen
JoukoVirtanen requested review from tommartensen and vikin91 and removed request for vikin91October 1, 2025 03:00
sed '/captureStart/d' "${KUBE_BURNER_METRICS_FILE}" > "$temp_metrics_file"
kubectl create configmap --from-file="$temp_metrics_file" kube-burner-metrics-config -n kube-burner

kubectl create configmap --from-file="$KUBE_BURNER_METRICS_FILE" kube-burner-metrics-config -n kube-burner

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we don't need that anymore?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We didn't need it in the first place. It is redundant with the line above it.

@tommartensen

Copy link
Copy Markdown
Collaborator

I believe we're running in circles here and on Slack, so here is my (untested) counterproposal:

What I would like to avoid is duplicating much of the Prometheus config (it might change) and have changes to the configuration obscured. I believe that it is cleaner to use the Helm built-in capabilities for overrides than to update values files with yq or deleting and re-creating Configmaps outside of the Helm cycle.

@JoukoVirtanen

JoukoVirtanen commented Oct 2, 2025

Copy link
Copy Markdown
ContributorAuthor

I believe we're running in circles here and on Slack, so here is my (untested) counterproposal:

What I would like to avoid is duplicating much of the Prometheus config (it might change) and have changes to the configuration obscured. I believe that it is cleaner to use the Helm built-in capabilities for overrides than to update values files with yq or deleting and re-creating Configmaps outside of the Helm cycle.

Thank you for putting together this counter proposal. I really like it when reviewers make the effort to create new branches and PRs. However, I think there might be a flaw in your proposal. Your proposal requires changes in both stackrox/stackrox and here. The problem with that is sometimes long running clusters are created for the release branches. If we go with your approach we would also need backports for the release branches in stackrox/stackrox, otherwise the code here would be incompatible with the helm charts for the monitoring deployment in stackrox/stackrox. Perhaps we can merge this as is and create a ticket to go with your approach. I will test your approach and let you know how it goes.

@tommartensen

tommartensen commented Oct 2, 2025

Copy link
Copy Markdown
Collaborator

Your proposal requires changes in both stackrox/stackrox and here.

I think that is a fundamental flaw in how this berserker thing is setup and should be addressed separately.

The problem with that is sometimes long running clusters are created for the release branches.

That shouldn't happen, can you point me to instances where this led to a problem?

Perhaps we can merge this as is and create a ticket to go with your approach.

I will be out-of-office in the next days. Please create a ticket to follow-up on this PR with the values improvements in ROX-10657 and work with someone in @stackrox/release-improvers to get this PR merged.

@JoukoVirtanen

JoukoVirtanen commented Oct 2, 2025

Copy link
Copy Markdown
ContributorAuthor

Your proposal requires changes in both stackrox/stackrox and here.

I think that is a fundamental flaw in how this berserker thing is setup and should be addressed separately.

I agree. I am not sure what the solution is. Though, I have a mini design proposal with some ideas on preventing breaking changes to the long running cluster https://docs.google.com/document/d/1Vfq1piBebKwAE9EvjNdb7P_TTO1kAgZvCzcPTqx-Nvg/edit?usp=sharing

It hasn't gotten much attention and hasn't gone anywhere.

The problem with that is sometimes long running clusters are created for the release branches.

That shouldn't happen, can you point me to instances where this led to a problem?

Sometimes long running clusters are needed for patch releases. In one case there was a release that had a memory leak which was fixed in a patch. The long running cluster was helpful with that.

One case in which problems occurred for patch releases was when metrics were sent to OpenSearch. There were changes in stackrox/stackrox that had to be made to get to work. Initially changes were made in stackrox/actions to detect what version of stackrox/stackrox was using and use different scripts based off of that. An old script was used for old release branches and a new script was for the current release. The changes to stackrox/stackrox were backported to older release branches. In the time between when the backports were merged and the logic of which script to use in stackrox/actions was updated, a long running cluster for an old release branch was created. That long running cluster failed. stackrox/actions had to be updated and then another long running cluster was successfully created for the patch release.

Perhaps we can merge this as is and create a ticket to go with your approach.

I will be out-of-office in the next days. Please create a ticket to follow-up on this PR with the values improvements in ROX-10657 and work with someone in @stackrox/release-improvers to get this PR merged.

I have created the following ticket https://issues.redhat.com/browse/ROX-31149

@JoukoVirtanen

Copy link
Copy Markdown
ContributorAuthor

@tommartensen I have tested your PRs. It didn't work. I think your idea is sound. There might just be some small mistake somewhere. I ran the following test.

I created a branch from stackrox/stackrox#17105 and tagged it 0.0.52. I then created a new branch in stackrox/test-gh-actions. In that branch I changed the refs in .github/workflows/create-clusters.yml to tm/override-helm-values-berserker. I then created a new long running cluster at https://github.com/stackrox/test-gh-actions/actions/workflows/create-clusters.yml with the branch set to the one I created in stackrox/test-gh-actions and the version set to 0.0.52. When I checked the long running cluster the monitoring pod was in a crash loop. I checked the logs and found the following

$ ks logs monitoring-5b657c9fc5-6kstf -c prometheus
ts=2025-10-03T03:30:11.087Z caller=main.go:438 level=error msg="Error loading config (--config.file=/etc/prometheus/prometheus.yml)" file=/etc/prometheus/prometheus.yml err="parsing YAML file /etc/prometheus/prometheus.yml: yaml: unmarshal errors:\n line 14: cannot unmarshal !!str `- job_n...` into []*config.ScrapeConfig"

The Prometheus ConfigMap had the following

$ ks get configmap prometheus -o yaml
apiVersion: v1
data:
prometheus.yml: "global:\n scrape_interval: 30s\n\nalerting:\n alertmanagers:\n
\ - static_configs:\n - targets:\n - stackrox-monitoring-alertmanager:9093\n\nrule_files:\n
\ - /etc/prometheus/rules_*.yml\n\nscrape_configs:\n |-\n - job_name: \"kubernetes-pods\"\n
\ tls_config:\n insecure_skip_verify: false\n kubernetes_sd_configs:\n
\ - role: pod\n namespaces:\n own_namespace: true\n
\ relabel_configs:\n - action: labelmap\n regex: __meta_kubernetes_pod_label_(.+)\n
\ - source_labels: [__meta_kubernetes_namespace]\n action: replace\n
\ target_label: namespace\n - source_labels: [__meta_kubernetes_pod_name]\n
\ action: replace\n target_label: pod\n - source_labels:
[__meta_kubernetes_pod_node_name]\n action: replace\n target_label:
node_name\n \n - job_name: \"kubernetes-cadvisor\"\n scheme: https\n
\ metrics_path: /metrics/cadvisor\n tls_config:\n ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt\n
\ insecure_skip_verify: true\n authorization:\n credentials_file:
/var/run/secrets/kubernetes.io/serviceaccount/token\n kubernetes_sd_configs:\n
\ - role: node\n relabel_configs:\n - action: labelmap\n regex:
__meta_kubernetes_node_label_(.+)\n \n - job_name: stackrox\n tls_config:\n
\ insecure_skip_verify: false\n kubernetes_sd_configs:\n - role:
endpoints\n namespaces:\n own_namespace: true\n relabel_configs:\n
\ - source_labels: [__meta_kubernetes_endpoint_port_name]\n action:
keep\n regex: monitoring\n - source_labels: [__meta_kubernetes_endpoints_name]\n
\ action: replace\n target_label: job\n - source_labels:
[__meta_kubernetes_namespace]\n action: replace\n target_label:
namespace\n - source_labels: [__meta_kubernetes_endpoint_node_name]\n action:
replace\n target_label: node_name"
rules_custom.yml: |-
|-
groups:
- name: Kubernetes
rules:
- alert: KubernetesContainerOomKiller
expr: (kube_pod_container_status_restarts_total - kube_pod_container_status_restarts_total offset 10m >= 1) and ignoring (reason) min_over_time(kube_pod_container_status_last_terminated_reason{reason="OOMKilled"}[10m]) == 1
for: 0m
labels:
severity: warning
annotations:
summary: Kubernetes container OOM killer (pod {{ "{{" }} .exported_pod {{ "}}" }})
description: "Container {{ "{{" }} .container {{ "}}" }} in pod {{ "{{" }} .exported_namespace {{ "}}" }}/{{ "{{" }} .exported_pod {{ "}}" }} has been OOMKilled {{ "{{" }} {{ "}}" }} times in the last 10 minutes."
- alert: KubernetesPodCrashLooping
expr: increase(kube_pod_container_status_restarts_total[5m]) > 0
for: 2m
labels:
severity: warning
annotations:
summary: Kubernetes pod crash looping (pod {{ "{{" }} .exported_pod {{ "}}" }})
description: "Pod {{ "{{" }} .exported_namespace {{ "}}" }}/{{ "{{" }} .exported_pod {{ "}}" }} is crash looping."
- alert: KubernetesReplicaSetMismatch
expr: kube_replicaset_spec_replicas != kube_replicaset_status_ready_replicas
for: 10m
labels:
severity: warning
annotations:
summary: Kubernetes ReplicaSet mismatch (replicaset {{ "{{" }} .replicaset {{ "}}" }})
description: "Replicas mismatch in ReplicaSet {{ "{{" }} .exported_namespace {{ "}}" }}/{{ "{{" }} .replicaset {{ "}}" }}"
kind: ConfigMap
metadata:
annotations:
meta.helm.sh/release-name: stackrox-monitoring
meta.helm.sh/release-namespace: stackrox
creationTimestamp: "2025-10-03T00:00:19Z"
labels:
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: stackrox
name: prometheus
namespace: stackrox
resourceVersion: "1759449619961263014"
uid: e2acf091-fe60-4ba3-9c91-b49dc5096827

@vikin91vikin91 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes look good!

I tried testing this branch with stackrox/stackrox#17146 but in the action execution, I saw that the code from the actions repository is hardcoded to main:

Download action repository 'stackrox/actions@main' (SHA:cc8a9579ba6de41d3b77b32403bf0f5e8809649d)

See: https://github.com/stackrox/stackrox/actions/runs/18283349491/job/52051757197

I will give you then a token of trust in regard that this has been tested and works correctly.

@JoukoVirtanen

Copy link
Copy Markdown
ContributorAuthor

The changes look good!

I tried testing this branch with stackrox/stackrox#17146 but in the action execution, I saw that the code from the actions repository is hardcoded to main:

Download action repository 'stackrox/actions@main' (SHA:cc8a9579ba6de41d3b77b32403bf0f5e8809649d)

See: https://github.com/stackrox/stackrox/actions/runs/18283349491/job/52051757197

I will give you then a token of trust in regard that this has been tested and works correctly.

To test this I created a branch in stackrox/test-gh-actions. In that branch I changed the occurrences of v1 in .github/workflows/create-clusters.yml to this branch. That makes it so that the actions in this branch are used.

You need to change

uses: stackrox/actions/.github/workflows/create-demo-clusters.yml@v1

and

workflow-ref: v1

@JoukoVirtanen
JoukoVirtanen dismissed tommartensen’s stale reviewOctober 6, 2025 22:51

He is on vacation and this should go in before the long running cluster is created for 4.9.

@JoukoVirtanen
JoukoVirtanen merged commit 09b66ab into mainOct 6, 2025
3 checks passed
@JoukoVirtanen
JoukoVirtanen deleted the jv-ROX-28976-optimize-berserker-load-in-long-running-cluster branch October 6, 2025 22:51
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@JoukoVirtanen@tommartensen@vikin91