Skip to content

Releases: atedgimo/k8s-dencer

v0.10.0

Choose a tag to compare

@github-actions github-actions released this 16 Aug 18:31
18b6e37

What's Changed

  • Ask whether the cluster can drain anything, at minute three by @atedgimo in #227
  • Give the docs one index, and the README a status you can read by @atedgimo in #228
  • Say where a finding holds capacity, not just how much by @atedgimo in #229
  • Say what the History bars have been saying by @atedgimo in #231
  • Tell someone a plan exists by @atedgimo in #232
  • Document v0.10.0, and bump the chart to match by @atedgimo in #233

Full Changelog: v0.9.0...v0.10.0

v0.9.0

Choose a tag to compare

@github-actions github-actions released this 15 Aug 18:23
ac0140e

What's Changed

  • Prepare the GKE run: what to look at, and what to keep by @atedgimo in #209
  • One command for everything except the spending by @atedgimo in #210
  • Fix the four harness bugs a laptop could not have found by @atedgimo in #215
  • Stop hiding the nodes that are already free by @atedgimo in #214
  • Put the money on the screen where the decision is made by @atedgimo in #216
  • Give the e2e a node it is allowed to drain by @atedgimo in #219
  • Let a better explanation reach a plan that already exists by @atedgimo in #218
  • Export a plan as a change record by @atedgimo in #221
  • Lead with the answer, and survive a narrow viewport by @atedgimo in #220
  • Document v0.9.0, and bump the chart to match by @atedgimo in #226

Full Changelog: v0.8.1...v0.9.0

v0.8.1

Choose a tag to compare

@github-actions github-actions released this 15 Aug 07:31
6f6d4e3

What's Changed

  • Stop the e2e draining its own feet by @atedgimo in #204
  • Give the resilience audit a screen, and stop it crying wolf by @atedgimo in #203
  • Remove the UI that cannot do anything by @atedgimo in #202
  • Let the two request screens mention each other by @atedgimo in #205
  • Prepare the GKE run's Postgres phase, and fix what rehearsing it found by @atedgimo in #206
  • Three bugs found by driving the real UI, and the tooling that found them by @atedgimo in #207
  • Document v0.8.1, and bump the chart to match by @atedgimo in #208

Full Changelog: v0.8.0...v0.8.1

v0.8.0

Choose a tag to compare

@github-actions github-actions released this 13 Aug 17:46
ddb734a

What's Changed

  • Say the right thing about sslMode=disable by @atedgimo in #186
  • Find the backend by label, and stop calling a live plan stale by @atedgimo in #188
  • Run the e2e against both plan stores by @atedgimo in #189
  • Reconnect the e2e port-forward when the drain takes its pod by @atedgimo in #192
  • Name the failure instead of taking the Service down by @atedgimo in #191
  • Document v0.8.0, and bump the chart to match by @atedgimo in #193

Full Changelog: v0.7.0...v0.8.0

v0.7.0

Choose a tag to compare

@github-actions github-actions released this 12 Aug 19:20
5eedd1c

What's Changed

  • Make the Postgres store actually work, and close the hole it came through (v0.7.0) by @atedgimo in #185

Full Changelog: v0.6.0...v0.7.0

v0.6.0

Choose a tag to compare

@github-actions github-actions released this 12 Aug 18:36
75d09b8

What's Changed

  • Keep the capture harness, and give the playground a price by @atedgimo in #171
  • Bump modernc.org/sqlite from 1.55.0 to 1.56.0 in the go-minor-and-patch group by @dependabot[bot] in #172
  • Bump vite from 8.2.0 to 8.2.1 in /ui in the npm-minor-and-patch group by @dependabot[bot] in #173
  • Test the upgrade path an operator actually takes by @atedgimo in #174
  • One store that speaks two dialects, rather than two stores by @atedgimo in #176
  • Give the store an insertion order it declares itself (schema v14) by @atedgimo in #177
  • Teach the store Postgres, and make a real server test it by @atedgimo in #178
  • Let an install choose Postgres, and drop what SQLite needed by @atedgimo in #179
  • Prove Postgres migrations resume, before one has to by @atedgimo in #182
  • Document v0.6.0, and bump the chart to match by @atedgimo in #184

