Skip to content

Shared Utilities & Infrastructure - #6896

Open
george-kalisse-sada wants to merge 1 commit into
GoogleCloudPlatform:masterfrom
george-kalisse-sada:SADA_2_shared_utils
Open

Shared Utilities & Infrastructure#6896
george-kalisse-sada wants to merge 1 commit into
GoogleCloudPlatform:masterfrom
george-kalisse-sada:SADA_2_shared_utils

Conversation

@george-kalisse-sada

Copy link
Copy Markdown
Collaborator

Files: ~10 new files

  • perfkitbenchmarker/linux_benchmarks/kubernetes/__init__.py
  • perfkitbenchmarker/linux_benchmarks/kubernetes/agentic/__init__.py
  • perfkitbenchmarker/linux_benchmarks/kubernetes/agentic/README.md
  • perfkitbenchmarker/linux_benchmarks/kubernetes/agentic/k8s_benchmark_utils.py
  • perfkitbenchmarker/linux_benchmarks/kubernetes/agentic/gke_deploy_utils.py
  • perfkitbenchmarker/scripts/agentic/__init__.py
  • perfkitbenchmarker/scripts/agentic/README.md
  • perfkitbenchmarker/scripts/agentic/gke_image_build_utils.py
  • perfkitbenchmarker/scripts/agentic/gke_prerequisites.py
  • perfkitbenchmarker/scripts/agentic/gke_post_teardown.py

Description: Adds shared infrastructure for GKE Agent Sandbox benchmarks:

  • k8s_benchmark_utils.py — Agent API interaction, kubectl helpers, warm pool management, port-forward manager, PKB sample construction
  • gke_deploy_utils.py — Idempotent deployment of Agent Sandbox ecosystem (CRDs, SandboxTemplates, WarmPools, Router, ADK Agent) onto pre-provisioned GKE clusters
  • gke_image_build_utils.py — Container image builds (Chrome Sandbox, Sandbox Router) via Google Cloud Build with cross-architecture support (amd64/arm64)
  • gke_prerequisites.py — One-time GCP project setup (APIs, Artifact Registry, Cloud Build SA, image builds including native ARM64 VM builds)
  • gke_post_teardown.py — Cleanup of resources created by prerequisites

@hubatish

hubatish commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

/gcbrun

@roycaihw

roycaihw commented Aug 6, 2026

Copy link
Copy Markdown

/cc @Nishanth29

@Nishanth29

Copy link
Copy Markdown

Hi @george-kalisse-sada , it looks like the CI check Pull (bionic-baton-343) failed during execution. could you check the build failure and rerun/resolve the CI run so all checks pass?

@Nishanth29

Copy link
Copy Markdown

Per @george-kalisse-sada, the pull failure was likely a transient timeout issue. Zach synced to head and re-ran the check, which passed successfully(documenting here for visibility).

"""Run a shell command, raising on failure."""
logger.info(" CMD: %s", " ".join(cmd))
env = os.environ.copy()
env["CLOUDSDK_AUTH_DISABLE_SSL_VALIDATION"] = "true"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Is CLOUDSDK_AUTH_DISABLE_SSL_VALIDATION needed here or was it left over from local testing? Can we drop this line?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Removed.

rendered = template.render(**kwargs)

