skills/k8s-rwo-deployment-recreate-strategy/SKILL.md
Fix for single-replica Kubernetes Deployments with ReadWriteOnce PVCs that deadlock during rolling updates. Use when: (1) a new pod is stuck in Init:0/1 or Pending with 'Multi-Attach error: Volume is already used by pod(s)', (2) the old pod won't terminate because maxUnavailable rounds to 0 for a single-replica Deployment, (3) deleting the old pod causes it to be immediately recreated by its ReplicaSet. Also covers the secondary error 'spec.strategy.rollingUpdate: Forbidden: may not be specified when strategy type is Recreate' when patching a live Deployment.
npx skillsauth add aldengolab/lorist k8s-rwo-deployment-recreate-strategyInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
A Deployment with one replica and a ReadWriteOnce PVC deadlocks during rolling updates. The new pod cannot start because the old pod holds the RWO volume, and the old pod will not terminate until the new pod is Ready.
Init:0/1 or PendingMulti-Attach error for volume "pvc-...": Volume is already used by pod(s) <old-pod>replicas: 1 and a RWO PVCmaxSurge: 25% (rounds to 1), maxUnavailable: 25% (rounds to 0)For kube-prometheus-stack Grafana:
grafana:
deploymentStrategy:
type: Recreate
For a raw Deployment:
spec:
strategy:
type: Recreate
Changing an existing Deployment from RollingUpdate to Recreate via kubectl apply
or ArgoCD sync fails with:
Deployment.apps "<name>" is invalid: spec.strategy.rollingUpdate:
Forbidden: may not be specified when strategy type is 'Recreate'
This happens because the live Deployment still has rollingUpdate sub-fields set.
Fix: delete the Deployment and let the controller recreate it with the new spec.
kubectl delete deployment <name> -n <namespace>
# ArgoCD will immediately recreate it with the correct spec on next sync
argocd app sync <app-name>
kubectl get deployment <name> -n <namespace> \
-o jsonpath='{.spec.strategy.type}'
# Should output: Recreate
spec.strategy in-place on a live Deployment that has rollingUpdate fields — always delete and recreate.k8s-helm-immutable-field-workaround — general pattern for other immutable Helm resource fields (Services, PVCs); includes PreSync hook templatek8s-helm-immutable-field-workaround/references/delete-and-recreate.md — all delete-and-recreate variants (PreSync hook, kubectl replace --force for PVs)development
Build a UEFI Secure Boot PXE netboot server for Ubuntu autoinstall. Use when: designing or implementing network boot infrastructure for automated Ubuntu provisioning with Secure Boot enabled. Covers the complete chain: signed shim+GRUB selection, TFTP layout, kernel parameters, autoinstall config requirements, and post-install bootstrapping scripts. Also applicable when debugging an existing PXE setup that uses the wrong GRUB binary or config paths.
development
Design pattern for running a persistent PXE/TFTP server that safely coexists with already-installed nodes. Use when: building PXE infrastructure that should stay always-on, designing automated bare-metal provisioning in GitOps/Kubernetes environments, or any PXE setup where UEFI boot order has network boot first. Eliminates boot loops without requiring UEFI firmware changes.
development
This skill governs all prose output — Claude's own responses, documentation, PR descriptions, commit messages, README content, comments, and any text the user asks to draft or edit. It should also be used when the user asks to "review my writing", "edit this for clarity", "make this clearer", "simplify this text", "rewrite this", "check my prose", "tighten this up", or "make this more concise". Based on George Orwell's "Politics and the English Language" (1946).
development
Debug Kubernetes pods using hostNetwork: true that crash with "Address already in use" or "failed to create listening socket for port N". Use when: (1) a hostNetwork pod container is in CrashLoopBackOff and logs show a port bind failure, (2) the port works fine in non-hostNetwork pods but fails with hostNetwork, (3) you need to identify which host-level process holds a port from within Kubernetes (no SSH). Covers /proc/net/udp inspection and kubectl debug node with nsenter.