Skip to main content
Yanked

This release has been yanked by its maintainers, and will be ignored by installers, except when explicitly specified.
Consider using release 0.6.0 instead.
Reason given by maintainers: related container image removed

CI Coverage

License

podbench

A development seat — editor, gdb, a Python inner loop — inside a Kubernetes pod, reached over nothing but your kubeconfig.

podbench launches a debug container into a running pod (or into a sacrificial clone of one), tunnels ssh through kubectl exec, and hands you the config stanza that VS Code Remote-SSH needs. There is no port-forward to babysit, no pod IP to reach, no file sync and no traffic interception: the editor is already inside the cluster.

              laptop
     VS Code · Remote-SSH · kubectl
                 |
                 |  ssh over kubectl exec (API server only)
                 |
  +--------------+--------------------------------------+
  |  pod                                                 |
  |                                                      |
  |  +----------------------+  +----------------------+  |
  |  | app container        |  | podbench             |  |
  |  |                      |  |                      |  |
  |  | workload process     |  | sshd · vscode-server |  |
  |  |   (maybe distroless) |  | gdb · git · uv       |  |
  |  | fs visible at        |  |                      |  |
  |  |   /proc/<pid>/root   |  |                      |  |
  |  +----------------------+  +----------------------+  |
  |                                                      |
  |  shared: PID namespace (via the target)              |
  |          network namespace (always)                  |
  +------------------------------------------------------+

Two artefacts: a debug container image (ghcr.io/gilesknap/podbench) and a launcher you never have to installuvx podbench runs it straight from PyPI, uses your kubeconfig, and shells out to kubectl for everything it does to a cluster.

Observe mode Iterate mode Hotfix mode
Command uvx podbench attach pod/foo uvx podbench dev pod/foo uvx podbench hotfix init pod/foo
What it does adds an ephemeral container to the live pod authors a sacrificial clone with the app idled and podbench as a real sidecar puts the app's venv on a claim, so an edit survives the restart — and the restart is the relaunch
Built for distroless targets with no shell of their own; gdb against the running workload edit → relaunch → see the change through the Service an emergency fix that has to outlive the session, with provenance
Resources shares the workload's limits, cannot reserve its own has its own cpu, memory and ephemeral-storage requests a ReadWriteOnce claim, mounted at the same path on both sides
Needs nothing at deploy time nothing at deploy time deploy-time chart cooperation, and it is Python-only and single-replica-only
Risk to the workload real — see below none by default; the origin pod is never touched it rolls the workload: that is how the fix takes
Explained in What attach does What dev does What hotfix does

Try it

$ uvx podbench doctor
$ uvx podbench attach pod/web-7d9f8c5b4-x2k9p -n demo

doctor checks the prerequisites, the cluster-side RBAC and the one-time ssh Include line — the only thing podbench leaves behind — and names whatever is missing; --fix adds the Include. attach then walks a capability ladder, lands the best seat the cluster will admit, and runs its probe inside the container it just created, so the report is measured rather than inferred from the spec it asked for:

rung        full - root plus CAP_SYS_PTRACE
supports
  [x] live attach (gdb -p <pid>)
  [x] read-only inspect (/proc/<pid>/root, maps, environ)
      root, maps and environ readable
  [x] debug launched processes (podbench dbg --launch ./prog)
  [ ] iterate (edit, relaunch, verify through the Service)
  [x] ssh seat (Remote-SSH: editor, shell, git, sftp)
measured
  verdict     live attach available
  blocker     none

ssh config written to ~/.podbench/config.d/demo-web-7d9f8c5b4-x2k9p.conf
then:  ssh podbench-demo-web-7d9f8c5b4-x2k9p

Connect that alias with Remote-SSH: Connect to Host…, or let attach --open do it for you.

The other two modes are a table row away. For the inner loop, podbench dev authors the dev pod and podbench run relaunches the app inside it: measured end to end, 1.18 s per edit → relaunch → verified-through-the-Service cycle. When the fix has to survive the pod, podbench hotfix moves the venv onto a claim so a restart no longer restores the image's code, and records where the change came from.