# Write rendered YAML to tmp dir (RunKubectlCommand does not support stdin)
tmp_dir = os.path.join(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Doesn't writing rendered manifests to data.ResourcePath(...) creates temp files inside the repository source tree?? ig we use PKB's managed temp dir instead so it doesn't mess git or fail in read-only installs.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Yes, changed to use PKB's managed vm_util.GetTempDir()

import threading


_PID_FILE = "/tmp/pkb_portforward.pid"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Wondering if two sweeps running in parallel might overwrite this /tmp file? Maybe we can put it in PKB's temp directory or add the port to the filename.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

updated the PID file path to dynamically include the local port number (e.g., pkb_portforward_8080.pid).

@@ -0,0 +1,54 @@
# GKE Agent Sandbox Benchmarks

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Replace "GKE" with "Kubernetes". Please also update other places that use "GKE"

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Done


PKB benchmark modules for measuring GKE Agent Sandbox performance under
gVisor isolation. Each benchmark is an atomic single-point measurement
designed to be invoked repeatedly by the sweep runner with varying parameters.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Each benchmark is a standalone PKB benchmark.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Updated to 'Each benchmark is a standalone PKB benchmark.' for clarity.

| Python Density | `k8s_python_density_benchmark.py` | Yes | CEL, TTFE, RSS, per-type latency (compute/syscall/import) |
| Payload Transfer | `k8s_payload_benchmark.py` | Yes | Generation, serialization, stdout write, throughput |
| Chromium Density | `k8s_chromium_density_benchmark.py` | Yes | Navigate, evaluate, click, fill, screenshot latency |
| QPS Saturation | `k8s_qps_benchmark.py` | Yes/No | TTFE at controlled request rates, warm pool drain detection |

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

What does "Agent API: Yes/No" mean?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Removed, It was originally intended to indicate whether the benchmark interacted with the custom the Agent's FastAPI service or just the raw K8s API, but yea it's not necessary for the documentation and creates confusion.

flags.DEFINE_string(
"k8s_agentic_benchmark_note",
"",
"Arbitrary note string attached to every sample for tagging runs.",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Please elaborate. What does note mean here and what's is for?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I've expanded the help string. It's used to inject a custom metadata tag (like 'nightly_run_v2') into the emitted samples so they can be easily filtered and grouped in downstream dashboards if needed.

Delegates to PKB's native kubectl module which handles kubeconfig
and retries for transient connection errors automatically.
"""
return kubectl.RunKubectlCommand(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Why do we need to duplicate this? This method adds no value but complexity.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Gentle ping. Let's remove this wrapper.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I forgot to reply back to this before but below would be my response:

The reason I kept this is because I wanted a global consistent timeout and raise_on_failure config for all benchmarks, rather than specifying them everytime I call the function. i would only specify them where they are not the default I chose in the wrapper.

During our saturation sweeps, if the K8s API server becomes unresponsive, we need it to fail fast rather than hanging the PKB thread indefinitely.

]
)
_RunCmd(
["git", "sparse-checkout", "set", "examples/chrome-sandbox"],

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Are we simply building example code from https://github.com/kubernetes-sigs/agent-sandbox? Ideally this should be built by the agent-sandbox repo so we can simply reuse published images.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Ideally yes, we would use the published images. However, we had to build them from source for two reasons:

  1. We needed to patch the Chrome Dockerfile to inject socat for the CDP proxy.
  2. The upstream repository does not currently publish arm64 images, which we need for the ARM saturation sweeps.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Resolving for now. I'm tracking the followup items and will open OSS issues / track internally.

"git",
"sparse-checkout",
"set",
"clients/python/agentic-sandbox-client/sandbox-router",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Same here. Are we simply building example code from https://github.com/kubernetes-sigs/agent-sandbox? Ideally this should be built by the agent-sandbox repo so we can simply reuse published images.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

The upstream repository does not currently publish arm64 images, which we need for the ARM saturation sweeps.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Resolving for now. I'm tracking the followup items and will open OSS issues / track internally.

@@ -0,0 +1,74 @@
# GKE Agentic Benchmark Scripts

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Replace "GKE" with "Kubernetes". You should scan all your code changes, find places that use "GKE" and update accordingly

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Done, but it's not a replace all exercise, since there are some things that are GKE specific. I might have missed a few things before, but I probably caught all now.


### Sweep Runner

`sweep.py` orchestrates multi-variant benchmark sweeps. It calls PKB

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I don't see sweep.py in this PR. Ideally we should remove this paragraph from this PR. We can discuss whether sweep.py belongs to PKB repo in a separate PR.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

The PR strategy document we discussed had splitting the mega-PR by whole files rather than fragmenting file contents across multiple PRs. So, this README describes the final state of the scripts/agentic directory. Content fragmentation at the stage we decided into split PRs would have've been prone to errors.

logger.info("Snapshot bucket deleted.")


def teardown_images(project_id: str, region: str) -> None:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Do these teardown operations happen on-demand, or do they happen during each benchmark? I'd expect it to be the former (otherwise it will be very time-consuming to do the unnecessary re-build), but just want to confirm with you.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Yes, It is the former. These teardown operations (like deleting the Artifact Registry and GCS buckets) do not happen during each benchmark. I've clarified this in the script's docstring.

@roycaihw roycaihw left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

These two comments are still not addressed. Please address them

Sign up for free to 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.

4 participants