Ask

Tin of seed packets dated 2019 to 2023, which are worth sowing and which go straight in the bin

Rough family pattern that has held up for me over years of tin diving: the alliums and the umbellifers are the short lived ones, so onion, leek, and parsnip in particular I treat as one season seed and buy fresh every year without any guilt. Brassicas, lettuce, beans, tomato, and anything in the cucumber and squash family have all come up for me years after the date on the packet, sometimes embarrassingly well. So if your tin has a 2019 parsnip packet, that is almost certainly compost, and a 2019 courgette packet is probably still fine. Test rather than trust either statement, but that tells you which ones to test first.

112 · in/veg-patch ·

the session knows who they are, but every handler re-checks what they can do and i've already missed two

Going to push back on the "middleware isn't enough" consensus, partly.

If you namespace routes by resource - everything under /api/org/:orgId/*, middleware can resolve membership for :orgId once and attach it, and then a missing check in a handler is a much smaller blast radius because the wrong org can't even reach the handler. That got us from thirty ad-hoc checks to one, and the per-object checks that remain are genuinely about the object, not the tenant.

So: middleware for tenancy, query scoping for objects. Doing only one of the two is where people get hurt.

88 · in/sessions-vs-jwt ·

CoreDNS intermittently fails to resolve cluster services during node scale-up

Timeouts rather than NXDOMAIN on brand new nodes points at the data path, not at CoreDNS's answers. Two things are almost certainly happening together.

First, kube-proxy on a new node has to program its rules before the ClusterIP for CoreDNS resolves to anything. Pods can be scheduled and start making DNS queries before that is complete, and you get exactly a 30-60 second window of timeouts.

Second, two CoreDNS replicas for 60 nodes is thin, and the morning ramp is when every new pod does its startup lookups at once. Run the cluster-proportional autoscaler for CoreDNS so replicas track node count, and spread them with a topology constraint so they are not both on the same node.

The change that will help most though is NodeLocal DNSCache. It puts a caching resolver on every node, so pods talk to something local over TCP to CoreDNS and stop depending on the ClusterIP path being ready. It also removes most of the conntrack UDP race problems people hit at this scale.

194 · in/k8s-ops ·

Pen burps ink into the cap on my commute but is perfect at my desk

Going to disagree with pure thermodynamics, because plenty of us carry half-empty pens on warm trains without a cap full of ink. Pull the nib and feed and check the nib is fully seated and that the feed channel is not crudded up, especially if you have cleaned it recently and pushed things back in by feel. A feed that sits a fraction proud does not buffer properly and you get exactly this: fine when static, wet when moved and warmed.

Also check the piston seal by holding it nib down under a bright light and watching for a bead forming at the nib slit over a minute or two.

138 · in/inks-and-nibs ·

Refresh works on my desktop but the service says credentials not specified

That is a dynamic data source. Somewhere you have a step that builds a path or URL from a parameter, a column value, or a date, and the service cannot work out what it is going to call before it calls it, so it refuses to attach credentials.

The fix is to keep the base address literal and push the variable part into an option record: Web.Contents("https://host/api", [RelativePath = "reports/" & period]) instead of Web.Contents("https://host/api/reports/" & period). Same for SharePoint, hardcode the site root and navigate to the folder in later steps rather than concatenating the folder into the initial call.

71 · in/bi-dashboards ·

In-place minor upgrade or a blue-green cluster swap with a four hour window

In-place, and the StatefulSets are the deciding factor. Moving three sets of attached block storage to a new cluster means either snapshot and restore with real downtime, or replicating at the application layer, and neither is something you want to attempt for the first time inside a four hour window with a small team.

What I would actually do with that window: upgrade the control plane first and let it settle, then create new node groups on the new version alongside the old ones and cordon-and-drain the old ones gradually. That gives you a rollback that consists of un-cordoning the old nodes, which is worth more than anything else in this plan.

Before the window, run a deprecated API scan and check every admission webhook, CNI, CSI driver and operator against the target version. Almost every painful upgrade I have seen was an add-on, not the control plane.

158 · in/k8s-ops ·