RAPPS-WP-0014-T04: record isolated target-hardware Vergabe replay
Throwaway namespace on railiance01 ran the deployed digest (3 workers, 60m/1000m CPU, 256Mi/1Gi) against fresh PostgreSQL 16 with the phased synthetic profile: ordinary p95 0.192s, transfer p95 0.076s, zero errors. Raw cgroup/node/Prometheus samples, manifests, driver and a bounded recommendation retained; namespace torn down; T03 unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 8340@bnt-lap001 Assistant-Session: 2e192b3d-b3e8-4403-94d4-d55a2c8b476c
This commit is contained in:
parent
3851865c87
commit
1af6d828f5
26 changed files with 2590 additions and 3 deletions
155
docs/evidence/2026-10-21-vergabe-target-replay/README.md
Normal file
155
docs/evidence/2026-10-21-vergabe-target-replay/README.md
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
# Vergabe target-hardware synthetic replay — 2026-10-21
|
||||
|
||||
Task: `RAPPS-WP-0014-T04` (feeds `CUST-WP-0071-T02`, `RESOURCE-WP-0008-T02`).
|
||||
Authority: founder decision of 2026-10-21
|
||||
(`the-custodian/docs/decisions/2026-10-21-cust-wp-0071-delivery-interview.md`):
|
||||
isolated replay in a throwaway namespace on railiance01, reads elsewhere only.
|
||||
No customer data was read or written; the live `vergabe-demo-company` deployment,
|
||||
its database (`apps-pg`), quotas, policies and nodes were not modified (live
|
||||
Deployment generation 4, same digest, Ready 1/1 before and after). No Secret was
|
||||
read. This is synthetic sizing evidence, not human/recovery acceptance (T03).
|
||||
|
||||
## Deployed release (read-only capture, 2026-10-21)
|
||||
|
||||
| Item | Value |
|
||||
| --- | --- |
|
||||
| Cluster / node | context `default` → 92.205.62.239, single k3s v1.35.1 control-plane node |
|
||||
| Node CPU / memory | 4 vCPU `AMD EPYC Processor (with IBPB)`, 16 GiB; requests 3605m (90%) / limits 37500m; reservation residual 395m |
|
||||
| Image | `forgejo.coulomb.social/coulomb/vergabe-teilnahme@sha256:a26444f59c259698159c69ccb96f73dc648a261ece4c86bb2037a9d977870d91` (source `c067993`, per `docs/vergabe-demo-company-binding.md`) |
|
||||
| Chart / rollout | `vergabe-teilnahme-0.2.1`, one replica, Recreate, init `migrate`; Deployment revision 4 (rollout restart 2026-09-25). Helm release revision not re-read (release storage is a Secret) |
|
||||
| Gunicorn | no command override → image CMD `--workers 3` (sync), default 30s timeout |
|
||||
| Resources (app and migrate) | requests 60m CPU / 256Mi, limits 1000m CPU / 1Gi |
|
||||
| Settings | `vergabe_teilnahme.settings.prod`, SSO via NetKingdom, `envFrom` Secret reference `vergabe-demo-env` (not read) |
|
||||
| Database binding | namespace label `railiance.io/postgres-client=apps-pg`: shared CNPG `databases/apps-pg`, PostgreSQL 16, 100m/256Mi request, 1000m/1Gi limit, WAL archiving + `wal_level=logical` |
|
||||
| Storage | media 5Gi and app-state 1Gi PVCs, `local-path` |
|
||||
|
||||
Drift vs. the 2026-10-19 local test image (`vergabe-synthetic:local-11f7c8a`,
|
||||
`sha256:57da46…`): source `11f7c8a` is 16 commits ahead of deployed `c067993`;
|
||||
9 application files differ (+181/−10: ausschreibungen forms/views/templates,
|
||||
core views, search partial); Dockerfile, `uv.lock`, `pyproject.toml` identical.
|
||||
The local runs used 2 workers; the deployed image runs 3. This replay used the
|
||||
deployed digest itself, so the drift does not affect these results.
|
||||
|
||||
## Replay configuration (pinned)
|
||||
|
||||
Namespace `vergabe-sizing-20261021` (manifests in `harness/bench.yaml`,
|
||||
`harness/driver.yaml`), all pods on the same node:
|
||||
|
||||
- **app**: deployed digest, image CMD (3 workers), init `migrate`, 60m/256Mi request,
|
||||
1000m/1Gi limit, live securityContext/probes, Recreate; media on a fresh
|
||||
`local-path` PVC, issue state emptyDir. Settings = harness synthetic settings
|
||||
(`harness/synthetic_settings.py`: base settings, SSO off, password login).
|
||||
- **db**: fresh `docker.io/library/postgres@sha256:4b7183ac…` (PostgreSQL 16),
|
||||
emptyDir, 100m/256Mi request, 1000m/1Gi limit (matching apps-pg resources).
|
||||
- **driver**: deployed digest running `vergabe-teilnahme/scripts/synthetic_pilot.py`
|
||||
`runtime: remote` (commit `dca6683`; executed copy and config retained, digests
|
||||
`c8da867f…` / `9045f2c7…` match `raw/result.json.gz`), 100m request/1000m limit.
|
||||
In-cluster HTTP via ClusterIP Service — chosen over port-forward so latency
|
||||
excludes the WSL/SSH tunnel. Restart deletes the app pod through a namespaced
|
||||
Role (pods get/list/delete) and waits for a different ready pod.
|
||||
- NetworkPolicy: ingress/egress within the namespace, DNS, API server only;
|
||||
preflight confirmed the live Service was unreachable.
|
||||
- Profile `config/synthetic-pilot-phases.json` unchanged except runtime fields
|
||||
(`synthetic-pilot-target-remote.json`): 2 users, 100 seed tenders, 1 MiB
|
||||
documents, 30s idle, 90s ordinary (0.2s think), 30s burst (0 think), restart,
|
||||
60s recovery; 11 named operations including edits.
|
||||
- Sampling: 1s cgroup v2 `cpu.stat`/`memory.current`/`cpu.pressure` inside app,
|
||||
db and driver containers plus node-wide `/proc/stat` (`harness/sampler.sh`);
|
||||
`kubectl top` every 15s; Prometheus (cadvisor) per-namespace CPU/throttling.
|
||||
The sampler shell itself costs ~11–12m per container and is included.
|
||||
|
||||
Timeline (UTC): namespace created 06:26; pre-run idle baseline 06:27:14–06:29:26;
|
||||
harness idle 06:29:31–06:30:01; ordinary 06:30:01–06:31:32; burst –06:32:03;
|
||||
restart –06:32:22 (18.98s to ready incl. migrate); recovery –06:33:23; post
|
||||
idle –06:34:28; namespace deletion requested 06:35:25, completed 06:36:18; namespace and its PV verified absent (`raw/teardown.txt`).
|
||||
|
||||
## Results
|
||||
|
||||
Driver: complete, `provisional_pass: true`, `measurement_complete: true`, no gaps.
|
||||
|
||||
| Phase | Ordinary req / err / p95 | Transfer req / err / p95 |
|
||||
| --- | --- | --- |
|
||||
| ordinary | 1903 / 0 / 0.142s | 422 / 0 / 0.085s |
|
||||
| burst | 697 / 0 / 0.192s | 154 / 0 / 0.069s |
|
||||
| recovery | 1075 / 0 / 0.214s | 238 / 0 / 0.073s |
|
||||
| **all** | **3675 / 0 / 0.192s** | **814 / 0 / 0.076s** |
|
||||
|
||||
Per operation p95 (all phases): list 0.262s, search 0.255s, detail 0.146s,
|
||||
creates/edits 0.059–0.066s, upload 0.088s, download 0.050s; login 1.27s and
|
||||
login form 0.62s (n=6, first requests after idle). ~24.7 requests/s closed loop —
|
||||
far above two human users' pace.
|
||||
|
||||
| Window | App CPU mean / p95 / peak | Throttled periods | App memory peak | DB CPU mean / p95 | Node busy mean (free mean / free p5) |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| pre-run baseline | 12m / 15m / 16m | 0% | 166 MiB | 22m / 66m | 1348m (2652m / 1499m) |
|
||||
| ordinary | 711m / 845m / 1003m | 20.4% | 403 MiB | 388m / 501m | 2979m (1021m / 78m) |
|
||||
| burst | 953m / 1004m / 1011m | 65.8% | 482 MiB | 430m / 539m | 2806m (1194m / 278m) |
|
||||
| recovery | 861m / 957m / 982m | 41.5% | 322 MiB | 335m / 399m | 2624m (1376m / 392m) |
|
||||
| all load phases | 775m / 998m / 1020m | 35.7% (22.8s throttled) | 483 MiB | 341m / 500m | 2790m (1210m / 147m) |
|
||||
| post | 12m | 0% | 323 MiB | 22m | 1413m (2587m) |
|
||||
|
||||
App memory is cgroup `memory.current` (includes page cache); no OOM, no restarts.
|
||||
CPU pressure (PSI some) on the app was 15–21% of wall time under load.
|
||||
Incremental PostgreSQL CPU ≈ 320m mean / ~480m p95 over its idle baseline, on
|
||||
the isolated DB only (live `apps-pg` stayed at ~8m during the window). Driver
|
||||
added ~84m mean.
|
||||
|
||||
Competing workloads (Prometheus, workload window): all containers 1622m mean, of
|
||||
which the replay namespace 915m; others led by databases 121m, state-hub 120m,
|
||||
telemetry 102m, forgejo 78m (max 385m), activity-core 59m, core-hub 43m; live
|
||||
vergabe ~0m. Node-wide busy includes ~0.7 core of k3s/system outside containers.
|
||||
Pre-run competing load left ~2.65 cores free on average; during the replay the
|
||||
node reached near-saturation at peaks (free p5 ~150m) largely through the replay
|
||||
itself (app + db + driver ≈ 1.2 cores). Requests during the run were 3865m of
|
||||
4000m (replay 260m of the 395m residual, released at teardown).
|
||||
|
||||
## Coverage and gaps
|
||||
|
||||
- Representative: exact deployed image/digest, worker count, CPU/memory
|
||||
requests and limits (CFS quota 100000/100000 verified), Recreate + init migrate
|
||||
restart path, target hardware and real shared node contention.
|
||||
- Not representative: synthetic settings instead of prod (no SSO/OIDC, insecure
|
||||
cookies, no whitenoise manifest storage); no Traefik ingress/TLS/browser; DB is a
|
||||
standalone PostgreSQL 16 pod, not shared CNPG `apps-pg` (WAL archiving, logical
|
||||
WAL, other tenants) — the ~320m incremental DB demand would land on apps-pg's
|
||||
1000m limit/100m request in production and is not proven there.
|
||||
- Load is a synthetic closed loop (~25 req/s), not observed human demand; one run
|
||||
with ~3.5 min of load (pinned profile), ~9 min namespace lifetime.
|
||||
- Node contention was partly self-induced; contention from other tenants was
|
||||
light at this hour. A busier moment (forgejo CI, backups) is not covered.
|
||||
- The 60m request is a scheduling weight/reservation, not a quota; the 1000m
|
||||
limit is the quota that throttled. Sampler exec overhead is in the app cgroup.
|
||||
|
||||
## Bounded recommendation (for RESOURCE-WP-0008-T02 / CUST-WP-0071-T02)
|
||||
|
||||
- **CPU limit 1000m: keep.** Under an aggressive synthetic mix it throttles
|
||||
(36% of periods, 66% in burst) yet ordinary p95 stays ≤0.22s per phase — ~9×
|
||||
margin to the 2s target, zero failed operations, including restart recovery.
|
||||
- **CPU request 60m: keep for the two-user invited pilot**, provisionally. Even
|
||||
with the node near saturation and only a 60m weight, latency stayed far inside
|
||||
target; two humans generate a small fraction of this load. Raising it (e.g.
|
||||
250m) is not required by these results and would consume most of the 395m
|
||||
residual — an allocation-owner decision, not made here.
|
||||
- **Memory limit 1Gi: keep** (peak 483 MiB incl. page cache, ~2× margin).
|
||||
**Memory request 256Mi: keep, consider 512Mi** at the next allocation review,
|
||||
since loaded working set (320–480 MiB) exceeds the request; node memory requests
|
||||
are 61%, so this is low-risk but not urgent.
|
||||
- **Database**: budget ~0.3–0.5 core incremental on apps-pg at this synthetic
|
||||
rate; acceptable against its 1000m limit for a two-user pilot, unverified on the
|
||||
shared cluster.
|
||||
- **Revisit when**: user count/companies or corpus grow, image or worker count
|
||||
changes, live p95 >1s or any 5xx, node requests >95% or sustained node free CPU
|
||||
<500m outside benchmarks, apps-pg CPU >600m sustained, or the pilot moves to
|
||||
railiance02/other hardware.
|
||||
|
||||
## Files
|
||||
|
||||
- `analysis.json` — per-window cgroup statistics, per-operation p95, phase results
|
||||
(`harness/analyze.py raw/ analysis.json` after gunzip)
|
||||
- `raw/result.json.gz` — driver output (all operations, phase UTC windows, host facts)
|
||||
- `raw/{app,db,driver}-cgroup.txt.gz` — 1s cgroup/node samples (`POD` lines mark
|
||||
the restart re-attach; the `exit code 137` exec termination is that restart)
|
||||
- `raw/kubectl-top.txt.gz`, `raw/prometheus-{baseline,workload}.json.gz`
|
||||
- `raw/windows.txt`, `raw/pod-provenance.txt`, `raw/namespace-events.txt`,
|
||||
`raw/teardown.txt`, `raw/driver-stdout.txt`
|
||||
- `harness/` — manifests, settings, samplers, orchestrator, executed driver/config
|
||||
923
docs/evidence/2026-10-21-vergabe-target-replay/analysis.json
Normal file
923
docs/evidence/2026-10-21-vergabe-target-replay/analysis.json
Normal file
|
|
@ -0,0 +1,923 @@
|
|||
{
|
||||
"windows_utc": {
|
||||
"baseline_pre": [
|
||||
"2026-10-21T06:27:14.447540Z",
|
||||
"2026-10-21T06:29:26.175778Z"
|
||||
],
|
||||
"harness_idle": [
|
||||
"2026-10-21T06:29:31.522662Z",
|
||||
"2026-10-21T06:30:01.522800Z"
|
||||
],
|
||||
"ordinary": [
|
||||
"2026-10-21T06:30:01.523056Z",
|
||||
"2026-10-21T06:31:32.589152Z"
|
||||
],
|
||||
"burst": [
|
||||
"2026-10-21T06:31:32.589194Z",
|
||||
"2026-10-21T06:32:03.275085Z"
|
||||
],
|
||||
"restart": [
|
||||
"2026-10-21T06:32:03.275117Z",
|
||||
"2026-10-21T06:32:22.256585Z"
|
||||
],
|
||||
"recovery": [
|
||||
"2026-10-21T06:32:22.256609Z",
|
||||
"2026-10-21T06:33:23.057045Z"
|
||||
],
|
||||
"workload_all_load_phases": [
|
||||
"2026-10-21T06:30:01.523056Z",
|
||||
"2026-10-21T06:33:23.057045Z"
|
||||
],
|
||||
"post": [
|
||||
"2026-10-21T06:33:22.885983Z",
|
||||
"2026-10-21T06:34:28.753426Z"
|
||||
]
|
||||
},
|
||||
"cgroup": {
|
||||
"app": {
|
||||
"pods": [
|
||||
"vergabe-app-579448bf49-2fsn2",
|
||||
"vergabe-app-579448bf49-plp4j"
|
||||
],
|
||||
"baseline_pre": {
|
||||
"samples": 126,
|
||||
"seconds": 128.0,
|
||||
"cpu_mean_m": 12.2,
|
||||
"cpu_p95_m": 14.7,
|
||||
"cpu_peak_m": 16.2,
|
||||
"cfs_periods": 317,
|
||||
"cfs_throttled_periods": 0,
|
||||
"throttle_ratio": 0.0,
|
||||
"throttled_seconds": 0.0,
|
||||
"psi_cpu_some_share": 0.002,
|
||||
"mem_peak_mib": 165.6,
|
||||
"mem_mean_mib": 165.2,
|
||||
"node_busy_mean_m": 1348,
|
||||
"node_busy_p95_m": 2501,
|
||||
"node_free_mean_m": 2652,
|
||||
"node_free_p5_m": 1499,
|
||||
"load1_max": 4.91
|
||||
},
|
||||
"harness_idle": {
|
||||
"samples": 28,
|
||||
"seconds": 28.4,
|
||||
"cpu_mean_m": 11.5,
|
||||
"cpu_p95_m": 13.4,
|
||||
"cpu_peak_m": 13.6,
|
||||
"cfs_periods": 76,
|
||||
"cfs_throttled_periods": 0,
|
||||
"throttle_ratio": 0.0,
|
||||
"throttled_seconds": 0.0,
|
||||
"psi_cpu_some_share": 0.002,
|
||||
"mem_peak_mib": 165.3,
|
||||
"mem_mean_mib": 165.1,
|
||||
"node_busy_mean_m": 1538,
|
||||
"node_busy_p95_m": 2800,
|
||||
"node_free_mean_m": 2462,
|
||||
"node_free_p5_m": 1200,
|
||||
"load1_max": 2.91
|
||||
},
|
||||
"ordinary": {
|
||||
"samples": 88,
|
||||
"seconds": 90.2,
|
||||
"cpu_mean_m": 711.4,
|
||||
"cpu_p95_m": 845.4,
|
||||
"cpu_peak_m": 1003.2,
|
||||
"cfs_periods": 902,
|
||||
"cfs_throttled_periods": 184,
|
||||
"throttle_ratio": 0.204,
|
||||
"throttled_seconds": 4.85,
|
||||
"psi_cpu_some_share": 0.15,
|
||||
"mem_peak_mib": 402.5,
|
||||
"mem_mean_mib": 295.2,
|
||||
"node_busy_mean_m": 2979,
|
||||
"node_busy_p95_m": 3922,
|
||||
"node_free_mean_m": 1021,
|
||||
"node_free_p5_m": 78,
|
||||
"load1_max": 7.83
|
||||
},
|
||||
"burst": {
|
||||
"samples": 29,
|
||||
"seconds": 29.9,
|
||||
"cpu_mean_m": 952.9,
|
||||
"cpu_p95_m": 1003.7,
|
||||
"cpu_peak_m": 1011.1,
|
||||
"cfs_periods": 298,
|
||||
"cfs_throttled_periods": 196,
|
||||
"throttle_ratio": 0.658,
|
||||
"throttled_seconds": 8.94,
|
||||
"psi_cpu_some_share": 0.211,
|
||||
"mem_peak_mib": 481.8,
|
||||
"mem_mean_mib": 443.4,
|
||||
"node_busy_mean_m": 2806,
|
||||
"node_busy_p95_m": 3722,
|
||||
"node_free_mean_m": 1194,
|
||||
"node_free_p5_m": 278,
|
||||
"load1_max": 8.19
|
||||
},
|
||||
"restart": {
|
||||
"samples": 10,
|
||||
"seconds": 10.3,
|
||||
"cpu_mean_m": 403.3,
|
||||
"cpu_p95_m": 1019.7,
|
||||
"cpu_peak_m": 1019.7,
|
||||
"cfs_periods": 54,
|
||||
"cfs_throttled_periods": 39,
|
||||
"throttle_ratio": 0.722,
|
||||
"throttled_seconds": 2.37,
|
||||
"psi_cpu_some_share": 0.235,
|
||||
"mem_peak_mib": 483.3,
|
||||
"mem_mean_mib": 154.0,
|
||||
"node_busy_mean_m": 1908,
|
||||
"node_busy_p95_m": 3359,
|
||||
"node_free_mean_m": 2092,
|
||||
"node_free_p5_m": 641,
|
||||
"load1_max": 7.84
|
||||
},
|
||||
"recovery": {
|
||||
"samples": 59,
|
||||
"seconds": 60.6,
|
||||
"cpu_mean_m": 860.6,
|
||||
"cpu_p95_m": 956.8,
|
||||
"cpu_peak_m": 982.3,
|
||||
"cfs_periods": 605,
|
||||
"cfs_throttled_periods": 251,
|
||||
"throttle_ratio": 0.415,
|
||||
"throttled_seconds": 6.17,
|
||||
"psi_cpu_some_share": 0.152,
|
||||
"mem_peak_mib": 322.2,
|
||||
"mem_mean_mib": 251.0,
|
||||
"node_busy_mean_m": 2624,
|
||||
"node_busy_p95_m": 3608,
|
||||
"node_free_mean_m": 1376,
|
||||
"node_free_p5_m": 392,
|
||||
"load1_max": 6.66
|
||||
},
|
||||
"workload_all_load_phases": {
|
||||
"samples": 189,
|
||||
"seconds": 194.0,
|
||||
"cpu_mean_m": 775.3,
|
||||
"cpu_p95_m": 998.3,
|
||||
"cpu_peak_m": 1019.7,
|
||||
"cfs_periods": 1889,
|
||||
"cfs_throttled_periods": 675,
|
||||
"throttle_ratio": 0.357,
|
||||
"throttled_seconds": 22.77,
|
||||
"psi_cpu_some_share": 0.166,
|
||||
"mem_peak_mib": 483.3,
|
||||
"mem_mean_mib": 295.7,
|
||||
"node_busy_mean_m": 2790,
|
||||
"node_busy_p95_m": 3853,
|
||||
"node_free_mean_m": 1210,
|
||||
"node_free_p5_m": 147,
|
||||
"load1_max": 8.19
|
||||
},
|
||||
"post": {
|
||||
"samples": 63,
|
||||
"seconds": 63.9,
|
||||
"cpu_mean_m": 12.3,
|
||||
"cpu_p95_m": 14.3,
|
||||
"cpu_peak_m": 15.1,
|
||||
"cfs_periods": 161,
|
||||
"cfs_throttled_periods": 0,
|
||||
"throttle_ratio": 0.0,
|
||||
"throttled_seconds": 0.0,
|
||||
"psi_cpu_some_share": 0.001,
|
||||
"mem_peak_mib": 322.5,
|
||||
"mem_mean_mib": 322.2,
|
||||
"node_busy_mean_m": 1413,
|
||||
"node_busy_p95_m": 2414,
|
||||
"node_free_mean_m": 2587,
|
||||
"node_free_p5_m": 1586,
|
||||
"load1_max": 5.75
|
||||
}
|
||||
},
|
||||
"db": {
|
||||
"pods": [
|
||||
"vergabe-db-7c4bffdd48-w4jz4"
|
||||
],
|
||||
"baseline_pre": {
|
||||
"samples": 127,
|
||||
"seconds": 128.5,
|
||||
"cpu_mean_m": 21.5,
|
||||
"cpu_p95_m": 65.7,
|
||||
"cpu_peak_m": 71.7,
|
||||
"cfs_periods": 333,
|
||||
"cfs_throttled_periods": 0,
|
||||
"throttle_ratio": 0.0,
|
||||
"throttled_seconds": 0.0,
|
||||
"psi_cpu_some_share": 0.002,
|
||||
"mem_peak_mib": 91.3,
|
||||
"mem_mean_mib": 90.4,
|
||||
"node_busy_mean_m": 1346,
|
||||
"node_busy_p95_m": 2448,
|
||||
"node_free_mean_m": 2654,
|
||||
"node_free_p5_m": 1552,
|
||||
"load1_max": 4.91
|
||||
},
|
||||
"harness_idle": {
|
||||
"samples": 29,
|
||||
"seconds": 29.3,
|
||||
"cpu_mean_m": 20.9,
|
||||
"cpu_p95_m": 64.5,
|
||||
"cpu_peak_m": 64.9,
|
||||
"cfs_periods": 75,
|
||||
"cfs_throttled_periods": 0,
|
||||
"throttle_ratio": 0.0,
|
||||
"throttled_seconds": 0.0,
|
||||
"psi_cpu_some_share": 0.003,
|
||||
"mem_peak_mib": 93.0,
|
||||
"mem_mean_mib": 92.7,
|
||||
"node_busy_mean_m": 1522,
|
||||
"node_busy_p95_m": 2680,
|
||||
"node_free_mean_m": 2478,
|
||||
"node_free_p5_m": 1320,
|
||||
"load1_max": 3.15
|
||||
},
|
||||
"ordinary": {
|
||||
"samples": 88,
|
||||
"seconds": 89.9,
|
||||
"cpu_mean_m": 387.8,
|
||||
"cpu_p95_m": 501.1,
|
||||
"cpu_peak_m": 532.2,
|
||||
"cfs_periods": 892,
|
||||
"cfs_throttled_periods": 2,
|
||||
"throttle_ratio": 0.002,
|
||||
"throttled_seconds": 0.02,
|
||||
"psi_cpu_some_share": 0.067,
|
||||
"mem_peak_mib": 101.4,
|
||||
"mem_mean_mib": 95.7,
|
||||
"node_busy_mean_m": 2974,
|
||||
"node_busy_p95_m": 3895,
|
||||
"node_free_mean_m": 1026,
|
||||
"node_free_p5_m": 105,
|
||||
"load1_max": 8.19
|
||||
},
|
||||
"burst": {
|
||||
"samples": 29,
|
||||
"seconds": 29.6,
|
||||
"cpu_mean_m": 430.1,
|
||||
"cpu_p95_m": 539.1,
|
||||
"cpu_peak_m": 544.4,
|
||||
"cfs_periods": 293,
|
||||
"cfs_throttled_periods": 2,
|
||||
"throttle_ratio": 0.007,
|
||||
"throttled_seconds": 0.06,
|
||||
"psi_cpu_some_share": 0.062,
|
||||
"mem_peak_mib": 113.1,
|
||||
"mem_mean_mib": 97.1,
|
||||
"node_busy_mean_m": 2798,
|
||||
"node_busy_p95_m": 3664,
|
||||
"node_free_mean_m": 1202,
|
||||
"node_free_p5_m": 336,
|
||||
"load1_max": 8.19
|
||||
},
|
||||
"restart": {
|
||||
"samples": 18,
|
||||
"seconds": 18.3,
|
||||
"cpu_mean_m": 24.3,
|
||||
"cpu_p95_m": 67.7,
|
||||
"cpu_peak_m": 67.7,
|
||||
"cfs_periods": 55,
|
||||
"cfs_throttled_periods": 0,
|
||||
"throttle_ratio": 0.0,
|
||||
"throttled_seconds": 0.0,
|
||||
"psi_cpu_some_share": 0.009,
|
||||
"mem_peak_mib": 103.3,
|
||||
"mem_mean_mib": 101.4,
|
||||
"node_busy_mean_m": 2650,
|
||||
"node_busy_p95_m": 3961,
|
||||
"node_free_mean_m": 1350,
|
||||
"node_free_p5_m": 39,
|
||||
"load1_max": 7.84
|
||||
},
|
||||
"recovery": {
|
||||
"samples": 58,
|
||||
"seconds": 58.9,
|
||||
"cpu_mean_m": 335.0,
|
||||
"cpu_p95_m": 398.7,
|
||||
"cpu_peak_m": 408.1,
|
||||
"cfs_periods": 581,
|
||||
"cfs_throttled_periods": 1,
|
||||
"throttle_ratio": 0.002,
|
||||
"throttled_seconds": 0.0,
|
||||
"psi_cpu_some_share": 0.041,
|
||||
"mem_peak_mib": 111.3,
|
||||
"mem_mean_mib": 106.9,
|
||||
"node_busy_mean_m": 2621,
|
||||
"node_busy_p95_m": 3524,
|
||||
"node_free_mean_m": 1379,
|
||||
"node_free_p5_m": 476,
|
||||
"load1_max": 6.66
|
||||
},
|
||||
"workload_all_load_phases": {
|
||||
"samples": 196,
|
||||
"seconds": 199.8,
|
||||
"cpu_mean_m": 340.8,
|
||||
"cpu_p95_m": 500.0,
|
||||
"cpu_peak_m": 544.4,
|
||||
"cfs_periods": 1837,
|
||||
"cfs_throttled_periods": 5,
|
||||
"throttle_ratio": 0.003,
|
||||
"throttled_seconds": 0.08,
|
||||
"psi_cpu_some_share": 0.052,
|
||||
"mem_peak_mib": 113.1,
|
||||
"mem_mean_mib": 99.8,
|
||||
"node_busy_mean_m": 2813,
|
||||
"node_busy_p95_m": 3894,
|
||||
"node_free_mean_m": 1187,
|
||||
"node_free_p5_m": 106,
|
||||
"load1_max": 8.19
|
||||
},
|
||||
"post": {
|
||||
"samples": 64,
|
||||
"seconds": 64.8,
|
||||
"cpu_mean_m": 21.7,
|
||||
"cpu_p95_m": 65.1,
|
||||
"cpu_peak_m": 79.6,
|
||||
"cfs_periods": 161,
|
||||
"cfs_throttled_periods": 0,
|
||||
"throttle_ratio": 0.0,
|
||||
"throttled_seconds": 0.0,
|
||||
"psi_cpu_some_share": 0.002,
|
||||
"mem_peak_mib": 101.3,
|
||||
"mem_mean_mib": 98.1,
|
||||
"node_busy_mean_m": 1420,
|
||||
"node_busy_p95_m": 2509,
|
||||
"node_free_mean_m": 2580,
|
||||
"node_free_p5_m": 1491,
|
||||
"load1_max": 5.75
|
||||
}
|
||||
},
|
||||
"driver": {
|
||||
"pods": [
|
||||
"synthetic-driver"
|
||||
],
|
||||
"baseline_pre": {
|
||||
"samples": 126,
|
||||
"seconds": 127.9,
|
||||
"cpu_mean_m": 11.6,
|
||||
"cpu_p95_m": 13.2,
|
||||
"cpu_peak_m": 13.7,
|
||||
"cfs_periods": 267,
|
||||
"cfs_throttled_periods": 0,
|
||||
"throttle_ratio": 0.0,
|
||||
"throttled_seconds": 0.0,
|
||||
"psi_cpu_some_share": 0.002,
|
||||
"mem_peak_mib": 6.6,
|
||||
"mem_mean_mib": 6.3,
|
||||
"node_busy_mean_m": 1348,
|
||||
"node_busy_p95_m": 2510,
|
||||
"node_free_mean_m": 2652,
|
||||
"node_free_p5_m": 1490,
|
||||
"load1_max": 4.91
|
||||
},
|
||||
"harness_idle": {
|
||||
"samples": 28,
|
||||
"seconds": 28.4,
|
||||
"cpu_mean_m": 11.6,
|
||||
"cpu_p95_m": 13.1,
|
||||
"cpu_peak_m": 13.1,
|
||||
"cfs_periods": 59,
|
||||
"cfs_throttled_periods": 0,
|
||||
"throttle_ratio": 0.0,
|
||||
"throttled_seconds": 0.0,
|
||||
"psi_cpu_some_share": 0.002,
|
||||
"mem_peak_mib": 63.3,
|
||||
"mem_mean_mib": 63.0,
|
||||
"node_busy_mean_m": 1537,
|
||||
"node_busy_p95_m": 2829,
|
||||
"node_free_mean_m": 2463,
|
||||
"node_free_p5_m": 1171,
|
||||
"load1_max": 2.91
|
||||
},
|
||||
"ordinary": {
|
||||
"samples": 88,
|
||||
"seconds": 90.0,
|
||||
"cpu_mean_m": 91.7,
|
||||
"cpu_p95_m": 117.2,
|
||||
"cpu_peak_m": 124.8,
|
||||
"cfs_periods": 891,
|
||||
"cfs_throttled_periods": 0,
|
||||
"throttle_ratio": 0.0,
|
||||
"throttled_seconds": 0.0,
|
||||
"psi_cpu_some_share": 0.029,
|
||||
"mem_peak_mib": 75.9,
|
||||
"mem_mean_mib": 72.4,
|
||||
"node_busy_mean_m": 2977,
|
||||
"node_busy_p95_m": 3912,
|
||||
"node_free_mean_m": 1023,
|
||||
"node_free_p5_m": 88,
|
||||
"load1_max": 7.83
|
||||
},
|
||||
"burst": {
|
||||
"samples": 29,
|
||||
"seconds": 29.6,
|
||||
"cpu_mean_m": 98.5,
|
||||
"cpu_p95_m": 124.8,
|
||||
"cpu_peak_m": 129.3,
|
||||
"cfs_periods": 289,
|
||||
"cfs_throttled_periods": 0,
|
||||
"throttle_ratio": 0.0,
|
||||
"throttled_seconds": 0.0,
|
||||
"psi_cpu_some_share": 0.026,
|
||||
"mem_peak_mib": 78.4,
|
||||
"mem_mean_mib": 76.4,
|
||||
"node_busy_mean_m": 2790,
|
||||
"node_busy_p95_m": 3387,
|
||||
"node_free_mean_m": 1210,
|
||||
"node_free_p5_m": 613,
|
||||
"load1_max": 8.19
|
||||
},
|
||||
"restart": {
|
||||
"samples": 18,
|
||||
"seconds": 18.3,
|
||||
"cpu_mean_m": 22.4,
|
||||
"cpu_p95_m": 25.5,
|
||||
"cpu_peak_m": 25.5,
|
||||
"cfs_periods": 112,
|
||||
"cfs_throttled_periods": 0,
|
||||
"throttle_ratio": 0.0,
|
||||
"throttled_seconds": 0.0,
|
||||
"psi_cpu_some_share": 0.009,
|
||||
"mem_peak_mib": 73.7,
|
||||
"mem_mean_mib": 71.3,
|
||||
"node_busy_mean_m": 2650,
|
||||
"node_busy_p95_m": 3990,
|
||||
"node_free_mean_m": 1350,
|
||||
"node_free_p5_m": 10,
|
||||
"load1_max": 7.84
|
||||
},
|
||||
"recovery": {
|
||||
"samples": 59,
|
||||
"seconds": 60.1,
|
||||
"cpu_mean_m": 82.2,
|
||||
"cpu_p95_m": 95.4,
|
||||
"cpu_peak_m": 139.7,
|
||||
"cfs_periods": 594,
|
||||
"cfs_throttled_periods": 0,
|
||||
"throttle_ratio": 0.0,
|
||||
"throttled_seconds": 0.0,
|
||||
"psi_cpu_some_share": 0.02,
|
||||
"mem_peak_mib": 80.9,
|
||||
"mem_mean_mib": 77.2,
|
||||
"node_busy_mean_m": 2635,
|
||||
"node_busy_p95_m": 3540,
|
||||
"node_free_mean_m": 1365,
|
||||
"node_free_p5_m": 460,
|
||||
"load1_max": 6.66
|
||||
},
|
||||
"workload_all_load_phases": {
|
||||
"samples": 197,
|
||||
"seconds": 201.1,
|
||||
"cpu_mean_m": 84.4,
|
||||
"cpu_p95_m": 117.7,
|
||||
"cpu_peak_m": 200.8,
|
||||
"cfs_periods": 1911,
|
||||
"cfs_throttled_periods": 0,
|
||||
"throttle_ratio": 0.0,
|
||||
"throttled_seconds": 0.0,
|
||||
"psi_cpu_some_share": 0.024,
|
||||
"mem_peak_mib": 80.9,
|
||||
"mem_mean_mib": 74.4,
|
||||
"node_busy_mean_m": 2820,
|
||||
"node_busy_p95_m": 3912,
|
||||
"node_free_mean_m": 1180,
|
||||
"node_free_p5_m": 88,
|
||||
"load1_max": 8.19
|
||||
},
|
||||
"post": {
|
||||
"samples": 64,
|
||||
"seconds": 64.9,
|
||||
"cpu_mean_m": 16.3,
|
||||
"cpu_p95_m": 13.2,
|
||||
"cpu_peak_m": 317.3,
|
||||
"cfs_periods": 137,
|
||||
"cfs_throttled_periods": 0,
|
||||
"throttle_ratio": 0.0,
|
||||
"throttled_seconds": 0.0,
|
||||
"psi_cpu_some_share": 0.002,
|
||||
"mem_peak_mib": 79.1,
|
||||
"mem_mean_mib": 19.2,
|
||||
"node_busy_mean_m": 1423,
|
||||
"node_busy_p95_m": 2535,
|
||||
"node_free_mean_m": 2577,
|
||||
"node_free_p5_m": 1465,
|
||||
"load1_max": 5.75
|
||||
}
|
||||
}
|
||||
},
|
||||
"per_operation": {
|
||||
"burst/detail": {
|
||||
"n": 77,
|
||||
"errors": 0,
|
||||
"p95_s": 0.1132,
|
||||
"max_s": 0.1706
|
||||
},
|
||||
"burst/document-download": {
|
||||
"n": 77,
|
||||
"errors": 0,
|
||||
"p95_s": 0.0447,
|
||||
"max_s": 0.0592
|
||||
},
|
||||
"burst/document-upload": {
|
||||
"n": 77,
|
||||
"errors": 0,
|
||||
"p95_s": 0.075,
|
||||
"max_s": 0.1055
|
||||
},
|
||||
"burst/list": {
|
||||
"n": 77,
|
||||
"errors": 0,
|
||||
"p95_s": 0.2974,
|
||||
"max_s": 0.3233
|
||||
},
|
||||
"burst/login": {
|
||||
"n": 2,
|
||||
"errors": 0,
|
||||
"p95_s": 1.1775,
|
||||
"max_s": 1.1775
|
||||
},
|
||||
"burst/login-form": {
|
||||
"n": 2,
|
||||
"errors": 0,
|
||||
"p95_s": 0.0281,
|
||||
"max_s": 0.0281
|
||||
},
|
||||
"burst/lot-create": {
|
||||
"n": 77,
|
||||
"errors": 0,
|
||||
"p95_s": 0.0581,
|
||||
"max_s": 0.0971
|
||||
},
|
||||
"burst/lot-edit": {
|
||||
"n": 77,
|
||||
"errors": 0,
|
||||
"p95_s": 0.0536,
|
||||
"max_s": 0.0743
|
||||
},
|
||||
"burst/search": {
|
||||
"n": 77,
|
||||
"errors": 0,
|
||||
"p95_s": 0.2652,
|
||||
"max_s": 0.3359
|
||||
},
|
||||
"burst/task-create": {
|
||||
"n": 77,
|
||||
"errors": 0,
|
||||
"p95_s": 0.0599,
|
||||
"max_s": 0.1778
|
||||
},
|
||||
"burst/task-edit": {
|
||||
"n": 77,
|
||||
"errors": 0,
|
||||
"p95_s": 0.0597,
|
||||
"max_s": 0.0759
|
||||
},
|
||||
"burst/tender-create": {
|
||||
"n": 77,
|
||||
"errors": 0,
|
||||
"p95_s": 0.0772,
|
||||
"max_s": 0.0845
|
||||
},
|
||||
"burst/tender-edit": {
|
||||
"n": 77,
|
||||
"errors": 0,
|
||||
"p95_s": 0.0623,
|
||||
"max_s": 0.0732
|
||||
},
|
||||
"ordinary/detail": {
|
||||
"n": 211,
|
||||
"errors": 0,
|
||||
"p95_s": 0.1758,
|
||||
"max_s": 0.3877
|
||||
},
|
||||
"ordinary/document-download": {
|
||||
"n": 211,
|
||||
"errors": 0,
|
||||
"p95_s": 0.0537,
|
||||
"max_s": 0.11
|
||||
},
|
||||
"ordinary/document-upload": {
|
||||
"n": 211,
|
||||
"errors": 0,
|
||||
"p95_s": 0.1051,
|
||||
"max_s": 0.4418
|
||||
},
|
||||
"ordinary/list": {
|
||||
"n": 211,
|
||||
"errors": 0,
|
||||
"p95_s": 0.194,
|
||||
"max_s": 0.3779
|
||||
},
|
||||
"ordinary/login": {
|
||||
"n": 2,
|
||||
"errors": 0,
|
||||
"p95_s": 1.2574,
|
||||
"max_s": 1.2574
|
||||
},
|
||||
"ordinary/login-form": {
|
||||
"n": 2,
|
||||
"errors": 0,
|
||||
"p95_s": 0.3288,
|
||||
"max_s": 0.3288
|
||||
},
|
||||
"ordinary/lot-create": {
|
||||
"n": 211,
|
||||
"errors": 0,
|
||||
"p95_s": 0.0696,
|
||||
"max_s": 0.1603
|
||||
},
|
||||
"ordinary/lot-edit": {
|
||||
"n": 211,
|
||||
"errors": 0,
|
||||
"p95_s": 0.0763,
|
||||
"max_s": 0.1017
|
||||
},
|
||||
"ordinary/search": {
|
||||
"n": 211,
|
||||
"errors": 0,
|
||||
"p95_s": 0.2294,
|
||||
"max_s": 0.6217
|
||||
},
|
||||
"ordinary/task-create": {
|
||||
"n": 211,
|
||||
"errors": 0,
|
||||
"p95_s": 0.0697,
|
||||
"max_s": 0.1338
|
||||
},
|
||||
"ordinary/task-edit": {
|
||||
"n": 211,
|
||||
"errors": 0,
|
||||
"p95_s": 0.0686,
|
||||
"max_s": 0.1146
|
||||
},
|
||||
"ordinary/tender-create": {
|
||||
"n": 211,
|
||||
"errors": 0,
|
||||
"p95_s": 0.0626,
|
||||
"max_s": 0.1187
|
||||
},
|
||||
"ordinary/tender-edit": {
|
||||
"n": 211,
|
||||
"errors": 0,
|
||||
"p95_s": 0.0633,
|
||||
"max_s": 0.1171
|
||||
},
|
||||
"recovery/detail": {
|
||||
"n": 119,
|
||||
"errors": 0,
|
||||
"p95_s": 0.131,
|
||||
"max_s": 0.1379
|
||||
},
|
||||
"recovery/document-download": {
|
||||
"n": 119,
|
||||
"errors": 0,
|
||||
"p95_s": 0.0475,
|
||||
"max_s": 0.0818
|
||||
},
|
||||
"recovery/document-upload": {
|
||||
"n": 119,
|
||||
"errors": 0,
|
||||
"p95_s": 0.08,
|
||||
"max_s": 0.1587
|
||||
},
|
||||
"recovery/list": {
|
||||
"n": 119,
|
||||
"errors": 0,
|
||||
"p95_s": 0.3302,
|
||||
"max_s": 0.3757
|
||||
},
|
||||
"recovery/login": {
|
||||
"n": 2,
|
||||
"errors": 0,
|
||||
"p95_s": 1.2653,
|
||||
"max_s": 1.2653
|
||||
},
|
||||
"recovery/login-form": {
|
||||
"n": 2,
|
||||
"errors": 0,
|
||||
"p95_s": 0.6157,
|
||||
"max_s": 0.6157
|
||||
},
|
||||
"recovery/lot-create": {
|
||||
"n": 119,
|
||||
"errors": 0,
|
||||
"p95_s": 0.0526,
|
||||
"max_s": 0.0945
|
||||
},
|
||||
"recovery/lot-edit": {
|
||||
"n": 119,
|
||||
"errors": 0,
|
||||
"p95_s": 0.0602,
|
||||
"max_s": 0.1186
|
||||
},
|
||||
"recovery/search": {
|
||||
"n": 119,
|
||||
"errors": 0,
|
||||
"p95_s": 0.3193,
|
||||
"max_s": 0.4237
|
||||
},
|
||||
"recovery/task-create": {
|
||||
"n": 119,
|
||||
"errors": 0,
|
||||
"p95_s": 0.0558,
|
||||
"max_s": 0.0888
|
||||
},
|
||||
"recovery/task-edit": {
|
||||
"n": 119,
|
||||
"errors": 0,
|
||||
"p95_s": 0.0577,
|
||||
"max_s": 0.0959
|
||||
},
|
||||
"recovery/tender-create": {
|
||||
"n": 119,
|
||||
"errors": 0,
|
||||
"p95_s": 0.0489,
|
||||
"max_s": 0.0661
|
||||
},
|
||||
"recovery/tender-edit": {
|
||||
"n": 119,
|
||||
"errors": 0,
|
||||
"p95_s": 0.0556,
|
||||
"max_s": 0.0753
|
||||
}
|
||||
},
|
||||
"per_operation_all_phases": {
|
||||
"detail": {
|
||||
"n": 407,
|
||||
"errors": 0,
|
||||
"p95_s": 0.1463
|
||||
},
|
||||
"document-download": {
|
||||
"n": 407,
|
||||
"errors": 0,
|
||||
"p95_s": 0.0498
|
||||
},
|
||||
"document-upload": {
|
||||
"n": 407,
|
||||
"errors": 0,
|
||||
"p95_s": 0.0878
|
||||
},
|
||||
"list": {
|
||||
"n": 407,
|
||||
"errors": 0,
|
||||
"p95_s": 0.2624
|
||||
},
|
||||
"login": {
|
||||
"n": 6,
|
||||
"errors": 0,
|
||||
"p95_s": 1.2653
|
||||
},
|
||||
"login-form": {
|
||||
"n": 6,
|
||||
"errors": 0,
|
||||
"p95_s": 0.6157
|
||||
},
|
||||
"lot-create": {
|
||||
"n": 407,
|
||||
"errors": 0,
|
||||
"p95_s": 0.0613
|
||||
},
|
||||
"lot-edit": {
|
||||
"n": 407,
|
||||
"errors": 0,
|
||||
"p95_s": 0.0621
|
||||
},
|
||||
"search": {
|
||||
"n": 407,
|
||||
"errors": 0,
|
||||
"p95_s": 0.2553
|
||||
},
|
||||
"task-create": {
|
||||
"n": 407,
|
||||
"errors": 0,
|
||||
"p95_s": 0.0621
|
||||
},
|
||||
"task-edit": {
|
||||
"n": 407,
|
||||
"errors": 0,
|
||||
"p95_s": 0.0657
|
||||
},
|
||||
"tender-create": {
|
||||
"n": 407,
|
||||
"errors": 0,
|
||||
"p95_s": 0.0661
|
||||
},
|
||||
"tender-edit": {
|
||||
"n": 407,
|
||||
"errors": 0,
|
||||
"p95_s": 0.0587
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"ordinary": {
|
||||
"requests": 3675,
|
||||
"errors": 0,
|
||||
"p95_seconds": 0.19182809395715594
|
||||
},
|
||||
"document_transfer": {
|
||||
"requests": 814,
|
||||
"errors": 0,
|
||||
"p95_seconds": 0.07621732295956463
|
||||
},
|
||||
"complete": true,
|
||||
"provisional_pass": true,
|
||||
"measurement_complete": true,
|
||||
"measurement_gaps": [],
|
||||
"startup_seconds": 0.04661138809751719,
|
||||
"duration_seconds": 201.53947580303065,
|
||||
"completed_iterations": {
|
||||
"ordinary": [
|
||||
106,
|
||||
105
|
||||
],
|
||||
"burst": [
|
||||
39,
|
||||
38
|
||||
],
|
||||
"recovery": [
|
||||
59,
|
||||
60
|
||||
]
|
||||
},
|
||||
"host": {
|
||||
"logical_cpus": 4,
|
||||
"affinity_cpus": 4,
|
||||
"cpu_model": "AMD EPYC Processor (with IBPB)",
|
||||
"memory_total": "MemTotal: 16377032 kB",
|
||||
"cgroup_cpu_max": "100000 100000",
|
||||
"app_cpu_quota": 1.0
|
||||
}
|
||||
},
|
||||
"phase_results": [
|
||||
{
|
||||
"name": "ordinary",
|
||||
"kind": "load",
|
||||
"seconds": 91.06608834001236,
|
||||
"started_at": "2026-10-21T06:30:01.523056+00:00",
|
||||
"finished_at": "2026-10-21T06:31:32.589152+00:00",
|
||||
"expected_requests": 2325,
|
||||
"actual_requests": 2325,
|
||||
"complete": true,
|
||||
"ordinary": {
|
||||
"requests": 1903,
|
||||
"errors": 0,
|
||||
"p95_seconds": 0.14162223995663226
|
||||
},
|
||||
"document_transfer": {
|
||||
"requests": 422,
|
||||
"errors": 0,
|
||||
"p95_seconds": 0.08520571992266923
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "burst",
|
||||
"kind": "load",
|
||||
"seconds": 30.685886312043294,
|
||||
"started_at": "2026-10-21T06:31:32.589194+00:00",
|
||||
"finished_at": "2026-10-21T06:32:03.275085+00:00",
|
||||
"expected_requests": 851,
|
||||
"actual_requests": 851,
|
||||
"complete": true,
|
||||
"ordinary": {
|
||||
"requests": 697,
|
||||
"errors": 0,
|
||||
"p95_seconds": 0.19206618797034025
|
||||
},
|
||||
"document_transfer": {
|
||||
"requests": 154,
|
||||
"errors": 0,
|
||||
"p95_seconds": 0.06853019201662391
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "restart",
|
||||
"kind": "restart",
|
||||
"seconds": 18.981462653027847,
|
||||
"started_at": "2026-10-21T06:32:03.275117+00:00",
|
||||
"finished_at": "2026-10-21T06:32:22.256585+00:00",
|
||||
"ready": true
|
||||
},
|
||||
{
|
||||
"name": "recovery",
|
||||
"kind": "load",
|
||||
"seconds": 60.80042844603304,
|
||||
"started_at": "2026-10-21T06:32:22.256609+00:00",
|
||||
"finished_at": "2026-10-21T06:33:23.057045+00:00",
|
||||
"expected_requests": 1313,
|
||||
"actual_requests": 1313,
|
||||
"complete": true,
|
||||
"ordinary": {
|
||||
"requests": 1075,
|
||||
"errors": 0,
|
||||
"p95_seconds": 0.21410848898813128
|
||||
},
|
||||
"document_transfer": {
|
||||
"requests": 238,
|
||||
"errors": 0,
|
||||
"p95_seconds": 0.07255190098658204
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
import json, math, sys, gzip, collections
|
||||
from datetime import datetime
|
||||
R = sys.argv[1]
|
||||
def ts(x): return datetime.fromisoformat(x.replace("Z", "+00:00").replace(".", ".", 1)[:26] + ("+00:00" if "+" not in x[19:] and not x.endswith("Z") else "")).timestamp() if False else _ts(x)
|
||||
def _ts(x):
|
||||
x = x.rstrip("Z")
|
||||
if "+" in x[19:]: x = x[:x.index("+", 19)]
|
||||
if "." in x: a, b = x.split("."); x = a + "." + b[:6]
|
||||
return datetime.fromisoformat(x + "+00:00").timestamp()
|
||||
def p95(v):
|
||||
v = sorted(v); return v[max(0, math.ceil(0.95 * len(v)) - 1)] if v else None
|
||||
def parse(path):
|
||||
segs, cur, s = [], None, None
|
||||
for line in open(path):
|
||||
line = line.rstrip("\n")
|
||||
if line.startswith("POD "): cur = {"pod": line.split()[1], "samples": []}; segs.append(cur)
|
||||
elif line.startswith("S "):
|
||||
s = {"t": float(line[2:])}; cur["samples"].append(s)
|
||||
elif s is None: continue
|
||||
elif line.startswith("M "): s["mem"] = int(line[2:])
|
||||
elif line.startswith("P "): s["psi_some_total"] = int(line.split("total=")[1])
|
||||
elif line.startswith("N "):
|
||||
f = [int(x) for x in line.split()[2:]]; s["node_total"] = sum(f[:8]); s["node_idle"] = f[3] + f[4]
|
||||
elif line.startswith("L "): s["load1"] = float(line.split()[1])
|
||||
elif line.split() and line.split()[0] in ("usage_usec","nr_periods","nr_throttled","throttled_usec"):
|
||||
k, v = line.split(); s[k] = int(v)
|
||||
for seg in segs: seg["samples"] = [x for x in seg["samples"] if "mem" in x and "node_total" in x and "usage_usec" in x]
|
||||
return segs
|
||||
def window(segs, a, b, cores=4):
|
||||
rates, mems, thr_p, per_p, thr_us, nodebusy, psi, load = [], [], 0, 0, 0, [], 0, []
|
||||
span = 0; used = 0
|
||||
for seg in segs:
|
||||
xs = [x for x in seg["samples"] if a <= x["t"] <= b]
|
||||
for x in xs: mems.append(x["mem"]); load.append(x["load1"])
|
||||
for p, q in zip(xs, xs[1:]):
|
||||
dt = q["t"] - p["t"]
|
||||
if dt <= 0 or dt > 5: continue
|
||||
du = q["usage_usec"] - p["usage_usec"]; used += du; span += dt
|
||||
rates.append(du / 1e3 / dt)
|
||||
per_p += q.get("nr_periods",0) - p.get("nr_periods",0); thr_p += q.get("nr_throttled",0) - p.get("nr_throttled",0)
|
||||
thr_us += q.get("throttled_usec",0) - p.get("throttled_usec",0)
|
||||
psi += q["psi_some_total"] - p["psi_some_total"]
|
||||
tot = q["node_total"] - p["node_total"]; idle = q["node_idle"] - p["node_idle"]
|
||||
if tot > 0: nodebusy.append(cores * (tot - idle) / tot * 1000)
|
||||
if not rates: return None
|
||||
return {"samples": len(rates), "seconds": round(span,1), "cpu_mean_m": round(used/1e3/span,1), "cpu_p95_m": round(p95(rates),1), "cpu_peak_m": round(max(rates),1),
|
||||
"cfs_periods": per_p, "cfs_throttled_periods": thr_p, "throttle_ratio": round(thr_p/per_p,3) if per_p else None, "throttled_seconds": round(thr_us/1e6,2),
|
||||
"psi_cpu_some_share": round(psi/1e6/span,3), "mem_peak_mib": round(max(mems)/2**20,1), "mem_mean_mib": round(sum(mems)/len(mems)/2**20,1),
|
||||
"node_busy_mean_m": round(sum(nodebusy)/len(nodebusy)), "node_busy_p95_m": round(p95(nodebusy)), "node_free_mean_m": round(cores*1000-sum(nodebusy)/len(nodebusy)),
|
||||
"node_free_p5_m": round(cores*1000-p95(nodebusy)), "load1_max": max(load)}
|
||||
win = {}
|
||||
for line in open(f"{R}/windows.txt"):
|
||||
k, *v = line.split(); win[k] = v
|
||||
res = json.load(open(f"{R}/result.json"))
|
||||
W = {"baseline_pre": (_ts(win["baseline_start"][0]), _ts(win["driver_start"][0])),
|
||||
"harness_idle": (_ts(res["idle_window"]["started_at"]), _ts(res["idle_window"]["finished_at"]))}
|
||||
for p in res["phase_results"]: W[p["name"]] = (_ts(p["started_at"]), _ts(p["finished_at"]))
|
||||
loads = [p for p in res["phase_results"] if p["kind"] == "load"]
|
||||
W["workload_all_load_phases"] = (_ts(loads[0]["started_at"]), _ts(loads[-1]["finished_at"]))
|
||||
W["post"] = (_ts(win["driver_exit"][1]), _ts(win["post_end"][0]))
|
||||
out = {"windows_utc": {k: [datetime.utcfromtimestamp(a).isoformat()+"Z", datetime.utcfromtimestamp(b).isoformat()+"Z"] for k,(a,b) in W.items()}, "cgroup": {}}
|
||||
for name in ("app", "db", "driver"):
|
||||
segs = parse(f"{R}/{name}-cgroup.txt")
|
||||
out["cgroup"][name] = {"pods": [s["pod"] for s in segs], **{k: window(segs, a, b) for k, (a, b) in W.items() if k != "workload_all_load_phases" or True}}
|
||||
ops = collections.defaultdict(list)
|
||||
for r in res["operations"]: ops[(r["phase"], r["operation"])].append(r)
|
||||
out["per_operation"] = {f"{ph}/{op}": {"n": len(v), "errors": sum(not x["ok"] for x in v), "p95_s": round(p95([x["seconds"] for x in v]),4), "max_s": round(max(x["seconds"] for x in v),4)} for (ph, op), v in sorted(ops.items())}
|
||||
allops = collections.defaultdict(list)
|
||||
for r in res["operations"]: allops[r["operation"]].append(r)
|
||||
out["per_operation_all_phases"] = {op: {"n": len(v), "errors": sum(not x["ok"] for x in v), "p95_s": round(p95([x["seconds"] for x in v]),4)} for op, v in sorted(allops.items())}
|
||||
out["summary"] = {k: res[k] for k in ("ordinary","document_transfer","complete","provisional_pass","measurement_complete","measurement_gaps","startup_seconds","duration_seconds","completed_iterations","host")}
|
||||
out["phase_results"] = [{k: v for k, v in p.items() if k != "operations"} for p in res["phase_results"]]
|
||||
json.dump(out, open(sys.argv[2], "w"), indent=1)
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: vergabe-sizing-20261021
|
||||
labels:
|
||||
railiance.io/purpose: synthetic-sizing
|
||||
railiance.io/task: rapps-wp-0014-t04
|
||||
railiance.io/ephemeral: "true"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata: {name: bench-media, namespace: vergabe-sizing-20261021}
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
storageClassName: local-path
|
||||
resources: {requests: {storage: 5Gi}}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata: {name: vergabe-db, namespace: vergabe-sizing-20261021}
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy: {type: Recreate}
|
||||
selector: {matchLabels: {app: vergabe-sizing-db}}
|
||||
template:
|
||||
metadata: {labels: {app: vergabe-sizing-db}}
|
||||
spec:
|
||||
automountServiceAccountToken: false
|
||||
containers:
|
||||
- name: postgres
|
||||
image: docker.io/library/postgres@sha256:4b7183ac05f8ef417db21fd72d71047a4238340c261d3cc3ddb6d579ab5071ae
|
||||
imagePullPolicy: IfNotPresent
|
||||
env:
|
||||
- {name: POSTGRES_DB, value: synthetic}
|
||||
- {name: POSTGRES_USER, value: synthetic}
|
||||
- {name: POSTGRES_PASSWORD, value: synthetic-local-only}
|
||||
- {name: PGDATA, value: /var/lib/postgresql/data/pgdata}
|
||||
ports: [{containerPort: 5432}]
|
||||
readinessProbe: {exec: {command: [pg_isready, -U, synthetic]}, periodSeconds: 5}
|
||||
resources: {requests: {cpu: 100m, memory: 256Mi}, limits: {cpu: "1", memory: 1Gi}}
|
||||
volumeMounts: [{name: data, mountPath: /var/lib/postgresql/data}]
|
||||
volumes: [{name: data, emptyDir: {}}]
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata: {name: vergabe-db, namespace: vergabe-sizing-20261021}
|
||||
spec: {selector: {app: vergabe-sizing-db}, ports: [{port: 5432, targetPort: 5432}]}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata: {name: vergabe-app, namespace: vergabe-sizing-20261021}
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy: {type: Recreate}
|
||||
selector: {matchLabels: {app: vergabe-sizing-app}}
|
||||
template:
|
||||
metadata: {labels: {app: vergabe-sizing-app}}
|
||||
spec:
|
||||
automountServiceAccountToken: false
|
||||
securityContext: {fsGroup: 999, runAsGroup: 999, runAsNonRoot: true, runAsUser: 999}
|
||||
initContainers:
|
||||
- name: migrate
|
||||
image: forgejo.coulomb.social/coulomb/vergabe-teilnahme@sha256:a26444f59c259698159c69ccb96f73dc648a261ece4c86bb2037a9d977870d91
|
||||
imagePullPolicy: IfNotPresent
|
||||
command: [python, manage.py, migrate, --noinput]
|
||||
env: &env
|
||||
- {name: DJANGO_SETTINGS_MODULE, value: synthetic_settings}
|
||||
- {name: PYTHONPATH, value: /synthetic}
|
||||
- {name: SECRET_KEY, value: synthetic-disposable-not-a-deployment-key}
|
||||
- {name: DATABASE_URL, value: "postgres://synthetic:synthetic-local-only@vergabe-db:5432/synthetic"}
|
||||
resources: &res {requests: {cpu: 60m, memory: 256Mi}, limits: {cpu: "1", memory: 1Gi}}
|
||||
securityContext: &sc {allowPrivilegeEscalation: false, capabilities: {drop: [ALL]}, readOnlyRootFilesystem: false}
|
||||
volumeMounts: [{name: settings, mountPath: /synthetic}]
|
||||
containers:
|
||||
- name: app
|
||||
image: forgejo.coulomb.social/coulomb/vergabe-teilnahme@sha256:a26444f59c259698159c69ccb96f73dc648a261ece4c86bb2037a9d977870d91
|
||||
imagePullPolicy: IfNotPresent
|
||||
env: *env
|
||||
ports: [{containerPort: 8000, name: http}]
|
||||
readinessProbe: {httpGet: {path: /health/, port: 8000, httpHeaders: [{name: Host, value: vergabe-app}]}, initialDelaySeconds: 5, periodSeconds: 10, timeoutSeconds: 5, failureThreshold: 3}
|
||||
livenessProbe: {httpGet: {path: /health/, port: 8000, httpHeaders: [{name: Host, value: vergabe-app}]}, initialDelaySeconds: 30, periodSeconds: 30, timeoutSeconds: 5, failureThreshold: 3}
|
||||
resources: *res
|
||||
securityContext: *sc
|
||||
volumeMounts:
|
||||
- {name: settings, mountPath: /synthetic}
|
||||
- {name: media, mountPath: /app/media}
|
||||
- {name: app-state, mountPath: /app/.issue-facade}
|
||||
volumes:
|
||||
- {name: settings, configMap: {name: synthetic-settings}}
|
||||
- {name: media, persistentVolumeClaim: {claimName: bench-media}}
|
||||
- {name: app-state, emptyDir: {}}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata: {name: vergabe-app, namespace: vergabe-sizing-20261021}
|
||||
spec: {selector: {app: vergabe-sizing-app}, ports: [{port: 80, targetPort: 8000}]}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata: {name: synthetic-driver, namespace: vergabe-sizing-20261021}
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata: {name: synthetic-driver-restart, namespace: vergabe-sizing-20261021}
|
||||
rules: [{apiGroups: [""], resources: [pods], verbs: [get, list, delete]}]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata: {name: synthetic-driver-restart, namespace: vergabe-sizing-20261021}
|
||||
roleRef: {apiGroup: rbac.authorization.k8s.io, kind: Role, name: synthetic-driver-restart}
|
||||
subjects: [{kind: ServiceAccount, name: synthetic-driver, namespace: vergabe-sizing-20261021}]
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata: {name: synthetic-isolation, namespace: vergabe-sizing-20261021}
|
||||
spec:
|
||||
podSelector: {}
|
||||
policyTypes: [Ingress, Egress]
|
||||
ingress: [{from: [{podSelector: {}}]}]
|
||||
egress:
|
||||
- to: [{podSelector: {}}]
|
||||
- to: [{namespaceSelector: {matchLabels: {kubernetes.io/metadata.name: kube-system}}, podSelector: {matchLabels: {k8s-app: kube-dns}}}]
|
||||
ports: [{port: 53, protocol: UDP}, {port: 53, protocol: TCP}]
|
||||
- to: [{ipBlock: {cidr: 92.205.62.239/32}}, {ipBlock: {cidr: 10.43.0.1/32}}]
|
||||
ports: [{port: 6443, protocol: TCP}, {port: 443, protocol: TCP}]
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
{
|
||||
"users": 2,
|
||||
"workers": 3,
|
||||
"iterations": 100000,
|
||||
"tenders": 100,
|
||||
"document_bytes": 1048576,
|
||||
"think_seconds": 0.2,
|
||||
"timeout_seconds": 30,
|
||||
"ordinary_p95_seconds": 2.0,
|
||||
"duration_seconds": 180,
|
||||
"idle_seconds": 30,
|
||||
"runtime": "remote",
|
||||
"app_image": "forgejo.coulomb.social/coulomb/vergabe-teilnahme@sha256:a26444f59c259698159c69ccb96f73dc648a261ece4c86bb2037a9d977870d91",
|
||||
"app_cpu_limit": 1.0,
|
||||
"app_memory_limit": "1Gi",
|
||||
"operations": [
|
||||
"list",
|
||||
"search",
|
||||
"tender-create",
|
||||
"detail",
|
||||
"tender-edit",
|
||||
"lot-create",
|
||||
"lot-edit",
|
||||
"task-create",
|
||||
"task-edit",
|
||||
"document-upload",
|
||||
"document-download"
|
||||
],
|
||||
"phases": [
|
||||
{
|
||||
"name": "ordinary",
|
||||
"kind": "load",
|
||||
"duration_seconds": 90,
|
||||
"think_seconds": 0.2
|
||||
},
|
||||
{
|
||||
"name": "burst",
|
||||
"kind": "load",
|
||||
"duration_seconds": 30,
|
||||
"think_seconds": 0
|
||||
},
|
||||
{
|
||||
"name": "restart",
|
||||
"kind": "restart"
|
||||
},
|
||||
{
|
||||
"name": "recovery",
|
||||
"kind": "load",
|
||||
"duration_seconds": 60,
|
||||
"think_seconds": 0.2
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata: {name: synthetic-driver, namespace: vergabe-sizing-20261021, labels: {app: vergabe-sizing-driver}}
|
||||
spec:
|
||||
serviceAccountName: synthetic-driver
|
||||
restartPolicy: Never
|
||||
securityContext: {runAsGroup: 999, runAsNonRoot: true, runAsUser: 999}
|
||||
containers:
|
||||
- name: driver
|
||||
image: forgejo.coulomb.social/coulomb/vergabe-teilnahme@sha256:a26444f59c259698159c69ccb96f73dc648a261ece4c86bb2037a9d977870d91
|
||||
imagePullPolicy: IfNotPresent
|
||||
workingDir: /app
|
||||
command: [sleep, "7200"]
|
||||
env:
|
||||
- {name: PYTHONPATH, value: /app}
|
||||
- {name: SYNTHETIC_BASE_URL, value: "http://vergabe-app"}
|
||||
- {name: SYNTHETIC_DATABASE_URL, value: "postgres://synthetic:synthetic-local-only@vergabe-db:5432/synthetic"}
|
||||
- {name: SYNTHETIC_RESTART_SELECTOR, value: "app=vergabe-sizing-app"}
|
||||
- {name: SYNTHETIC_SOURCE_REVISION, value: "deployed image c067993037f1cdeeb7b22d5600b51c649bc239db; driver from vergabe-teilnahme working tree"}
|
||||
- {name: SYNTHETIC_DATABASE_DESCRIPTION, value: "fresh PostgreSQL 16 pod in throwaway namespace (docker.io/library/postgres:16 pinned digest)"}
|
||||
- {name: SYNTHETIC_TRANSPORT_DESCRIPTION, value: "in-cluster HTTP via ClusterIP Service to Gunicorn (image CMD, 3 workers)"}
|
||||
resources: {requests: {cpu: 100m, memory: 256Mi}, limits: {cpu: "1", memory: 1Gi}}
|
||||
securityContext: {allowPrivilegeEscalation: false, capabilities: {drop: [ALL]}}
|
||||
volumeMounts:
|
||||
- {name: driver, mountPath: /driver}
|
||||
- {name: out, mountPath: /out}
|
||||
volumes:
|
||||
- {name: driver, configMap: {name: synthetic-driver}}
|
||||
- {name: out, emptyDir: {}}
|
||||
File diff suppressed because it is too large
Load diff
15
docs/evidence/2026-10-21-vergabe-target-replay/harness/orchestrate.sh
Executable file
15
docs/evidence/2026-10-21-vergabe-target-replay/harness/orchestrate.sh
Executable file
|
|
@ -0,0 +1,15 @@
|
|||
#!/bin/bash
|
||||
NS=vergabe-sizing-20261021; W=$SCRATCH; R=$W/raw; STOP=$R/stop; rm -f $STOP
|
||||
$SCRATCH/sampler.sh app=vergabe-sizing-app app $R/app-cgroup.txt $STOP &
|
||||
$SCRATCH/sampler.sh app=vergabe-sizing-db postgres $R/db-cgroup.txt $STOP &
|
||||
$SCRATCH/sampler.sh app=vergabe-sizing-driver driver $R/driver-cgroup.txt $STOP &
|
||||
$SCRATCH/top.sh $R/kubectl-top.txt $STOP &
|
||||
echo "baseline_start $(date -u +%FT%T.%NZ)" > $R/windows.txt
|
||||
sleep 120
|
||||
echo "driver_start $(date -u +%FT%T.%NZ)" >> $R/windows.txt
|
||||
kubectl -n $NS exec synthetic-driver -- python /driver/synthetic_pilot.py --config /driver/config.json --output /out/result.json > $R/driver-stdout.txt 2>&1
|
||||
echo "driver_exit $? $(date -u +%FT%T.%NZ)" >> $R/windows.txt
|
||||
sleep 60
|
||||
echo "post_end $(date -u +%FT%T.%NZ)" >> $R/windows.txt
|
||||
touch $STOP; sleep 3; wait
|
||||
echo done
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import json, subprocess, sys, urllib.parse
|
||||
start, end, out = sys.argv[1], sys.argv[2], sys.argv[3]
|
||||
P = "/api/v1/namespaces/telemetry/services/telemetry-prometheus:9090/proxy/api/v1/query_range?"
|
||||
def q(expr, step="15s"):
|
||||
url = P + urllib.parse.urlencode({"query": expr, "start": start, "end": end, "step": step})
|
||||
return json.loads(subprocess.check_output(["kubectl", "get", "--raw", url]))
|
||||
res = {"window": [start, end], "queries": {}}
|
||||
for name, expr in {
|
||||
"cpu_by_namespace_cores": 'sum by (namespace) (rate(container_cpu_usage_seconds_total{container!="",image!=""}[1m]))',
|
||||
"throttled_ratio_by_namespace": 'sum by (namespace) (rate(container_cpu_cfs_throttled_periods_total{container!=""}[1m])) / sum by (namespace) (rate(container_cpu_cfs_periods_total{container!=""}[1m]))',
|
||||
"memory_working_set_by_namespace_bytes": 'sum by (namespace) (container_memory_working_set_bytes{container!="",image!=""})',
|
||||
"apps_pg_cpu_cores": 'sum by (pod) (rate(container_cpu_usage_seconds_total{namespace="databases",container!="",image!=""}[1m]))',
|
||||
"live_vergabe_cpu_cores": 'sum (rate(container_cpu_usage_seconds_total{namespace="vergabe-demo-company",container!="",image!=""}[1m]))',
|
||||
}.items():
|
||||
r = q(expr)
|
||||
res["queries"][name] = {"expr": expr, "result": r["data"]["result"]}
|
||||
json.dump(res, open(out, "w"))
|
||||
# summary: mean per namespace cpu
|
||||
s = {}
|
||||
for series in res["queries"]["cpu_by_namespace_cores"]["result"]:
|
||||
v = [float(x[1]) for x in series["values"]]
|
||||
s[series["metric"].get("namespace", "?")] = (round(1000*sum(v)/len(v)), round(1000*max(v)))
|
||||
tot = sum(a for a, b in s.values())
|
||||
print("container_total_mean_m", tot)
|
||||
for k, v in sorted(s.items(), key=lambda kv: -kv[1][0])[:15]: print(k, "mean_m", v[0], "max_m", v[1])
|
||||
16
docs/evidence/2026-10-21-vergabe-target-replay/harness/sampler.sh
Executable file
16
docs/evidence/2026-10-21-vergabe-target-replay/harness/sampler.sh
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash
|
||||
# usage: sampler.sh <label-selector> <container> <outfile> <stopfile>
|
||||
NS=vergabe-sizing-20261021; SEL=$1; C=$2; OUT=$3; STOP=$4
|
||||
LOOP='while :; do echo "S $(date +%s.%N)"; cat /sys/fs/cgroup/cpu.stat; echo "M $(cat /sys/fs/cgroup/memory.current)"; echo "P $(head -1 /sys/fs/cgroup/cpu.pressure)"; echo "N $(head -1 /proc/stat)"; echo "L $(cat /proc/loadavg)"; sleep 1; done'
|
||||
while [ ! -e "$STOP" ]; do
|
||||
POD=$(kubectl -n $NS get pod -l "$SEL" --field-selector=status.phase=Running -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||||
if [ -n "$POD" ]; then
|
||||
echo "POD $POD $(date +%s.%N)" >> "$OUT"
|
||||
timeout 1500 kubectl -n $NS exec "$POD" -c "$C" -- sh -c "$LOOP" >> "$OUT" 2>>"$OUT.err" &
|
||||
PID=$!
|
||||
while kill -0 $PID 2>/dev/null && [ ! -e "$STOP" ]; do sleep 1; done
|
||||
kill $PID 2>/dev/null
|
||||
echo "DETACH $(date +%s.%N)" >> "$OUT"
|
||||
fi
|
||||
sleep 0.5
|
||||
done
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
from vergabe_teilnahme.settings.base import *
|
||||
DEBUG = False
|
||||
ALLOWED_HOSTS = ['vergabe-app']
|
||||
NETKINGDOM_ENABLED = False
|
||||
MEDIA_ROOT = '/app/media'
|
||||
ISSUE_FACADE_LOCAL_DB = '/app/.issue-facade/issues.db'
|
||||
ISSUE_FACADE_GITEA = None
|
||||
FORCE_SCRIPT_NAME = None
|
||||
MEDIA_URL = "/media/"
|
||||
EMAIL_BACKEND = "django.core.mail.backends.locmem.EmailBackend"
|
||||
SESSION_COOKIE_SECURE = False
|
||||
CSRF_COOKIE_SECURE = False
|
||||
3
docs/evidence/2026-10-21-vergabe-target-replay/harness/top.sh
Executable file
3
docs/evidence/2026-10-21-vergabe-target-replay/harness/top.sh
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/bash
|
||||
OUT=$1; STOP=$2
|
||||
while [ ! -e "$STOP" ]; do echo "T $(date -u +%s)"; kubectl top pods -A --no-headers 2>&1; kubectl top node --no-headers 2>&1; sleep 15; done >> $OUT
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1 @@
|
|||
{"ordinary": {"requests": 3675, "errors": 0, "p95_seconds": 0.19182809395715594}, "document_transfer": {"requests": 814, "errors": 0, "p95_seconds": 0.07621732295956463}, "complete": true, "provisional_pass": true}
|
||||
Binary file not shown.
|
|
@ -0,0 +1,36 @@
|
|||
T R O M
|
||||
<nil> Scheduled vergabe-app-579448bf49-2fsn2 Successfully assigned vergabe-sizing-20261021/vergabe-app-579448bf49-2fsn2 to 239.62.205.92.host.secureserver.net
|
||||
<nil> Scheduled vergabe-db-7c4bffdd48-w4jz4 Successfully assigned vergabe-sizing-20261021/vergabe-db-7c4bffdd48-w4jz4 to 239.62.205.92.host.secureserver.net
|
||||
<nil> Scheduled synthetic-driver Successfully assigned vergabe-sizing-20261021/synthetic-driver to 239.62.205.92.host.secureserver.net
|
||||
<nil> Scheduled vergabe-app-579448bf49-plp4j Successfully assigned vergabe-sizing-20261021/vergabe-app-579448bf49-plp4j to 239.62.205.92.host.secureserver.net
|
||||
2026-10-21T06:26:14Z ScalingReplicaSet vergabe-db Scaled up replica set vergabe-db-7c4bffdd48 from 0 to 1
|
||||
2026-10-21T06:26:14Z SuccessfulCreate vergabe-db-7c4bffdd48 Created pod: vergabe-db-7c4bffdd48-w4jz4
|
||||
2026-10-21T06:26:14Z WaitForFirstConsumer bench-media waiting for first consumer to be created before binding
|
||||
2026-10-21T06:26:16Z SuccessfulCreate vergabe-app-579448bf49 Created pod: vergabe-app-579448bf49-2fsn2
|
||||
2026-10-21T06:26:16Z ScalingReplicaSet vergabe-app Scaled up replica set vergabe-app-579448bf49 from 0 to 1
|
||||
2026-10-21T06:26:16Z Pulled vergabe-db-7c4bffdd48-w4jz4 Container image "docker.io/library/postgres@sha256:4b7183ac05f8ef417db21fd72d71047a4238340c261d3cc3ddb6d579ab5071ae" already present on machine and can be accessed by the pod
|
||||
2026-10-21T06:26:16Z Created vergabe-db-7c4bffdd48-w4jz4 Container created
|
||||
2026-10-21T06:26:16Z Provisioning bench-media External provisioner is provisioning volume for claim "vergabe-sizing-20261021/bench-media"
|
||||
2026-10-21T06:26:16Z Started vergabe-db-7c4bffdd48-w4jz4 Container started
|
||||
2026-10-21T06:26:19Z Unhealthy vergabe-db-7c4bffdd48-w4jz4 Readiness probe failed: /var/run/postgresql:5432 - no response
|
||||
|
||||
2026-10-21T06:26:21Z Created synthetic-driver Container created
|
||||
2026-10-21T06:26:21Z ExternalProvisioning bench-media Waiting for a volume to be created either by the external provisioner 'rancher.io/local-path' or manually by the system administrator. If volume creation is delayed, please verify that the provisioner is running and correctly registered.
|
||||
2026-10-21T06:26:21Z Pulled synthetic-driver Container image "forgejo.coulomb.social/coulomb/vergabe-teilnahme@sha256:a26444f59c259698159c69ccb96f73dc648a261ece4c86bb2037a9d977870d91" already present on machine and can be accessed by the pod
|
||||
2026-10-21T06:26:22Z Started synthetic-driver Container started
|
||||
2026-10-21T06:26:25Z ProvisioningSucceeded bench-media Successfully provisioned volume pvc-a23ccb84-ecd8-47af-9832-6d8b09c48e38
|
||||
2026-10-21T06:26:26Z Started vergabe-app-579448bf49-2fsn2 Container started
|
||||
2026-10-21T06:26:26Z Created vergabe-app-579448bf49-2fsn2 Container created
|
||||
2026-10-21T06:26:26Z Pulled vergabe-app-579448bf49-2fsn2 Container image "forgejo.coulomb.social/coulomb/vergabe-teilnahme@sha256:a26444f59c259698159c69ccb96f73dc648a261ece4c86bb2037a9d977870d91" already present on machine and can be accessed by the pod
|
||||
2026-10-21T06:26:32Z Started vergabe-app-579448bf49-2fsn2 Container started
|
||||
2026-10-21T06:26:32Z Created vergabe-app-579448bf49-2fsn2 Container created
|
||||
2026-10-21T06:26:32Z Pulled vergabe-app-579448bf49-2fsn2 Container image "forgejo.coulomb.social/coulomb/vergabe-teilnahme@sha256:a26444f59c259698159c69ccb96f73dc648a261ece4c86bb2037a9d977870d91" already present on machine and can be accessed by the pod
|
||||
2026-10-21T06:32:03Z SuccessfulCreate vergabe-app-579448bf49 Created pod: vergabe-app-579448bf49-plp4j
|
||||
2026-10-21T06:32:03Z Killing vergabe-app-579448bf49-2fsn2 Stopping container app
|
||||
2026-10-21T06:32:04Z Started vergabe-app-579448bf49-plp4j Container started
|
||||
2026-10-21T06:32:04Z Created vergabe-app-579448bf49-plp4j Container created
|
||||
2026-10-21T06:32:04Z Pulled vergabe-app-579448bf49-plp4j Container image "forgejo.coulomb.social/coulomb/vergabe-teilnahme@sha256:a26444f59c259698159c69ccb96f73dc648a261ece4c86bb2037a9d977870d91" already present on machine and can be accessed by the pod
|
||||
2026-10-21T06:32:04Z Unhealthy vergabe-app-579448bf49-2fsn2 Readiness probe failed: Get "http://10.42.0.96:8000/health/": dial tcp 10.42.0.96:8000: connect: connection refused
|
||||
2026-10-21T06:32:09Z Started vergabe-app-579448bf49-plp4j Container started
|
||||
2026-10-21T06:32:09Z Created vergabe-app-579448bf49-plp4j Container created
|
||||
2026-10-21T06:32:09Z Pulled vergabe-app-579448bf49-plp4j Container image "forgejo.coulomb.social/coulomb/vergabe-teilnahme@sha256:a26444f59c259698159c69ccb96f73dc648a261ece4c86bb2037a9d977870d91" already present on machine and can be accessed by the pod
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
synthetic-driver driver forgejo.coulomb.social/coulomb/vergabe-teilnahme@sha256:a26444f59c259698159c69ccb96f73dc648a261ece4c86bb2037a9d977870d91 0 {} ['running']
|
||||
vergabe-app-579448bf49-plp4j migrate forgejo.coulomb.social/coulomb/vergabe-teilnahme@sha256:a26444f59c259698159c69ccb96f73dc648a261ece4c86bb2037a9d977870d91 0 {} ['terminated']
|
||||
vergabe-app-579448bf49-plp4j app forgejo.coulomb.social/coulomb/vergabe-teilnahme@sha256:a26444f59c259698159c69ccb96f73dc648a261ece4c86bb2037a9d977870d91 0 {} ['running']
|
||||
vergabe-db-7c4bffdd48-w4jz4 postgres docker.io/library/postgres@sha256:4b7183ac05f8ef417db21fd72d71047a4238340c261d3cc3ddb6d579ab5071ae 0 {} ['running']
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,7 @@
|
|||
delete_requested 2026-10-21T06:35:25Z
|
||||
namespace "vergabe-sizing-20261021" deleted
|
||||
delete_returned 2026-10-21T06:36:18Z
|
||||
Error from server (NotFound): namespaces "vergabe-sizing-20261021" not found
|
||||
Error from server (NotFound): persistentvolumes "pvc-a23ccb84-ecd8-47af-9832-6d8b09c48e38" not found
|
||||
0
|
||||
live generation=4 image=forgejo.coulomb.social/coulomb/vergabe-teilnahme@sha256:a26444f59c259698159c69ccb96f73dc648a261ece4c86bb2037a9d977870d91 ready=1
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
baseline_start 2026-10-21T06:27:14.447540583Z
|
||||
driver_start 2026-10-21T06:29:26.175778371Z
|
||||
driver_exit 0 2026-10-21T06:33:22.885983171Z
|
||||
post_end 2026-10-21T06:34:28.753426744Z
|
||||
Loading…
Add table
Add a link
Reference in a new issue