Install
$ agentstack add skill-bnaylor-agent-skills-microk8s-janitor ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
MicroK8s Janitor
This skill manages the lifecycle of a MicroK8s cluster, specifically focusing on safe, rolling upgrades of nodes to ensure high availability is maintained throughout the process.
Prerequisites
- SSH access to at least one node in the cluster (the "seed" node).
- Passwordless
sudoor SSH key-based authentication for the user. - The
microk8ssnap must be installed on the target nodes.
Core Workflows
1. Cluster Discovery & Environment Setup
Starting from a single seed node provided by the user, the janitor discovers the full cluster state.
- Seed Connection: Connect to the seed node and run
microk8s kubectl get nodes -o json. - Node Mapping: Parse the output to identify all nodes, their roles, and current statuses.
- Connectivity Check: Verify SSH and
sudoaccess to every node in the cluster. - Channel Discovery: Run
snap info microk8son the seed node to list available tracking channels (e.g.,1.28/stable,latest/edge).
2. Pre-flight Checks (The "Dry Run")
Before any disruptive action, the janitor ensures the cluster is healthy:
- All nodes must be in the
Readystatus. - Check for any "critical" pods (e.g.,
Longhorn,Calico,CoreDNS) that are currently in a non-running state. - Verify that
dqlite(the HA backend) has a healthy quorum.
3. Interactive Planning
Present the plan to the user:
- Current version vs. Target channel.
- The order of nodes to be upgraded.
- Ask for confirmation before proceeding.
4. Rolling Upgrade Loop (Sequential Execution)
For each node in the sequence:
- Cordon:
microk8s kubectl cordon - Drain:
microk8s kubectl drain --ignore-daemonsets --delete-emptydir-data --force - Upgrade:
sudo snap refresh microk8s --channel= - Wait for Ready: Poll
microk8s status --wait-ready(max 5 minutes). - Health Check: Verify local pods are starting and node status is
Ready. - Uncordon:
microk8s kubectl uncordon
5. Resume & Recovery
If a step fails:
- Abort: Stop immediately. Do not move to the next node.
- Log: Capture and display the error from the node.
- State Check: On re-invocation, the janitor detects if any nodes are still cordoned and offers to "Resume" the upgrade from the failed node.
Helm & StatefulSet Management
The "Immutable Wall"
When upgrading stateful applications (PostgreSQL, MongoDB, Redis) via Helm, changing certain fields (like storageClass or volumeClaimTemplates) will cause a Forbidden error because StatefulSet templates are immutable.
The Stateful Upgrade Workflow
To resolve immutable field errors:
- Identify: Confirm the error is due to immutable fields in a \
StatefulSet\. - Preservation Decision:
- If data MUST be kept: Ensure the PVC has a
RetainorDeletepolicy that allows it to persist (or orphan) after the StatefulSet is deleted. - If a clean slate is intended: Prepare to delete the PVC as well.
- Destructive Action: Delete the specific StatefulSet directly:
\\\bash kubectl delete statefulset -n \\\
- Re-apply: Re-run the
helm upgradeorhelm installcommand. Helm will now successfully recreate the StatefulSet with the new spec.
Best Practices
- Quorum First: Never upgrade more than one node at a time in a 3-node HA cluster to avoid losing quorum.
- Drain Timeout: If a drain hangs, report the specific pod causing the delay to the user.
- Snap Rollback: If
snap refreshfails, attemptssnap revert microk8sif appropriate.
Cluster Access (bnaylor's cluster)
- Local kubectl:
kubectlworks directly from the Mac via~/.kube/config— no SSH needed for cluster operations. - API server:
https://10.3.2.4:16443(microk8s-cluster) - Docker Hub user:
bnaylor— already authenticated locally.
Deploying Services to This Cluster
General workflow for Python services (e.g. running-proxy)
Always cross-build for linux/amd64 — even pure Python services use pip packages with native binaries (uvicorn, pydantic-core, cryptography, greenlet, etc.) that are architecture-specific. Building natively on an ARM64 Mac produces an image that crashes with exec format error on the x86_64 cluster nodes.
docker buildx build --platform linux/amd64 -t bnaylor/:latest --push .
kubectl rollout restart deployment/ -n
kubectl rollout status deployment/ -n
--pushin the buildx command pushes directly, skipping a separatedocker pushstep.- If
docker pushgets a 504 on a plain push, retry once — layers are already cached.
running-proxy service
- Namespace:
running-proxy - Image:
bnaylor/running-proxy:latest - External IP:
10.3.2.132(LoadBalancer, port 80 → container 8000) - Deployment YAMLs:
~/k8s/running-proxy/yamls/ - Secrets:
running-proxy-secrets(spreadsheet-id),google-service-account-json(service-account.json) - Storage: NFS PVC
running-proxy-datamounted at/app/data(SQLite lives there); strategy isRecreateto avoid concurrent writers
LiteLLM (noc cluster)
- Namespace:
litellm - Image:
ghcr.io/berriai/litellm:main - External IP:
10.3.2.135(LoadBalancer, port 8000) - Config:
litellm-configConfigMap inlitellmnamespace.
Software Version Discovery (LiteLLM)
Determining the version of LiteLLM in the cluster is non-trivial because the CLI and package attributes are inconsistent.
Effective Methods:
- Check pyproject.toml (Most Reliable for source version):
``bash kubectl exec -n litellm -- cat /app/pyproject.toml | grep version ``
- Check pip list (Reliable for installed package):
``bash kubectl exec -n litellm -- pip list | grep litellm ``
- Check Git Commit (For development builds):
``bash kubectl exec -n litellm -- cat /app/.git/refs/heads/main ``
- Image Digest (Most definitive for release date):
``bash kubectl get pod -n litellm -o jsonpath="{.status.containerStatuses[0].imageID}" ``
Known Failures (Don't use these):
- ❌
litellm --version(Throws an error or shows help) - ❌
python3 -c "import litellm; print(litellm.__version__)"(AttributeError: module 'litellm' has no attribute '__version__') - ❌
/versionHTTP endpoint (Returns 404 in many configurations)
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: bnaylor
- Source: bnaylor/agent_skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.