The PyPI name is not published yet, so uvx podbench will not resolve until the first release. Until then, run every command as uvx --from git+https://github.com/gilesknap/podbench podbench <verb>.

Read this before you attach to a live pod

Not fine print — each of these has bitten a spike on a real cluster.

  • podbench can get your workload OOM-killed. An ephemeral container may not declare resources at all, so on a live pod the seat shares the workload's memory and ephemeral-storage limits and cannot reserve its own — and a VS Code session is a 1.1–1.3 GB working set. Exceed memory and the kernel OOM-kills something in the pod cgroup; exceed ephemeral storage and the kubelet evicts the whole pod. Anything heavier than looking belongs in a dev pod, which is immune. attach --resize buys headroom in place, opt-in.
  • Being refused SYS_PTRACE is normal, not an error. It is outside both the baseline and the restricted Pod Security Standards, so podbench walks a ladder with two valid rungs and lands the better one the cluster admits. Four unrelated subsystems deny attach with the same EPERM, so it probes and names the blocker instead of leaving you an errno.
  • Ephemeral containers are permanent. They cannot be removed, restarted or edited, and a name once used is burnt for the life of the pod. So attach reconnects by default, nothing may live only in the writable layer, and --new is for when you mean it.
  • A dev pod never joins a Service by accident. podbench dev drops the origin's selector labels unless you pass --take-traffic, and --cutover records the original selector for an exact restore.

The docs carry the reasoning and the measurements behind all four, and What is proven, and what is not is candid about the gaps — no real VS Code GUI client has connected yet, and Hotfix mode has never been run against a cluster.

What Where
Source https://github.com/gilesknap/podbench
Launcher https://pypi.org/project/podbench (not published yet)
Image ghcr.io/gilesknap/podbench
Chart oci://ghcr.io/gilesknap/charts/podbench
Documentation https://gilesknap.github.io/podbench
Releases https://github.com/gilesknap/podbench/releases

Documentation

See https://gilesknap.github.io/podbench for the full documentation.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

podbench-0.4.0b1.tar.gz (922.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

podbench-0.4.0b1-py3-none-any.whl (292.4 kB view details)

Uploaded Python 3

File details

Details for the file podbench-0.4.0b1.tar.gz.

File metadata

  • Download URL: podbench-0.4.0b1.tar.gz
  • Upload date:
  • Size: 922.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for podbench-0.4.0b1.tar.gz
Algorithm Hash digest
SHA256 bcc0d8377e7acc6ff10c748c6b8cecba96b8b9095d8154ab59904778040a870d
MD5 346726e633b893bf9226b7b100aec7ba
BLAKE2b-256 a15ab3d4e7ea479132772dd5d05d862d79a21f1b8171c003fb8795d36d6dc607

See more details on using hashes here.

File details

Details for the file podbench-0.4.0b1-py3-none-any.whl.

File metadata

  • Download URL: podbench-0.4.0b1-py3-none-any.whl
  • Upload date:
  • Size: 292.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for podbench-0.4.0b1-py3-none-any.whl
Algorithm Hash digest
SHA256 757d2a20b9c5be1af920140d65b2bb996ed5f79eee3cff156fafc415debc13e5
MD5 bf20349d0b0a38645c72b9dd32b9583a
BLAKE2b-256 8efa936ed03a19f17beebc18270a2e286e49ebd36d117c7b5096dd15b50622f5

See more details on using hashes here.

Release history Release notifications | RSS feed

0.6.0

2 files

0.5.0

2 files

0.4.0

2 files

0.4.0b3

2 files

This release

0.4.0b1 This release

2 files

0.3.0b1

2 files

0.2.0b2

2 files

0.2.0b1

2 files

0.1.0b5

2 files

0.1.0b4

2 files

0.1.0b3

2 files

0.1.0b2

2 files

0.1.0b1

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page