Full Changelog: v0.5.0...v0.6.0

v0.5.0

Choose a tag to compare

@github-actions github-actions released this 07 Aug 19:21
6807a35

This is the release that made the product work on managed clusters — because a
real one showed that it did not.

It could not plan on a managed cluster at all

GKE runs kube-proxy as a static pod owned by the node. The analyzer recognised
only DaemonSets as pinned, so it tried to reschedule a pod nothing can move,
failed to place it, and marked every node undrainable. converge reported
nothing to do while Google's own autoscaler reclaimed two nodes from the same
cluster three minutes later.

Its inverse was fixed with it: DaemonSet pods cannot move but do not hold a
drain up, and counting them meant preflight reported "0 of N nodes will
drain cleanly" on every real cluster in existence.

Neither was reachable from CI, because KWOK nodes run no system pods at all —
0m of system CPU locally against 276m minimum on GKE, where the daemons take
between 29% and 82% of a node before your workload is scheduled. There is now
a GKE-shaped fixture that reproduces that fleet to within 2m per node.

Savings in money

Tell the chart what your machines cost and the ledger reports it:

uiBackend:
  pricing:
    currency: USD
    perHour:
      e2-medium: 0.0335
      e2-medium/spot: 0.0100

No built-in price table, and there will not be one — list prices vary by
region and are wrong for anyone with a committed-use discount, so a default
would be a guess wearing the clothes of a measurement. Unpriced machine types
are reported as unpriced, never as free. The figure is a rate, because
reclaiming a node saves money every hour from now on.

Nodes reclaimed by something else — an autoscaler, or someone with kubectl —
are now counted too, and reported separately. The cluster saved that money
whoever caused it.

Four capabilities that existed and were never shown

rightsizing, whatif, preflight and the whole maintenance-window
subsystem were built, tested, shipped, and never called by the UI.

Rightsizing is the one worth opening first. On a real cluster it read 3.0
cores requested against 0.2 observed — over-requesting is why the nodes were
too full to consolidate.

Maintenance windows were the sharpest: the package writes a reason for every
closed window and nobody could read any of them, so a typo in a cron
expression meant Red steps silently never became runnable.

An empty plan explains itself

The state a healthy cluster spends most of its life in used to render as a
headline and nothing else. It now says which nodes cannot be freed and what is
holding each one — and, where the blocker is capacity, how much would have to
come free and which node is closest.

Stop a run, with one control rather than two

The design called for an Abort and a "Pause after this step". A pod that has
been evicted cannot be un-evicted, so there is no aborting mid-step — only
declining to start the next one. Two buttons would have promised an undo that
does not exist.

dencer stop, or the button on a run in flight. Runs that end this way get
their own Stopped status, distinct in the audit ledger from a run that
finished and one that failed.

Also

  • Per-node history, so a node stably idle for a fortnight reads differently
    from one that peaks nightly
  • Recovery time recorded per workload, so a step can say what it is likely to
    cost before it is approved
  • Node pools read from the provider's own label, rather than "pool" meaning
    the machine type
  • The planner's staleness is visible: the top bar says when it has stopped
    confirming, and a stored plan no longer describes a fleet size that has
    changed underneath it
  • A PriorityClass for the SQLite-co-located pair, so the planner stops
    losing scheduling races it cannot afford to lose

Upgrading

helm upgrade k8s-dencer oci://ghcr.io/atedgimo/charts/k8s-dencer \
  --namespace k8s-dencer --reuse-values

No breaking changes. Five additive schema migrations apply on first start.

Full changelog: v0.4.0...v0.5.0

v0.4.0

Choose a tag to compare

@github-actions github-actions released this 06 Aug 04:37
3e4c026

This release is the first to carry a change from outside the project.

The CLI now authenticates itself on cloud clusters

