Quick Reference Guide¶
Fast lookup for common operations.
Cluster Access¶
# List contexts
kubectl config get-contexts
# Switch context
kubectl config use-context k3s-prod # Production cluster
kubectl config use-context k3d-local # Local dev cluster
# Get current context
kubectl config current-context
# Test access
kubectl get nodes
Node Management¶
# List nodes
kubectl get nodes -o wide
# Get node status
kubectl top nodes
kubectl describe node <node-name>
# Drain node (graceful shutdown)
kubectl drain <node-name> --ignore-daemonsets
# Uncordon node (make available for scheduling)
kubectl uncordon <node-name>
# Taint node (prevent scheduling)
kubectl taint node <node-name> key=value:NoSchedule
# Label node
kubectl label nodes <node-name> workload-type=storage
Pod Management¶
# List pods
kubectl get pods -A # All namespaces
kubectl get pods -n apps # Specific namespace
kubectl get pods -l app=moodle # By label
# Pod details
kubectl describe pod <pod-name> -n <namespace>
# Logs
kubectl logs <pod-name> -n <namespace>
kubectl logs -f deployment/<name> -n <ns> # Follow
kubectl logs --previous <pod-name> -n <ns> # Previous crash
# If you get "timed out" or "502 Bad Gateway": see docs/KUBECTL-LOGS-502.md (fix kubelet cert with --node-ip on each node)
# Execute command in pod
kubectl exec -it <pod-name> -n <ns> -- /bin/sh
kubectl exec <pod-name> -n <ns> -- command
# Port forward
kubectl port-forward pod/<name> 8080:8080 -n <ns>
kubectl port-forward svc/<name> 8080:8080 -n <ns>
# Copy files
kubectl cp <pod>:/path/to/file ./local/path -n <ns>
kubectl cp ./local/file <pod>:/path/to/file -n <ns>
Deployment Management¶
# List deployments
kubectl get deployments -n apps
# Deploy YAML
kubectl apply -f deployment.yaml
kustomize build apps/base/moodle | kubectl apply -f -
# Scale deployment
kubectl scale deployment/<name> --replicas=3 -n <ns>
# Rolling restart
kubectl rollout restart deployment/<name> -n <ns>
# Check rollout status
kubectl rollout status deployment/<name> -n <ns>
# Rollback to previous version
kubectl rollout undo deployment/<name> -n <ns>
# View rollout history
kubectl rollout history deployment/<name> -n <ns>
# Update image
kubectl set image deployment/<name> <container>=image:newtag -n <ns>
# Prune old ReplicaSets (after revisionHistoryLimit is set in manifests)
# List ReplicaSets with 0 desired replicas
kubectl get rs -A | grep '\s0\s'
# Optional: patch deployment to force controller to prune (or rely on next Flux reconcile)
kubectl patch deployment <name> -n <ns> -p '{"spec":{"revisionHistoryLimit":3}}'
Cluster cleanup (ReplicaSets / memory)¶
- ReplicaSets: All base deployments use
revisionHistoryLimit: 3, so only the last 3 revisions are kept (e.g. Stirling-PDF, Bento). After Flux reconciles, old ReplicaSets are pruned automatically. - Homarr RAM: Homarr (Next.js) uses ~1GB by default (Node.js heap). The deployment sets a 512Mi memory limit; if the pod is OOMKilled, raise the limit or set
NODE_OPTIONS=--max-old-space-size=384to cap the V8 heap.
Storage Management¶
# List PersistentVolumes
kubectl get pv
kubectl describe pv <pv-name>
# List PersistentVolumeClaims
kubectl get pvc -A
kubectl get pvc -n apps
# PVC details
kubectl describe pvc <pvc-name> -n <ns>
# Storage classes
kubectl get storageclass
kubectl describe storageclass longhorn
# Check disk usage
kubectl exec -it <pod> -- df -h /mnt/data
Service Management¶
# List services
kubectl get svc -n <ns>
# Service details
kubectl describe svc <service-name> -n <ns>
# Get service endpoints
kubectl get endpoints -n <ns>
# Port forward to service
kubectl port-forward svc/<name> 8080:8080 -n <ns>
Ingress Management¶
# List ingresses
kubectl get ingress -A
# Ingress details
kubectl describe ingress <ingress-name> -n <ns>
# Check ingress status
kubectl get ingress -o wide -n <ns>
Namespace Management¶
# List namespaces
kubectl get namespaces
# Create namespace
kubectl create namespace myapp
# Delete namespace (WARNING: deletes all resources in it!)
kubectl delete namespace myapp
# Set default namespace
kubectl config set-context --current --namespace=apps
Secret Management¶
# List secrets
kubectl get secrets -n <ns>
# Create secret
kubectl create secret generic <name> \
--from-literal=key=value \
-n <ns>
# View secret (base64 encoded)
kubectl get secret <name> -o yaml -n <ns>
# Decode secret
kubectl get secret <name> -o jsonpath='{.data.password}' -n <ns> | base64 -d
# Delete secret
kubectl delete secret <name> -n <ns>
ConfigMap Management¶
# List ConfigMaps
kubectl get configmap -n <ns>
# View ConfigMap
kubectl describe configmap <name> -n <ns>
# Create ConfigMap
kubectl create configmap <name> --from-file=file.yaml -n <ns>
# Edit ConfigMap
kubectl edit configmap <name> -n <ns>
Flux Management¶
# Check Flux status
flux get all --all-namespaces
# Check specific resource
flux get kustomizations --all-namespaces
flux get sources git --all-namespaces
# Force reconciliation
flux reconcile kustomization <name> --with-source
flux reconcile source git <name>
# View logs
flux logs --follow
flux logs --follow deployment/<name> -n <ns>
# Get installed version
flux --version
# Uninstall Flux
flux uninstall --namespace flux-system
Helm Management (if using)¶
# Add Helm repo
helm repo add <repo-name> <repo-url>
helm repo update
# List charts
helm search repo <repo-name>
# Install chart
helm install <release> <repo>/<chart> -n <ns>
# Upgrade chart
helm upgrade <release> <repo>/<chart> -n <ns>
# List releases
helm list -n <ns>
# Get values
helm get values <release> -n <ns>
# Uninstall
helm uninstall <release> -n <ns>
Skooner Dashboard¶
# Get login token
kubectl create token skooner-sa -n monitoring --duration=24h
kubectl create token default -n monitoring --duration=24h
# Check Skooner status
kubectl get pods -n monitoring -l app=skooner
kubectl get svc -n monitoring -l app=skooner
kubectl get ingress -n monitoring -l app=skooner
# View Skooner logs
kubectl logs -f deployment/skooner -n monitoring
# Check Flux HelmRelease
flux get helmrelease skooner -n monitoring
flux get source helm skooner -n flux-system
# Force reconciliation
flux reconcile helmrelease skooner -n monitoring
flux reconcile source helm skooner -n flux-system
# Restart Skooner
kubectl rollout restart deployment/skooner -n monitoring
# Port-forward for local access
kubectl port-forward svc/skooner 8080:80 -n monitoring
# Check resource usage
kubectl top pods -n monitoring -l app=skooner
Kustomize¶
# Build manifest
kustomize build <path> > output.yaml
# Apply built manifest
kustomize build <path> | kubectl apply -f -
# Validate
kustomize build <path> | kubectl --dry-run=client -f - apply
# View differences
kustomize build <path> | kubectl diff -f -
Monitoring & Debugging¶
# Get cluster events
kubectl get events -A --sort-by='.lastTimestamp'
# Check resource usage
kubectl top nodes
kubectl top pods -n <ns>
# Get resource requests/limits
kubectl describe node <node> | grep -A 5 "Allocated resources"
# Check node conditions
kubectl describe node <node> | grep Condition -A 5
# View API server logs
kubectl logs -n kube-system -l component=kube-apiserver
# Resource quotas
kubectl describe resourcequota -n <ns>
# Network policies
kubectl get networkpolicies -n <ns>
Common Troubleshooting¶
# Pod won't start
kubectl describe pod <pod> -n <ns>
kubectl logs <pod> -n <ns>
kubectl logs --previous <pod> -n <ns>
# Check PVC binding
kubectl describe pvc <pvc> -n <ns>
kubectl get pv | grep <pvc-name>
# Check node resources
kubectl top nodes
kubectl top pod <pod> -n <ns>
kubectl describe nodes
# Check DNS
kubectl run -it --rm debug --image=busybox --restart=Never -- sh
nslookup kubernetes.default
nslookup myservice.apps.svc.cluster.local
# Connectivity test
kubectl run -it --rm netshoot --image=nicolaka/netshoot --restart=Never -- bash
curl http://myservice.apps.svc.cluster.local:8080
# Restart all pods in deployment
kubectl rollout restart deployment/<name> -n <ns>
# Force delete pod
kubectl delete pod <pod> -n <ns> --grace-period=0 --force
File Editing¶
# Edit deployment in-place
kubectl edit deployment <name> -n <ns>
# Edit service
kubectl edit svc <name> -n <ns>
# Edit ConfigMap
kubectl edit configmap <name> -n <ns>
# Patch resource
kubectl patch deployment <name> -p '{"spec":{"replicas":3}}' -n <ns>
Export & Backup¶
# Export all resources
kubectl get all -A -o yaml > cluster-backup.yaml
# Export namespace
kubectl get all -n apps -o yaml > namespace-apps-backup.yaml
# Export specific resource
kubectl get deployment/<name> -n <ns> -o yaml > deployment-backup.yaml
# Export to JSON
kubectl get all -n <ns> -o json > backup.json
YAML Validation¶
# Validate YAML syntax
kubectl apply -f file.yaml --dry-run=client
# Validate without applying
kubectl apply -k . --dry-run=client
# Show what would change
kubectl apply -k . --dry-run=client -o yaml
# Diff before apply
kustomize build . | kubectl diff -f -
Performance¶
# Monitor cluster activity
kubectl get events -A --watch
# Show API server latency
kubectl top nodes --use-protocol-buffers
# Check etcd size (on master node)
sudo journalctl -u k3s | grep "etcd size"
# Get resource metrics
kubectl get --raw /apis/metrics.k8s.io/v1beta1/nodes
SSH to Nodes¶
# SSH to K3s master node
ssh root@192.168.1.100 # leia
# SSH to K3s worker node
ssh root@192.168.1.101 # luke-1
# SSH to Proxmox host
ssh root@192.168.1.10 # r2d2
# Check K3s status on node
sudo systemctl status k3s
sudo systemctl status k3s-agent
# View K3s logs on node
sudo journalctl -u k3s -f
sudo journalctl -u k3s-agent -f
# K3s commands on node
sudo k3s kubectl get nodes
sudo k3s crictl ps # View containers
Git Workflow¶
# Clone repo
git clone https://github.com/yourusername/homelab-gitops
# Create feature branch
git checkout -b feature/add-myservice
# Make changes
# ... edit YAML files
# Stage changes
git add apps/base/myservice/
# Commit
git commit -m "feat: add myservice"
# Push
git push origin feature/add-myservice
# Create PR on GitHub
# Wait for CI validation
# Review and merge
# Verify deployment (Flux auto-deploys)
kubectl get pods -n apps
Environment Variables¶
# Set context
export KUBECONFIG=~/.kube/config:~/.kube/config-prod
kubectl config use-context k3s-prod
# Set default namespace
export KUBE_NAMESPACE=apps
kubectl get pods -n $KUBE_NAMESPACE
# GitHub credentials (for Flux)
export GITHUB_TOKEN=ghp_xxxxx
export GITHUB_USER=yourusername
Aliases (Add to ~/.bashrc or ~/.zshrc)¶
alias k='kubectl'
alias kgp='kubectl get pods'
alias kgs='kubectl get svc'
alias kgpvc='kubectl get pvc'
alias kgd='kubectl get deployments'
alias kdesc='kubectl describe'
alias kex='kubectl exec -it'
alias klf='kubectl logs -f'
alias kaf='kubectl apply -f'
alias kdel='kubectl delete'
alias kn='kubectl config set-context --current --namespace'
# Kustomize
alias kbuild='kustomize build'
alias kbuildlocal='kustomize build clusters/local'
alias kbuildprod='kustomize build clusters/production'
# Flux
alias fstat='flux get all --all-namespaces'
alias fsync='flux reconcile kustomization flux-system --with-source'
alias flogs='flux logs --follow'
# Navigation
alias cdgit='cd ~/homelab-gitops'
Useful One-Liners¶
# Get all pods not in Running state
kubectl get pods -A --field-selector=status.phase!=Running
# Find pods with errors
kubectl get pods -A -o jsonpath='{range .items[?(@.status.containerStatuses[*].state.waiting)]}{.metadata.name}{"\n"}{end}'
# Get resource usage for all pods
kubectl top pods -A --sort-by=memory
# Find pending pods
kubectl get pods -A --field-selector=status.phase=Pending
# List all resources in namespace
kubectl api-resources -n apps
# Get YAML for running resource and edit
kubectl get deployment myapp -o yaml | vim - | kubectl apply -f -
# Compare cluster state with YAML
kustomize build . | kubectl diff -f -
# Get service endpoints
kubectl get svc -A -o wide
# Find pods on specific node
kubectl get pods -A --field-selector=spec.nodeName=leia
# Get PVC usage
kubectl exec -it <pod> -- du -sh /data
# Restart all pods in namespace
kubectl delete pods -n apps --all
# Tail all pod logs in namespace
kubectl logs -f -n apps -l app=moodle --all-containers=true --max-log-requests=10
Emergency Commands¶
# Force delete stuck pod
kubectl delete pod <pod> -n <ns> --grace-period=0 --force
# Drain and reboot node
kubectl drain <node> --ignore-daemonsets --delete-emptydir-data
# (reboot node)
kubectl uncordon <node>
# Clear evicted pods
kubectl get pods -n <ns> -o json | jq '.items[] | select(.status.reason=="Evicted")' | jq '.metadata.name' | xargs kubectl delete pod -n <ns>
# Delete namespace stuck in Terminating
kubectl get namespace <ns> -o json | jq '.spec.finalizers = []' | kubectl replace --raw /api/v1/namespaces/<ns>/finalize -f -
# Force delete PVC
kubectl patch pvc <pvc> -p '{"metadata":{"finalizers":null}}' -n <ns>
# Restart Kubelet
ssh root@<node>
sudo systemctl restart k3s-agent
Tip: Bookmark this page or add it to your notes. These commands are frequently needed!
Remember: Always test in k3d first before applying to production.
Last updated: November 2025