| name | sos-emergency |
| description | Ship Operating System: Emergency Kubernetes cluster recovery, Talos reset procedures, Synology Container Manager recovery, and graceful shutdown protocols. Trigger with /sos |
| allowed-tools | ["read_file","run_in_terminal","grep_search","semantic_search","get_terminal_output","fetch_webpage","create_file"] |
Ship Operating System (SOS) - Emergency Recovery
"When everything fails, this skill has your back."
I provide emergency recovery procedures for Sunkworks home lab infrastructure. This skill embraces the reality that systems fail—often spectacularly, often live on stream—and focuses on getting you back to operational status.
Enterprise Warning: These are emergency procedures. Some operations are destructive. Always verify you're targeting the correct cluster/node before executing recovery commands.
Slash Command
/sos
Runs emergency diagnostic workflow:
- Identify cluster connectivity status
- Check node health and etcd quorum
- Assess recovery options based on failure mode
- Recommend appropriate recovery procedure
Usage: Type /sos when systems are unresponsive or in critical failure state.
Script Verification: Before executing, verify the script integrity:
sha256sum .github/skills/sos-emergency/scripts/diagnose.sh
Execute diagnostics:
bash .github/skills/sos-emergency/scripts/diagnose.sh
When I Activate
/sos (slash command)
- "Everything is broken"
- "Cluster unreachable"
- "etcd quorum lost"
- "Talos node hung"
- "Synology Container Manager crashed"
- "Power failure protocol"
- "Emergency shutdown"
- "Abandon ship"
Expected Failure Modes
Kubernetes Cluster Failures
| Failure Mode | Symptoms | Est. Recovery Time |
|---|
| Single control plane down | API server unreachable, etcd errors | 15-30 min |
| etcd quorum loss | All control planes down, cluster frozen | 1-2 hours |
| Node kubelet crash | Pods stuck Terminating, node NotReady | 10-20 min |
| CNI failure | Pods running but no network connectivity | 30-60 min |
Talos-Specific Failures
| Failure Mode | Symptoms | Est. Recovery Time |
|---|
| Extension deadlock | Node boots but services hang (Tailscale subnet router) | 30-45 min |
| Config drift | talosctl commands rejected, authentication failures | 15-30 min |
| Disk pressure | Node evicting pods, kubelet OOM | 20-40 min |
Synology Infrastructure Failures
| Failure Mode | Symptoms | Est. Recovery Time |
|---|
| Container Manager crash | Docker daemon unresponsive, WebUI timeout | 10-20 min |
| Volume mount failures | Containers crash loop, permission errors | 15-30 min |
| DSM update breakage | Services fail post-update | 30-60 min |
Core Recovery Procedures
1. Kubernetes Cluster Recovery
Check Cluster Connectivity
kubectl cluster-info --request-timeout=5s
kubectl config current-context
kubectl config get-contexts
etcd Health Check
talosctl -n <control-plane-ip> etcd status
talosctl -n <control-plane-ip> etcd members
talosctl -n <control-plane-ip> etcd alarm list
etcd Quorum Recovery (DESTRUCTIVE - Single Node)
Use only when quorum is lost and cannot be recovered normally.
talosctl -n <node1-ip> etcd status
talosctl -n <node2-ip> etcd status
talosctl -n <node3-ip> etcd status
talosctl -n <surviving-node> etcd remove-member <failed-member-id>
talosctl -n <surviving-node> etcd forfeit-leadership
etcd Snapshot Restore
talosctl -n <healthy-node> etcd snapshot /tmp/etcd-backup.db
talosctl -n <node-ip> bootstrap --recover-from=/path/to/etcd-backup.db
2. Talos Reset Procedures
The Tailscale Subnet Router Deadlock
From Moon and Back Episode: Node hangs during boot when Tailscale extension can't reach coordination server.
Symptoms:
- Node boots but never becomes Ready
talosctl dmesg shows Tailscale initialization timeout
- Network extension blocks kubelet startup
Recovery:
talosctl -n <node-ip> reset --graceful=false --reboot
talosctl -n <node-ip> edit machineconfig
talosctl -n <node-ip> apply-config --insecure
Complete Node Reset
DESTRUCTIVE: Wipes node and reinstalls from config.
talosctl -n <node-ip> reset --graceful
talosctl -n <node-ip> reset --graceful=false --reboot
talosctl -n <node-ip> reset --system-labels-to-wipe STATE --system-labels-to-wipe EPHEMERAL
Recover Unresponsive Node
talosctl -n <node-ip> --endpoints <node-ip> version --insecure
talosctl -n <node-ip> apply-config -f machineconfig.yaml --insecure
3. Synology Emergency Access
Container Manager Crash Recovery
When DSM Container Manager (Docker) becomes unresponsive:
ssh admin@<synology-ip>
sudo synosystemctl status pkgctl-Docker
sudo synosystemctl restart pkgctl-Docker
sudo synosystemctl stop pkgctl-Docker
sudo cat /var/log/synopkg.log | grep -i docker
sudo killall -9 dockerd
sudo synosystemctl start pkgctl-Docker
Emergency SSH Access Setup
Prepare before you need it:
ssh-copy-id -i ~/.ssh/id_ed25519 admin@<synology-ip>
ssh admin@<synology-ip> "sudo whoami"
Volume Mount Recovery
ssh admin@<synology-ip>
mount | grep volume
sudo cat /proc/mdstat
sudo dmesg | tail -50
sudo mount /volume1
4. Abandon Ship Protocol
Graceful Shutdown Sequence
For planned power outages or emergency situations:
#!/bin/bash
echo "=== ABANDON SHIP PROTOCOL INITIATED ==="
echo "Time: $(date)"
echo "Phase 1: Suspending Flux reconciliation..."
kubectl annotate fluxinstance flux -n flux-system \
kustomize.toolkit.fluxcd.io/suspend=true
echo "Phase 2: Scaling down deployments..."
kubectl get deployments -A -o name | \
xargs -I{} kubectl scale {} --replicas=0
echo "Phase 3: Draining worker nodes..."
for node in $(kubectl get nodes -l node-role.kubernetes.io/control-plane!= -o name); do
kubectl drain $node --ignore-daemonsets --delete-emptydir-data --force
done
echo "Phase 4: Draining control planes..."
for node in $(kubectl get nodes -l node-role.kubernetes.io/control-plane -o name); do
kubectl drain $node --ignore-daemonsets --delete-emptydir-data --force
done
echo "Phase 5: Shutting down Talos nodes..."
for node_ip in <worker-ips>; do
talosctl -n $node_ip shutdown
done
sleep 30
for node_ip in <control-plane-ips>; do
talosctl -n $node_ip shutdown
done
echo "Phase 6: Shutting down Synology NAS..."
ssh admin@<synology-ip> "sudo shutdown -h now"
echo "=== SHUTDOWN COMPLETE ==="
echo "Safe to remove power in 60 seconds"
UPS Integration Check
upsc <ups-name>@localhost
upsc <ups-name>@localhost battery.charge
upsc <ups-name>@localhost ups.status
Emergency Power Script
#!/bin/bash
BATTERY_LEVEL=$(upsc <ups-name>@localhost battery.charge 2>/dev/null)
if [ "$BATTERY_LEVEL" -lt 20 ]; then
echo "CRITICAL: Battery at ${BATTERY_LEVEL}%"
echo "Initiating emergency shutdown..."
bash /path/to/abandon-ship.sh
fi
Recovery Playbooks
Playbook 1: "I Can't Reach My Cluster" (15-30 min)
- Check network connectivity:
ping <control-plane-ip>
- Check VPN/Tailscale:
tailscale status
- Check kubeconfig:
kubectl config current-context
- Test direct connection:
kubectl --server=https://<ip>:6443 cluster-info
- SSH to node and check kubelet:
talosctl -n <ip> service kubelet
Playbook 2: "Node Won't Come Back Up" (30-60 min)
- Check node status:
talosctl -n <ip> version --insecure
- Review boot logs:
talosctl -n <ip> dmesg | tail -100
- Check etcd membership:
talosctl -n <other-node> etcd members
- If extension hang: Apply config without problematic extension
- If total failure: Reset and reinstall from known-good config
Playbook 3: "Everything Is Down" (1-2 hours)
- Identify last known good state (Terraform state, git history)
- Check physical infrastructure (power, network switches)
- Boot minimal cluster (single control plane if needed)
- Restore etcd from most recent snapshot
- Gradually bring up additional nodes
- Verify Flux sync before re-enabling reconciliation
MCP Server Integration
After initial recovery, the Flux Operator MCP Server accelerates verification:
Post-Recovery Health Check
Once cluster connectivity is restored, use MCP tools instead of manual kubectl:
MCP Tool: get_flux_instance
→ Comprehensive Flux controller status and CRD health
→ Faster than iterative /flux-status diagnosis
MCP Tool: get_kubernetes_resources
→ Query all pods, check for CrashLoopBackOff across namespaces
→ Identify remaining issues post-recovery
Setup: See flux-operator skill Step 10 for MCP server configuration.
Integration Points
- Flux Operator → Use MCP server for comprehensive post-recovery verification
- Prometheus Observer: Check
/prometheus-status for alert state after cluster recovery
- Post-Mortem Author: After recovery, use
/postmortem to document what happened
Read-Only Diagnostic Commands
Safe commands for assessment without modification:
kubectl get nodes -o wide
kubectl get pods -A | grep -v Running
kubectl get events -A --sort-by=.lastTimestamp | tail -20
talosctl -n <node-ip> version
talosctl -n <node-ip> service
talosctl -n <node-ip> dmesg | tail -50
talosctl -n <node-ip> netstat -tulpn
talosctl -n <node-ip> etcd status
Sunkworks Episode Notes
"The best debugging happens live, with an audience watching you fail."
This skill is designed for live-stream troubleshooting where:
- Mistakes are educational
- Recovery time matters for audience engagement
- Documentation happens in real-time
- Iterative debugging is expected and embraced