dencer used to fail on GKE, EKS and AKS kubeconfigs with a credential-plugin
error, because it never ran the plugin that kubectl runs. It does now — the
token is resolved through client-go's own transport, and a line on stderr names
the plugin being executed so the credential path is never silent. Certificate
kubeconfigs still ask for an explicit token, since the API server's TokenReview
only accepts bearer tokens.

Contributed by @jainpratik163, who found it, fixed it, and then revised the
patch twice under review. Thank you.

Install without the web UI

helm install k8s-dencer oci://ghcr.io/atedgimo/charts/k8s-dencer \
  --namespace k8s-dencer --create-namespace \
  --set auth.enabled=true \
  --set uiFrontend.enabled=false

The planner and ui-backend still install — the CLI talks to the API the UI
talks to — but nothing serves a browser. For operators who only ever wanted the
command line. See docs/cli.md.

Also in this release

  • The UI serves security headers: CSP, X-Content-Type-Options,
    X-Frame-Options: DENY, Referrer-Policy, and frame-ancestors 'none'.
  • Keyboard and screen-reader fixes in the recommendations queue.
  • The one CRD this chart ships (maintenancewindows.dencer.io) is now
    documented, including the part Helm will not do for you: CRDs are installed
    on first install and never upgraded. The dencer.io names in the RBAC are
    SubjectAccessReview permissions, not CRDs — kubectl get plans.dencer.io
    was never going to work, and the docs now say so.

Upgrading

helm upgrade k8s-dencer oci://ghcr.io/atedgimo/charts/k8s-dencer \
  --namespace k8s-dencer --reuse-values

No breaking changes. uiFrontend.enabled defaults to true, so an existing
install keeps its UI without being told to.

Binaries

dencer is attached below for linux and darwin on amd64 and arm64, with
checksums. If you are running the v0.3.0 binary against a cloud cluster,
this is the upgrade that fixes it.

Full changelog: v0.3.0...v0.4.0

v0.3.0

Choose a tag to compare

@github-actions github-actions released this 01 Aug 15:28
c576611

What's Changed

  • A cloud test on GKE, so a reclaimer we didn't write removes the node by @atedgimo in #34
  • A header, a scale, and a way into a node by @atedgimo in #35
  • Make the cloud test survive a real new GCP project by @atedgimo in #37
  • Add Dependabot for the four ecosystems this repo actually has by @atedgimo in #36
  • Find the GKE auth plugin that Homebrew installs but doesn't link by @atedgimo in #39
  • Stop a cloud run hijacking the terminal it didn't start in, and default to dark by @atedgimo in #38
  • The cloud claim is proven, and the findings are collected by @atedgimo in #41
  • M24: show that a node is cordoned, and open the milestone for live state by @atedgimo in #40
  • Bump nginxinc/nginx-unprivileged from 1.27-alpine to 1.31-alpine in /build in the base-images group by @dependabot[bot] in #42
  • Bump the go-minor-and-patch group with 2 updates by @dependabot[bot] in #43
  • Bump the actions group with 8 updates by @dependabot[bot] in #47
  • Stop Dependabot proposing majors it cannot land by @atedgimo in #50
  • Bump github.com/prometheus/client_golang from 1.23.2 to 1.24.1 in the go-minor-and-patch group by @dependabot[bot] in #51
  • Document what shipped today but never reached the docs by @atedgimo in #52
  • Three renderings of the field, chosen by cluster size by @atedgimo in #53
  • README: three field renderings, and what fullness means by @atedgimo in #54
  • Re-read the plan's confirmation instead of freezing it at page load by @atedgimo in #55
  • M24: an observed overlay on the field, so facts hold still by @atedgimo in #56
  • A product roadmap, and order in the docs by @atedgimo in #57
  • The planning cycle moves to a tested package; window reads obey the run by @atedgimo in #58
  • The consent prompt becomes testable, and two comments stop lying by @atedgimo in #59
  • State what the node count is worth: reclaimable capacity in the verdict by @atedgimo in #60
  • The roadmap widens: five more questions for the same engine by @atedgimo in #61
  • App sheds its plumbing into three hooks before M25 adds more by @atedgimo in #62
  • Community files: CONTRIBUTING and CODE_OF_CONDUCT by @atedgimo in #63
  • M25: the closed loop — stop executing forecasts by @atedgimo in #64
  • Upgrade preflight: the analyzer's answer, printed before the 3am version by @atedgimo in #65
  • The savings ledger: capacity actually returned, as a measurement by @atedgimo in #66
  • Frontend majors, all three: React 19, Vite 8, TypeScript 7 by @atedgimo in #67
  • The lookahead question, closed by measurement: there is nothing to recover by @atedgimo in #68
  • GCP second run: what it proves that local clusters cannot by @atedgimo in #69
  • e2e: show the image-build error instead of discarding it by @atedgimo in #70
  • M24 and M25, finished: the envelope reaches the UI, evicted pods stop lying by @atedgimo in #71
  • Resilience audit and guarded drain: the same engine, two more moods by @atedgimo in #72
  • The mark: a lowercase d with a heptagon bowl by @atedgimo in #73
  • Cost awareness, first slice: what the machines are, said everywhere by @atedgimo in #75
  • Reclaimer evidence, three-valued: proof, promise, or honestly unknown by @atedgimo in #74
  • What-if: the loss question, answered by the engine instead of a spreadsheet by @atedgimo in #76
  • The stylesheet splits at its own banners, provably without change by @atedgimo in #78
  • Right-sizing: requests versus measured usage, and the seam it exposed by @atedgimo in #77
  • A run before its first event serves events: [], not null by @atedgimo in #80
  • Strays out, and the GCP bill stated in numbers by @atedgimo in #79
  • The showcase: every constraint at once, on a fleet worth looking at by @atedgimo in #81
  • Reports analyze fresh; the README learns the new verbs by @atedgimo in #82
  • Gateway API HTTPRoute, beside the Ingress by @atedgimo in #83
  • Honour the ecosystem's hands-off annotations by @atedgimo in #84
  • The timeline exists: samples, the history API, and the fabric's autoscaler by @atedgimo in #85
  • History: the cluster becomes a line by @atedgimo in #86
  • Recommendations: the analyzer finally says what to do by @atedgimo in #87
  • The demo records itself, and advice reaches the sidebar by @atedgimo in #88
  • The product grows a spine: a nav rail, and pods get their own card by @atedgimo in #89
  • Revert the UI shell (#89) — design comes first by @atedgimo in #90
  • UI redesign PR 1/7 — foundation: design tokens, Plex-only type, app frame by @atedgimo in #91
  • UI redesign PR 2/7 — plan review: the step list is the screen by @atedgimo in #92
  • UI redesign PR 3/7 — run screens: rehearsal, execution, halted by the guard by @atedgimo in #95
  • UI redesign PR 4/7 — Recommendations: the queue ranked by nodes unlocked by @atedgimo in #94
  • UI redesign PR 5/7 — Cluster lenses, History ledger, and a real packing ceiling by @atedgimo in #96
  • UI redesign PR 6/7 — sign-in: the lockup, the thesis, and the ambient loop by @atedgimo in #97
  • UI redesign PR 7/7 — closeout: dead CSS, re-recorded walkthrough, docs by @atedgimo in #98
  • A timed GCP playground: random scenario, 20 minutes, self-destructs by @atedgimo in #99
  • Release 0.3.0 by @atedgimo in #100

New Contributors

Full Changelog: v0.2.0...v0.3.0

v0.2.0

Choose a tag to compare

@github-actions github-actions released this 31 Jul 07:20
5e6a3d3

What's Changed

  • M21: install it, drain a real node, prove the workload came back by @atedgimo in #28
  • CLI: dencer, for operators who don't want the UI by @atedgimo in #29
  • Security policy, and put the CLI where people look for it by @atedgimo in #30
  • Check whether draining actually removed anything by @atedgimo in #31
  • M21b: prove the ingress and storage claims, not just render them by @atedgimo in #32
  • Release 0.2.0 by @atedgimo in #33

Full Changelog: v0.1.0...v0.2.0