Commit f67d52956ecb
Changed files (7)
dots
.config
claude
skills
Kubernetes
dots/.config/claude/skills/Kubernetes/workflows/Context.md
@@ -0,0 +1,555 @@
+# Context Workflow
+
+Managing kubectl contexts, namespaces, and cluster switching.
+
+## When to Use
+
+- Switching between multiple Kubernetes clusters
+- Managing different namespaces
+- Setting default context or namespace
+- Organizing multi-cluster workflows
+
+## Context Management
+
+### View Contexts
+
+```bash
+# List all contexts
+kubectl config get-contexts
+
+# Show current context
+kubectl config current-context
+
+# View full kubeconfig
+kubectl config view
+
+# View kubeconfig without revealing secrets
+kubectl config view --minify
+```
+
+### Switch Contexts
+
+```bash
+# Switch to different context
+kubectl config use-context <context-name>
+
+# Example: Switch to production cluster
+kubectl config use-context prod-cluster
+
+# Example: Switch to development cluster
+kubectl config use-context dev-cluster
+```
+
+### Create Context
+
+```bash
+# Create new context
+kubectl config set-context <context-name> \
+ --cluster=<cluster-name> \
+ --user=<user-name> \
+ --namespace=<namespace>
+
+# Example: Create staging context
+kubectl config set-context staging \
+ --cluster=staging-cluster \
+ --user=staging-admin \
+ --namespace=staging
+```
+
+### Modify Context
+
+```bash
+# Set default namespace for current context
+kubectl config set-context --current --namespace=<namespace>
+
+# Example: Set namespace to production
+kubectl config set-context --current --namespace=production
+
+# Rename context
+kubectl config rename-context <old-name> <new-name>
+```
+
+### Delete Context
+
+```bash
+# Delete context
+kubectl config delete-context <context-name>
+
+# Delete cluster
+kubectl config delete-cluster <cluster-name>
+
+# Delete user
+kubectl config delete-user <user-name>
+```
+
+## Namespace Management
+
+### View Namespaces
+
+```bash
+# List all namespaces
+kubectl get namespaces
+kubectl get ns
+
+# Describe namespace
+kubectl describe namespace <namespace>
+
+# Get namespace with labels
+kubectl get namespace --show-labels
+```
+
+### Create Namespace
+
+```bash
+# Create namespace imperatively
+kubectl create namespace <namespace>
+
+# Create namespace declaratively
+cat <<EOF | kubectl apply -f -
+apiVersion: v1
+kind: Namespace
+metadata:
+ name: myapp
+ labels:
+ environment: production
+ team: backend
+EOF
+```
+
+### Set Default Namespace
+
+```bash
+# Set namespace for current context
+kubectl config set-context --current --namespace=<namespace>
+
+# Verify namespace
+kubectl config view --minify | grep namespace
+
+# Or check current context details
+kubectl config get-contexts $(kubectl config current-context)
+```
+
+### Delete Namespace
+
+```bash
+# Delete namespace (WARNING: deletes all resources in namespace)
+kubectl delete namespace <namespace>
+
+# Delete with confirmation
+kubectl delete namespace <namespace> --wait=true
+```
+
+## Multi-Cluster Workflows
+
+### Context Naming Convention
+
+**Recommended format:** `<environment>-<region>-<cluster>`
+
+Examples:
+- `prod-us-east-1`
+- `staging-eu-west-1`
+- `dev-local`
+
+```bash
+# Rename contexts to follow convention
+kubectl config rename-context arn:aws:eks:us-east-1:123456789:cluster/prod prod-us-east-1
+kubectl config rename-context docker-desktop dev-local
+```
+
+### Quick Context Switching
+
+```bash
+# Create aliases for common contexts
+alias kctx='kubectl config use-context'
+alias kns='kubectl config set-context --current --namespace'
+
+# Usage
+kctx prod-us-east-1
+kns production
+```
+
+### Context Switcher Tools
+
+**kubectx/kubens (recommended):**
+```bash
+# Install kubectx and kubens
+# On NixOS, add to packages: pkgs.kubectx
+
+# Switch context interactively
+kubectx
+
+# Switch to specific context
+kubectx prod-us-east-1
+
+# Switch to previous context
+kubectx -
+
+# Switch namespace interactively
+kubens
+
+# Switch to specific namespace
+kubens production
+
+# Switch to previous namespace
+kubens -
+```
+
+### Verify Current Context
+
+```bash
+# Show current context and namespace
+kubectl config current-context
+kubectl config view --minify | grep namespace
+
+# Or use kubectx/kubens
+kubectx
+kubens
+
+# Show cluster info
+kubectl cluster-info
+
+# Verify you're in the right cluster
+kubectl get nodes
+```
+
+## Kubeconfig Management
+
+### Kubeconfig Location
+
+**Default:** `~/.kube/config`
+
+**Custom location:**
+```bash
+# Use custom kubeconfig
+export KUBECONFIG=/path/to/custom/kubeconfig
+
+# Use multiple kubeconfigs (merged)
+export KUBECONFIG=~/.kube/config:~/.kube/config-cluster2
+
+# Temporary kubeconfig for single command
+kubectl --kubeconfig=/path/to/config get pods
+```
+
+### Merge Kubeconfigs
+
+```bash
+# Backup current config
+cp ~/.kube/config ~/.kube/config.backup
+
+# Merge multiple configs
+KUBECONFIG=~/.kube/config:~/.kube/config-new kubectl config view --flatten > ~/.kube/config-merged
+mv ~/.kube/config-merged ~/.kube/config
+```
+
+### Extract Context to Separate File
+
+```bash
+# Extract specific context
+kubectl config view --minify --flatten --context=prod-cluster > prod-kubeconfig.yaml
+```
+
+### Secure Kubeconfig
+
+```bash
+# Set proper permissions
+chmod 600 ~/.kube/config
+
+# Verify permissions
+ls -la ~/.kube/config
+```
+
+## Cluster Access Patterns
+
+### EKS (AWS)
+
+```bash
+# Configure kubectl for EKS cluster
+aws eks update-kubeconfig --region us-east-1 --name my-cluster
+
+# With specific profile
+aws eks update-kubeconfig --region us-east-1 --name my-cluster --profile prod
+
+# With specific role
+aws eks update-kubeconfig --region us-east-1 --name my-cluster --role-arn arn:aws:iam::123456789:role/EKSAdmin
+```
+
+### GKE (Google Cloud)
+
+```bash
+# Get GKE cluster credentials
+gcloud container clusters get-credentials my-cluster --region us-central1
+
+# With specific project
+gcloud container clusters get-credentials my-cluster --region us-central1 --project my-project
+```
+
+### AKS (Azure)
+
+```bash
+# Get AKS cluster credentials
+az aks get-credentials --resource-group myResourceGroup --name myAKSCluster
+
+# Overwrite existing context
+az aks get-credentials --resource-group myResourceGroup --name myAKSCluster --overwrite-existing
+```
+
+### K3s/Local Clusters
+
+```bash
+# K3s kubeconfig location
+export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
+
+# Kind (Kubernetes in Docker)
+kind export kubeconfig --name my-cluster
+
+# Minikube
+minikube kubectl -- get pods
+# or
+kubectl --context=minikube get pods
+```
+
+## Namespace Best Practices
+
+### Standard Namespaces
+
+- `default`: Avoid using for applications
+- `kube-system`: System components only
+- `kube-public`: Public resources
+- `kube-node-lease`: Node heartbeats
+
+### Recommended Namespace Structure
+
+**By Environment:**
+```
+development
+staging
+production
+```
+
+**By Team:**
+```
+team-frontend
+team-backend
+team-data
+```
+
+**By Application:**
+```
+app-web
+app-api
+app-workers
+```
+
+**Hybrid Approach:**
+```
+prod-frontend
+prod-backend
+staging-frontend
+staging-backend
+dev-shared
+```
+
+### Namespace Isolation
+
+```yaml
+# Resource quota
+apiVersion: v1
+kind: ResourceQuota
+metadata:
+ name: compute-quota
+ namespace: production
+spec:
+ hard:
+ requests.cpu: "10"
+ requests.memory: 20Gi
+ limits.cpu: "20"
+ limits.memory: 40Gi
+ persistentvolumeclaims: "10"
+---
+# Limit range
+apiVersion: v1
+kind: LimitRange
+metadata:
+ name: cpu-memory-limits
+ namespace: production
+spec:
+ limits:
+ - max:
+ cpu: "2"
+ memory: 4Gi
+ min:
+ cpu: 100m
+ memory: 128Mi
+ default:
+ cpu: 500m
+ memory: 512Mi
+ defaultRequest:
+ cpu: 100m
+ memory: 128Mi
+ type: Container
+---
+# Network policy (deny all by default)
+apiVersion: networking.k8s.io/v1
+kind: NetworkPolicy
+metadata:
+ name: default-deny-all
+ namespace: production
+spec:
+ podSelector: {}
+ policyTypes:
+ - Ingress
+ - Egress
+```
+
+## Context Switching Safety
+
+### Pre-flight Checks
+
+```bash
+# Always verify context before running commands
+kubectl config current-context
+
+# Verify you're in the right cluster
+kubectl get nodes
+
+# Check namespace
+kubectl config view --minify | grep namespace
+```
+
+### Prevent Accidental Production Changes
+
+```bash
+# Create read-only context for production
+kubectl config set-context prod-readonly \
+ --cluster=prod-cluster \
+ --user=readonly-user \
+ --namespace=production
+
+# Use separate terminal profiles for different environments
+# Set terminal title based on context
+export PS1='[\u@\h $(kubectl config current-context)] \W\$ '
+```
+
+### Shell Prompt Integration
+
+```bash
+# Add to ~/.bashrc or ~/.zshrc
+
+# Show current k8s context in prompt
+kube_ps1() {
+ local ctx=$(kubectl config current-context 2>/dev/null)
+ local ns=$(kubectl config view --minify --output 'jsonpath={..namespace}' 2>/dev/null)
+ if [ -n "$ctx" ]; then
+ echo "($ctx:${ns:-default})"
+ fi
+}
+
+# Update PS1
+export PS1='$(kube_ps1) \$ '
+
+# Or use kube-ps1 tool
+# On NixOS: pkgs.kube-ps1
+source /path/to/kube-ps1.sh
+PROMPT='$(kube_ps1)'$PROMPT
+```
+
+## Advanced Context Management
+
+### Context Aliases
+
+```bash
+# Create short aliases
+kubectl config set-context dev --cluster=dev-cluster --user=dev-user --namespace=development
+kubectl config set-context prod --cluster=prod-cluster --user=prod-user --namespace=production
+
+# Quick switching
+kubectl config use-context dev
+kubectl config use-context prod
+```
+
+### Per-Shell Context
+
+```bash
+# Override kubeconfig for specific shell session
+export KUBECONFIG=~/.kube/config-dev
+
+# Verify isolation
+kubectl config current-context
+```
+
+### Context Validation Script
+
+```bash
+#!/bin/bash
+# validate-context.sh
+
+CONTEXT=$(kubectl config current-context)
+NAMESPACE=$(kubectl config view --minify -o jsonpath='{..namespace}')
+
+echo "Current context: $CONTEXT"
+echo "Current namespace: ${NAMESPACE:-default}"
+echo ""
+echo "Cluster nodes:"
+kubectl get nodes --no-headers | wc -l
+echo ""
+read -p "Is this the correct cluster? (yes/no): " confirm
+
+if [ "$confirm" != "yes" ]; then
+ echo "Aborting operation"
+ exit 1
+fi
+```
+
+## Troubleshooting Context Issues
+
+### Context Not Found
+
+```bash
+# List available contexts
+kubectl config get-contexts
+
+# Verify kubeconfig file
+kubectl config view
+
+# Check KUBECONFIG environment variable
+echo $KUBECONFIG
+```
+
+### Authentication Errors
+
+```bash
+# Refresh cloud provider credentials
+# AWS
+aws eks update-kubeconfig --region us-east-1 --name my-cluster
+
+# GCP
+gcloud container clusters get-credentials my-cluster --region us-central1
+
+# Azure
+az aks get-credentials --resource-group myRG --name myCluster
+```
+
+### Permission Errors
+
+```bash
+# Check current user
+kubectl auth whoami
+
+# Check permissions
+kubectl auth can-i get pods
+kubectl auth can-i create deployments
+kubectl auth can-i '*' '*' --all-namespaces
+```
+
+## Best Practices Checklist
+
+- [ ] Use descriptive context names
+- [ ] Set default namespace for each context
+- [ ] Verify context before running commands
+- [ ] Use kubectx/kubens for easier switching
+- [ ] Secure kubeconfig with proper permissions
+- [ ] Create separate contexts for read-only access
+- [ ] Use namespace isolation (quotas, limits, network policies)
+- [ ] Add context to shell prompt
+- [ ] Backup kubeconfig before modifications
+- [ ] Document context naming conventions for team
dots/.config/claude/skills/Kubernetes/workflows/Debug.md
@@ -0,0 +1,368 @@
+# Debug Workflow
+
+Systematic debugging workflow for Kubernetes pods and resources.
+
+## When to Use
+
+- Pod is failing, crashing, or in error state
+- Application not behaving as expected in cluster
+- Need to troubleshoot connectivity or performance issues
+- Investigating resource problems
+
+## Debugging Steps
+
+### 1. Check Pod Status
+
+```bash
+# Get all pods in current namespace
+kubectl get pods
+
+# Get pods in specific namespace
+kubectl get pods -n <namespace>
+
+# Get pods with more details
+kubectl get pods -o wide
+
+# Watch pod status changes
+kubectl get pods -w
+```
+
+**Common Pod States:**
+- `Pending`: Waiting to be scheduled
+- `ContainerCreating`: Container image being pulled/created
+- `Running`: Pod is running
+- `CrashLoopBackOff`: Container keeps crashing
+- `Error`: Container exited with error
+- `ImagePullBackOff`: Cannot pull container image
+- `Evicted`: Pod evicted due to resource pressure
+
+### 2. Describe Pod for Details
+
+```bash
+# Get detailed pod information
+kubectl describe pod <pod-name>
+
+# Focus on specific sections
+kubectl describe pod <pod-name> | grep -A 10 Events
+kubectl describe pod <pod-name> | grep -A 5 State
+```
+
+**Look for:**
+- Events (errors, warnings, scheduling issues)
+- Container states and restart counts
+- Resource requests/limits vs actual usage
+- Node assignment and conditions
+- Volume mount issues
+
+### 3. Check Logs
+
+```bash
+# View current logs
+kubectl logs <pod-name>
+
+# View logs from specific container in multi-container pod
+kubectl logs <pod-name> -c <container-name>
+
+# Follow logs in real-time
+kubectl logs <pod-name> -f
+
+# View previous container logs (after crash)
+kubectl logs <pod-name> --previous
+
+# Get last N lines
+kubectl logs <pod-name> --tail=100
+
+# Show timestamps
+kubectl logs <pod-name> --timestamps
+```
+
+### 4. Check Events
+
+```bash
+# Get recent events sorted by time
+kubectl get events --sort-by=.metadata.creationTimestamp
+
+# Watch events in real-time
+kubectl get events -w
+
+# Get events for specific namespace
+kubectl get events -n <namespace>
+
+# Filter events by type
+kubectl get events --field-selector type=Warning
+```
+
+### 5. Exec into Pod
+
+```bash
+# Get shell in pod
+kubectl exec -it <pod-name> -- /bin/sh
+kubectl exec -it <pod-name> -- /bin/bash
+
+# Run specific command
+kubectl exec <pod-name> -- ls /app
+kubectl exec <pod-name> -- env
+kubectl exec <pod-name> -- cat /etc/resolv.conf
+
+# Exec into specific container
+kubectl exec -it <pod-name> -c <container-name> -- /bin/sh
+```
+
+**Inside pod, check:**
+- Environment variables: `env`
+- DNS resolution: `nslookup service-name`
+- Network connectivity: `wget -O- http://service:port`
+- File permissions: `ls -la /app`
+- Disk usage: `df -h`
+- Process list: `ps aux`
+
+### 6. Port Forward for Testing
+
+```bash
+# Forward local port to pod port
+kubectl port-forward pod/<pod-name> 8080:8080
+
+# Forward to service
+kubectl port-forward service/<service-name> 8080:80
+
+# Forward in background
+kubectl port-forward pod/<pod-name> 8080:8080 &
+
+# Test with curl
+curl http://localhost:8080
+```
+
+### 7. Check Resource Usage
+
+```bash
+# Get pod resource usage (requires metrics-server)
+kubectl top pod <pod-name>
+
+# Get all pods resource usage
+kubectl top pods
+
+# Get node resource usage
+kubectl top nodes
+```
+
+### 8. Check Related Resources
+
+```bash
+# Check deployment
+kubectl get deployment <deployment-name>
+kubectl describe deployment <deployment-name>
+
+# Check replica set
+kubectl get rs
+kubectl describe rs <replicaset-name>
+
+# Check service
+kubectl get svc
+kubectl describe svc <service-name>
+
+# Check endpoints
+kubectl get endpoints <service-name>
+
+# Check configmaps and secrets
+kubectl get configmap
+kubectl get secret
+kubectl describe configmap <name>
+```
+
+### 9. Network Debugging
+
+```bash
+# Check service endpoints
+kubectl get endpoints
+
+# Test DNS resolution from within pod
+kubectl exec <pod-name> -- nslookup kubernetes.default
+kubectl exec <pod-name> -- nslookup <service-name>
+
+# Check network policies
+kubectl get networkpolicies
+kubectl describe networkpolicy <policy-name>
+
+# Test connectivity between pods
+kubectl exec <pod-name> -- wget -O- http://<service-name>:<port>
+```
+
+### 10. Check RBAC Permissions
+
+```bash
+# Check if service account can perform action
+kubectl auth can-i get pods --as=system:serviceaccount:<namespace>:<sa-name>
+
+# Get service account details
+kubectl get serviceaccount <sa-name> -o yaml
+
+# Check role bindings
+kubectl get rolebindings
+kubectl describe rolebinding <binding-name>
+```
+
+## Common Issues and Solutions
+
+### ImagePullBackOff
+
+**Causes:**
+- Image doesn't exist
+- Image tag is wrong
+- Private registry authentication failed
+- Network issues pulling image
+
+**Debug:**
+```bash
+kubectl describe pod <pod-name> | grep -A 5 "Failed"
+kubectl get events | grep "Failed to pull"
+```
+
+**Solutions:**
+- Verify image name and tag
+- Check imagePullSecrets
+- Test image pull manually: `docker pull <image>`
+
+### CrashLoopBackOff
+
+**Causes:**
+- Application exits immediately
+- Missing dependencies or configuration
+- Resource limits too low
+- Failed health checks
+
+**Debug:**
+```bash
+kubectl logs <pod-name> --previous
+kubectl describe pod <pod-name>
+```
+
+**Solutions:**
+- Check application logs for errors
+- Verify environment variables and config
+- Increase resource limits
+- Check liveness probe configuration
+
+### Pending Pods
+
+**Causes:**
+- Insufficient node resources
+- Node selector/affinity not matching
+- PersistentVolumeClaim not bound
+- Pod security policy blocking
+
+**Debug:**
+```bash
+kubectl describe pod <pod-name> | grep -A 10 Events
+kubectl get nodes
+kubectl top nodes
+```
+
+**Solutions:**
+- Scale cluster or reduce resource requests
+- Check node labels and selectors
+- Verify PVC status
+- Review pod security policies
+
+### OOMKilled (Out of Memory)
+
+**Causes:**
+- Memory limit too low
+- Memory leak in application
+- Unexpected memory usage spike
+
+**Debug:**
+```bash
+kubectl describe pod <pod-name> | grep -i "OOMKilled"
+kubectl top pod <pod-name>
+```
+
+**Solutions:**
+- Increase memory limits
+- Investigate application memory usage
+- Add memory profiling to application
+
+## Debugging Checklist
+
+- [ ] Check pod status and events
+- [ ] Review pod description for errors
+- [ ] Examine current and previous logs
+- [ ] Verify resource requests and limits
+- [ ] Test network connectivity
+- [ ] Validate environment variables and config
+- [ ] Check RBAC permissions
+- [ ] Verify image and pull secrets
+- [ ] Review health probe configuration
+- [ ] Check node resources and scheduling
+
+## Advanced Debugging
+
+### Enable Debug Container (Kubernetes 1.23+)
+
+```bash
+# Add ephemeral debug container to running pod
+kubectl debug <pod-name> -it --image=busybox --target=<container-name>
+
+# Create debug copy of pod
+kubectl debug <pod-name> -it --copy-to=<debug-pod-name> --container=debug
+```
+
+### Node Debugging
+
+```bash
+# SSH to node (if accessible)
+kubectl get nodes -o wide
+
+# Create privileged pod on specific node
+kubectl debug node/<node-name> -it --image=ubuntu
+```
+
+### Check API Server Logs
+
+```bash
+# Get API server logs (if running as pod)
+kubectl logs -n kube-system kube-apiserver-<node-name>
+
+# Get controller manager logs
+kubectl logs -n kube-system kube-controller-manager-<node-name>
+
+# Get scheduler logs
+kubectl logs -n kube-system kube-scheduler-<node-name>
+```
+
+## Monitoring Recommendations
+
+**Install metrics-server:**
+```bash
+kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
+```
+
+**Use kubectl plugins:**
+- `kubectl-debug`: Enhanced debugging capabilities
+- `kubectl-trace`: Trace syscalls and kernel events
+- `kubectl-df`: Show disk usage in pods
+- `kubectl-view-allocations`: View resource allocations
+
+## Example Debugging Session
+
+```bash
+# 1. Find problematic pod
+kubectl get pods | grep -v Running
+
+# 2. Get details
+kubectl describe pod myapp-5d4b6c8f9-xz2k4
+
+# 3. Check logs
+kubectl logs myapp-5d4b6c8f9-xz2k4 --previous
+
+# 4. Check events
+kubectl get events --field-selector involvedObject.name=myapp-5d4b6c8f9-xz2k4
+
+# 5. Test connectivity
+kubectl exec myapp-5d4b6c8f9-xz2k4 -- wget -O- http://backend-service:8080
+
+# 6. Check resources
+kubectl top pod myapp-5d4b6c8f9-xz2k4
+
+# 7. If needed, exec into pod
+kubectl exec -it myapp-5d4b6c8f9-xz2k4 -- /bin/sh
+```
dots/.config/claude/skills/Kubernetes/workflows/Deploy.md
@@ -0,0 +1,567 @@
+# Deploy Workflow
+
+Best practices for deploying applications to Kubernetes with proper validation and rollout management.
+
+## When to Use
+
+- Deploying new applications to cluster
+- Updating existing deployments
+- Rolling out configuration changes
+- Managing deployment strategies
+
+## Deployment Best Practices
+
+### Pre-Deployment Checklist
+
+- [ ] Manifests validated with `kubectl apply --dry-run=client`
+- [ ] Resource limits and requests defined
+- [ ] Health probes configured (readiness, liveness)
+- [ ] Security context set (non-root user)
+- [ ] Labels and selectors properly configured
+- [ ] Secrets and ConfigMaps created
+- [ ] Image tags are specific (not `:latest`)
+- [ ] Namespace exists
+- [ ] RBAC permissions configured
+- [ ] Pod disruption budget defined (for production)
+
+## Deployment Steps
+
+### 1. Validate Manifests
+
+```bash
+# Dry-run validation (client-side)
+kubectl apply --dry-run=client -f deployment.yaml
+
+# Dry-run validation (server-side, with validation)
+kubectl apply --dry-run=server -f deployment.yaml
+
+# Validate with kubectl diff
+kubectl diff -f deployment.yaml
+
+# Validate YAML syntax
+kubectl apply --dry-run=client -f deployment.yaml -o yaml
+```
+
+### 2. Create Namespace (if needed)
+
+```bash
+# Create namespace
+kubectl create namespace myapp
+
+# Or use manifest
+cat <<EOF | kubectl apply -f -
+apiVersion: v1
+kind: Namespace
+metadata:
+ name: myapp
+ labels:
+ name: myapp
+EOF
+```
+
+### 3. Create ConfigMaps and Secrets
+
+```bash
+# Create ConfigMap from file
+kubectl create configmap myapp-config --from-file=config.json
+
+# Create ConfigMap from literal
+kubectl create configmap myapp-config \
+ --from-literal=database_url=postgres://db:5432/myapp \
+ --from-literal=cache_ttl=3600
+
+# Create Secret from file
+kubectl create secret generic myapp-secret --from-file=credentials.json
+
+# Create Secret from literal
+kubectl create secret generic myapp-secret \
+ --from-literal=api_key=supersecret123
+
+# Create TLS secret
+kubectl create secret tls myapp-tls \
+ --cert=path/to/cert.pem \
+ --key=path/to/key.pem
+```
+
+### 4. Apply Deployment
+
+```bash
+# Apply single file
+kubectl apply -f deployment.yaml
+
+# Apply directory
+kubectl apply -f ./k8s/
+
+# Apply with specific namespace
+kubectl apply -f deployment.yaml -n myapp
+
+# Apply and record the command (for rollback)
+kubectl apply -f deployment.yaml --record
+
+# Apply with validation
+kubectl apply -f deployment.yaml --validate=true
+```
+
+### 5. Monitor Rollout
+
+```bash
+# Check rollout status
+kubectl rollout status deployment/myapp
+
+# Watch deployment progress
+kubectl get deployment myapp -w
+
+# Check pods during rollout
+kubectl get pods -l app=myapp -w
+
+# Check events
+kubectl get events -w
+```
+
+### 6. Verify Deployment
+
+```bash
+# Get deployment status
+kubectl get deployment myapp
+
+# Check pods are running
+kubectl get pods -l app=myapp
+
+# Check replica set
+kubectl get rs -l app=myapp
+
+# Verify service endpoints
+kubectl get endpoints myapp
+
+# Test service connectivity
+kubectl port-forward service/myapp 8080:80
+curl http://localhost:8080/healthz
+```
+
+## Deployment Strategies
+
+### Rolling Update (Default)
+
+**Best for:** Most applications, zero-downtime deployments
+
+```yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: myapp
+spec:
+ replicas: 3
+ strategy:
+ type: RollingUpdate
+ rollingUpdate:
+ maxSurge: 1 # Max pods above desired count
+ maxUnavailable: 0 # Max pods unavailable during update
+ template:
+ spec:
+ containers:
+ - name: myapp
+ image: myapp:v2.0.0
+```
+
+**Commands:**
+```bash
+# Update image
+kubectl set image deployment/myapp myapp=myapp:v2.0.0
+
+# Monitor rollout
+kubectl rollout status deployment/myapp
+
+# Pause rollout
+kubectl rollout pause deployment/myapp
+
+# Resume rollout
+kubectl rollout resume deployment/myapp
+```
+
+### Recreate Strategy
+
+**Best for:** Incompatible version changes, dev environments
+
+```yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: myapp
+spec:
+ replicas: 3
+ strategy:
+ type: Recreate
+ template:
+ spec:
+ containers:
+ - name: myapp
+ image: myapp:v2.0.0
+```
+
+### Blue/Green Deployment
+
+**Best for:** Zero-downtime with instant rollback capability
+
+```bash
+# Deploy green version alongside blue
+kubectl apply -f deployment-green.yaml
+
+# Verify green is healthy
+kubectl get pods -l version=green
+
+# Switch traffic by updating service selector
+kubectl patch service myapp -p '{"spec":{"selector":{"version":"green"}}}'
+
+# Monitor and rollback if needed
+kubectl patch service myapp -p '{"spec":{"selector":{"version":"blue"}}}'
+
+# Clean up old version
+kubectl delete deployment myapp-blue
+```
+
+### Canary Deployment
+
+**Best for:** Gradual rollout with risk mitigation
+
+```bash
+# Deploy canary with fewer replicas
+kubectl apply -f deployment-canary.yaml
+
+# Monitor metrics and logs
+kubectl logs -l version=canary -f
+
+# Gradually increase canary replicas
+kubectl scale deployment myapp-canary --replicas=2
+
+# If successful, update main deployment
+kubectl apply -f deployment-main.yaml
+
+# Clean up canary
+kubectl delete deployment myapp-canary
+```
+
+## Rollback Procedures
+
+### Quick Rollback
+
+```bash
+# Rollback to previous version
+kubectl rollout undo deployment/myapp
+
+# Rollback to specific revision
+kubectl rollout undo deployment/myapp --to-revision=2
+
+# Check rollback status
+kubectl rollout status deployment/myapp
+```
+
+### View Rollout History
+
+```bash
+# View deployment history
+kubectl rollout history deployment/myapp
+
+# View specific revision
+kubectl rollout history deployment/myapp --revision=3
+
+# Compare revisions
+kubectl rollout history deployment/myapp --revision=2 > rev2.yaml
+kubectl rollout history deployment/myapp --revision=3 > rev3.yaml
+diff rev2.yaml rev3.yaml
+```
+
+## Production Deployment Template
+
+```yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: myapp
+ namespace: production
+ labels:
+ app.kubernetes.io/name: myapp
+ app.kubernetes.io/version: "2.0.0"
+ app.kubernetes.io/component: backend
+spec:
+ replicas: 3
+ revisionHistoryLimit: 10
+ strategy:
+ type: RollingUpdate
+ rollingUpdate:
+ maxSurge: 1
+ maxUnavailable: 0
+ selector:
+ matchLabels:
+ app.kubernetes.io/name: myapp
+ template:
+ metadata:
+ labels:
+ app.kubernetes.io/name: myapp
+ app.kubernetes.io/version: "2.0.0"
+ app.kubernetes.io/component: backend
+ annotations:
+ prometheus.io/scrape: "true"
+ prometheus.io/port: "8080"
+ prometheus.io/path: "/metrics"
+ spec:
+ serviceAccountName: myapp
+ securityContext:
+ runAsNonRoot: true
+ runAsUser: 1000
+ fsGroup: 1000
+ seccompProfile:
+ type: RuntimeDefault
+ containers:
+ - name: myapp
+ image: myregistry.com/myapp:2.0.0
+ imagePullPolicy: IfNotPresent
+ ports:
+ - name: http
+ containerPort: 8080
+ protocol: TCP
+ env:
+ - name: POD_NAME
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.name
+ - name: POD_NAMESPACE
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.namespace
+ envFrom:
+ - configMapRef:
+ name: myapp-config
+ - secretRef:
+ name: myapp-secret
+ resources:
+ requests:
+ cpu: 100m
+ memory: 128Mi
+ limits:
+ cpu: 500m
+ memory: 512Mi
+ livenessProbe:
+ httpGet:
+ path: /healthz
+ port: http
+ initialDelaySeconds: 30
+ periodSeconds: 10
+ timeoutSeconds: 5
+ failureThreshold: 3
+ readinessProbe:
+ httpGet:
+ path: /ready
+ port: http
+ initialDelaySeconds: 5
+ periodSeconds: 5
+ timeoutSeconds: 3
+ failureThreshold: 3
+ startupProbe:
+ httpGet:
+ path: /healthz
+ port: http
+ initialDelaySeconds: 0
+ periodSeconds: 5
+ timeoutSeconds: 3
+ failureThreshold: 30
+ securityContext:
+ allowPrivilegeEscalation: false
+ readOnlyRootFilesystem: true
+ runAsNonRoot: true
+ runAsUser: 1000
+ capabilities:
+ drop:
+ - ALL
+ volumeMounts:
+ - name: tmp
+ mountPath: /tmp
+ - name: cache
+ mountPath: /app/cache
+ volumes:
+ - name: tmp
+ emptyDir: {}
+ - name: cache
+ emptyDir: {}
+ affinity:
+ podAntiAffinity:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ - weight: 100
+ podAffinityTerm:
+ labelSelector:
+ matchLabels:
+ app.kubernetes.io/name: myapp
+ topologyKey: kubernetes.io/hostname
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: myapp
+ namespace: production
+ labels:
+ app.kubernetes.io/name: myapp
+spec:
+ type: ClusterIP
+ selector:
+ app.kubernetes.io/name: myapp
+ ports:
+ - name: http
+ port: 80
+ targetPort: http
+ protocol: TCP
+---
+apiVersion: policy/v1
+kind: PodDisruptionBudget
+metadata:
+ name: myapp
+ namespace: production
+spec:
+ minAvailable: 2
+ selector:
+ matchLabels:
+ app.kubernetes.io/name: myapp
+```
+
+## Update Strategies
+
+### Update Image Only
+
+```bash
+# Update image for specific container
+kubectl set image deployment/myapp myapp=myapp:v2.0.0
+
+# Update with recording for rollback
+kubectl set image deployment/myapp myapp=myapp:v2.0.0 --record
+```
+
+### Update Environment Variables
+
+```bash
+# Update ConfigMap
+kubectl create configmap myapp-config --from-literal=new_key=new_value --dry-run=client -o yaml | kubectl apply -f -
+
+# Restart deployment to pick up changes
+kubectl rollout restart deployment/myapp
+```
+
+### Patch Deployment
+
+```bash
+# Patch replicas
+kubectl patch deployment myapp -p '{"spec":{"replicas":5}}'
+
+# Patch strategy
+kubectl patch deployment myapp -p '{"spec":{"strategy":{"type":"Recreate"}}}'
+
+# Patch with JSON file
+kubectl patch deployment myapp --patch-file=patch.json
+```
+
+## GitOps Best Practices
+
+### Recommended Workflow
+
+1. Store manifests in Git repository
+2. Use Kustomize or Helm for templating
+3. CI/CD pipeline validates manifests
+4. Automated deployment via GitOps tool (ArgoCD, Flux)
+5. Manual approval for production
+6. Automated rollback on failures
+
+### Kustomize Example
+
+```bash
+# Directory structure
+# base/
+# deployment.yaml
+# service.yaml
+# kustomization.yaml
+# overlays/
+# dev/
+# kustomization.yaml
+# prod/
+# kustomization.yaml
+
+# Apply with kustomize
+kubectl apply -k overlays/prod/
+
+# Preview changes
+kubectl diff -k overlays/prod/
+```
+
+## Troubleshooting Deployments
+
+### Deployment Not Progressing
+
+```bash
+# Check deployment status
+kubectl describe deployment myapp
+
+# Look for conditions
+kubectl get deployment myapp -o jsonpath='{.status.conditions}'
+
+# Check replica set
+kubectl get rs -l app=myapp
+kubectl describe rs <replicaset-name>
+```
+
+### Pods Not Starting
+
+```bash
+# Check pod status
+kubectl get pods -l app=myapp
+
+# Describe problematic pod
+kubectl describe pod <pod-name>
+
+# Check events
+kubectl get events --sort-by=.metadata.creationTimestamp
+```
+
+### Resource Quota Issues
+
+```bash
+# Check resource quotas
+kubectl get resourcequota
+
+# Describe quota
+kubectl describe resourcequota <quota-name>
+
+# Check current usage
+kubectl top pods
+```
+
+## Post-Deployment Tasks
+
+```bash
+# Verify deployment health
+kubectl get deployment myapp
+kubectl get pods -l app=myapp
+
+# Check logs
+kubectl logs -l app=myapp --tail=100
+
+# Test endpoint
+kubectl port-forward service/myapp 8080:80
+curl http://localhost:8080/healthz
+
+# Monitor metrics (if metrics-server installed)
+kubectl top pods -l app=myapp
+
+# Clean up old replica sets
+kubectl delete rs <old-replicaset-name>
+```
+
+## Production Deployment Checklist
+
+- [ ] Manifests stored in version control
+- [ ] Dry-run validation passed
+- [ ] Security scan completed (image vulnerabilities)
+- [ ] Resource limits appropriate for load
+- [ ] Health probes tested and validated
+- [ ] Pod disruption budget configured
+- [ ] Monitoring and alerting configured
+- [ ] Rollback procedure documented
+- [ ] Deployment tested in staging
+- [ ] Change approval obtained
+- [ ] Deployment window scheduled
+- [ ] Stakeholders notified
dots/.config/claude/skills/Kubernetes/workflows/Resources.md
@@ -0,0 +1,861 @@
+# Resources Workflow
+
+Creating and managing Kubernetes resources including manifests, ConfigMaps, Secrets, and other workload types.
+
+## When to Use
+
+- Creating new Kubernetes resources
+- Writing or modifying YAML manifests
+- Managing ConfigMaps and Secrets
+- Working with different workload types
+
+## Resource Creation Methods
+
+### Imperative vs Declarative
+
+**Imperative (quick testing, not recommended for production):**
+```bash
+kubectl create deployment nginx --image=nginx
+kubectl expose deployment nginx --port=80
+kubectl scale deployment nginx --replicas=3
+```
+
+**Declarative (recommended for production):**
+```bash
+kubectl apply -f deployment.yaml
+kubectl apply -f service.yaml
+kubectl apply -k ./manifests/
+```
+
+## Common Resource Types
+
+### Deployment
+
+**Use for:** Stateless applications, web servers, APIs
+
+```yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: myapp
+ namespace: production
+ labels:
+ app.kubernetes.io/name: myapp
+ app.kubernetes.io/version: "1.0.0"
+spec:
+ replicas: 3
+ selector:
+ matchLabels:
+ app.kubernetes.io/name: myapp
+ template:
+ metadata:
+ labels:
+ app.kubernetes.io/name: myapp
+ app.kubernetes.io/version: "1.0.0"
+ spec:
+ containers:
+ - name: myapp
+ image: myapp:1.0.0
+ ports:
+ - containerPort: 8080
+ name: http
+ resources:
+ requests:
+ cpu: 100m
+ memory: 128Mi
+ limits:
+ cpu: 500m
+ memory: 512Mi
+ livenessProbe:
+ httpGet:
+ path: /healthz
+ port: http
+ initialDelaySeconds: 30
+ periodSeconds: 10
+ readinessProbe:
+ httpGet:
+ path: /ready
+ port: http
+ initialDelaySeconds: 5
+ periodSeconds: 5
+```
+
+### StatefulSet
+
+**Use for:** Databases, stateful applications requiring stable network identity and persistent storage
+
+```yaml
+apiVersion: apps/v1
+kind: StatefulSet
+metadata:
+ name: postgres
+ namespace: production
+spec:
+ serviceName: postgres
+ replicas: 3
+ selector:
+ matchLabels:
+ app: postgres
+ template:
+ metadata:
+ labels:
+ app: postgres
+ spec:
+ containers:
+ - name: postgres
+ image: postgres:15
+ ports:
+ - containerPort: 5432
+ name: postgres
+ env:
+ - name: POSTGRES_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: postgres-secret
+ key: password
+ - name: PGDATA
+ value: /var/lib/postgresql/data/pgdata
+ volumeMounts:
+ - name: data
+ mountPath: /var/lib/postgresql/data
+ resources:
+ requests:
+ cpu: 500m
+ memory: 1Gi
+ limits:
+ cpu: 2000m
+ memory: 4Gi
+ volumeClaimTemplates:
+ - metadata:
+ name: data
+ spec:
+ accessModes: ["ReadWriteOnce"]
+ storageClassName: fast-ssd
+ resources:
+ requests:
+ storage: 100Gi
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: postgres
+ namespace: production
+spec:
+ clusterIP: None # Headless service for StatefulSet
+ selector:
+ app: postgres
+ ports:
+ - port: 5432
+ targetPort: postgres
+ name: postgres
+```
+
+### DaemonSet
+
+**Use for:** Node-level services (logging, monitoring, network plugins)
+
+```yaml
+apiVersion: apps/v1
+kind: DaemonSet
+metadata:
+ name: node-exporter
+ namespace: monitoring
+spec:
+ selector:
+ matchLabels:
+ app: node-exporter
+ template:
+ metadata:
+ labels:
+ app: node-exporter
+ spec:
+ hostNetwork: true
+ hostPID: true
+ containers:
+ - name: node-exporter
+ image: prom/node-exporter:latest
+ args:
+ - --path.procfs=/host/proc
+ - --path.sysfs=/host/sys
+ - --collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)
+ ports:
+ - containerPort: 9100
+ protocol: TCP
+ name: metrics
+ resources:
+ requests:
+ cpu: 100m
+ memory: 128Mi
+ limits:
+ cpu: 200m
+ memory: 256Mi
+ volumeMounts:
+ - name: proc
+ mountPath: /host/proc
+ readOnly: true
+ - name: sys
+ mountPath: /host/sys
+ readOnly: true
+ volumes:
+ - name: proc
+ hostPath:
+ path: /proc
+ - name: sys
+ hostPath:
+ path: /sys
+ tolerations:
+ - effect: NoSchedule
+ operator: Exists
+```
+
+### Job
+
+**Use for:** One-time batch jobs, database migrations, backups
+
+```yaml
+apiVersion: batch/v1
+kind: Job
+metadata:
+ name: database-migration
+ namespace: production
+spec:
+ ttlSecondsAfterFinished: 86400 # Clean up after 24 hours
+ backoffLimit: 3
+ template:
+ metadata:
+ labels:
+ app: migration
+ spec:
+ restartPolicy: OnFailure
+ containers:
+ - name: migrate
+ image: myapp:1.0.0
+ command: ["/app/migrate"]
+ args: ["--direction", "up"]
+ env:
+ - name: DATABASE_URL
+ valueFrom:
+ secretKeyRef:
+ name: db-secret
+ key: url
+ resources:
+ requests:
+ cpu: 100m
+ memory: 128Mi
+ limits:
+ cpu: 500m
+ memory: 512Mi
+```
+
+### CronJob
+
+**Use for:** Scheduled tasks, periodic backups, cleanup jobs
+
+```yaml
+apiVersion: batch/v1
+kind: CronJob
+metadata:
+ name: backup-job
+ namespace: production
+spec:
+ schedule: "0 2 * * *" # Daily at 2 AM
+ timeZone: "America/New_York"
+ concurrencyPolicy: Forbid
+ successfulJobsHistoryLimit: 3
+ failedJobsHistoryLimit: 3
+ jobTemplate:
+ spec:
+ ttlSecondsAfterFinished: 86400
+ template:
+ metadata:
+ labels:
+ app: backup
+ spec:
+ restartPolicy: OnFailure
+ containers:
+ - name: backup
+ image: backup-tool:latest
+ command: ["/backup.sh"]
+ env:
+ - name: BACKUP_TARGET
+ value: s3://my-backups/
+ - name: AWS_ACCESS_KEY_ID
+ valueFrom:
+ secretKeyRef:
+ name: aws-credentials
+ key: access-key-id
+ - name: AWS_SECRET_ACCESS_KEY
+ valueFrom:
+ secretKeyRef:
+ name: aws-credentials
+ key: secret-access-key
+ resources:
+ requests:
+ cpu: 100m
+ memory: 256Mi
+ limits:
+ cpu: 500m
+ memory: 1Gi
+```
+
+## ConfigMaps and Secrets
+
+### ConfigMap
+
+**Use for:** Non-sensitive configuration data
+
+**From literals:**
+```bash
+kubectl create configmap myapp-config \
+ --from-literal=database_host=postgres.production.svc.cluster.local \
+ --from-literal=database_port=5432 \
+ --from-literal=log_level=info
+```
+
+**From file:**
+```bash
+kubectl create configmap myapp-config --from-file=config.json
+kubectl create configmap nginx-config --from-file=nginx.conf
+```
+
+**From directory:**
+```bash
+kubectl create configmap app-configs --from-file=./configs/
+```
+
+**Declarative YAML:**
+```yaml
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: myapp-config
+ namespace: production
+data:
+ database_host: postgres.production.svc.cluster.local
+ database_port: "5432"
+ log_level: info
+ config.json: |
+ {
+ "feature_flags": {
+ "new_ui": true,
+ "beta_features": false
+ },
+ "cache_ttl": 3600
+ }
+```
+
+**Using ConfigMap in Pod:**
+```yaml
+apiVersion: v1
+kind: Pod
+metadata:
+ name: myapp
+spec:
+ containers:
+ - name: myapp
+ image: myapp:1.0.0
+ # Option 1: All keys as environment variables
+ envFrom:
+ - configMapRef:
+ name: myapp-config
+ # Option 2: Specific keys as environment variables
+ env:
+ - name: DATABASE_HOST
+ valueFrom:
+ configMapKeyRef:
+ name: myapp-config
+ key: database_host
+ # Option 3: Mount as volume
+ volumeMounts:
+ - name: config
+ mountPath: /etc/config
+ volumes:
+ - name: config
+ configMap:
+ name: myapp-config
+```
+
+### Secret
+
+**Use for:** Sensitive data (passwords, tokens, certificates)
+
+**From literals:**
+```bash
+kubectl create secret generic myapp-secret \
+ --from-literal=api_key=supersecret123 \
+ --from-literal=database_password=pass123
+```
+
+**From file:**
+```bash
+kubectl create secret generic myapp-secret --from-file=credentials.json
+kubectl create secret generic ssh-key --from-file=ssh-privatekey=~/.ssh/id_rsa
+```
+
+**TLS secret:**
+```bash
+kubectl create secret tls myapp-tls \
+ --cert=path/to/cert.pem \
+ --key=path/to/key.pem
+```
+
+**Docker registry secret:**
+```bash
+kubectl create secret docker-registry regcred \
+ --docker-server=myregistry.com \
+ --docker-username=user \
+ --docker-password=pass \
+ --docker-email=user@example.com
+```
+
+**Declarative YAML:**
+```yaml
+apiVersion: v1
+kind: Secret
+metadata:
+ name: myapp-secret
+ namespace: production
+type: Opaque
+stringData: # Use stringData for plain text (will be base64 encoded)
+ api_key: supersecret123
+ database_password: pass123
+# Or use data for base64 encoded values
+data:
+ api_key: c3VwZXJzZWNyZXQxMjM=
+```
+
+**Using Secret in Pod:**
+```yaml
+apiVersion: v1
+kind: Pod
+metadata:
+ name: myapp
+spec:
+ containers:
+ - name: myapp
+ image: myapp:1.0.0
+ # Option 1: All keys as environment variables
+ envFrom:
+ - secretRef:
+ name: myapp-secret
+ # Option 2: Specific keys as environment variables
+ env:
+ - name: API_KEY
+ valueFrom:
+ secretKeyRef:
+ name: myapp-secret
+ key: api_key
+ # Option 3: Mount as volume (RECOMMENDED for sensitive data)
+ volumeMounts:
+ - name: secrets
+ mountPath: /etc/secrets
+ readOnly: true
+ # Use image pull secret
+ imagePullSecrets:
+ - name: regcred
+ volumes:
+ - name: secrets
+ secret:
+ secretName: myapp-secret
+ defaultMode: 0400 # Read-only for owner
+```
+
+## Service Types
+
+### ClusterIP (Default)
+
+**Use for:** Internal service-to-service communication
+
+```yaml
+apiVersion: v1
+kind: Service
+metadata:
+ name: backend
+ namespace: production
+spec:
+ type: ClusterIP
+ selector:
+ app: backend
+ ports:
+ - name: http
+ port: 80
+ targetPort: 8080
+ protocol: TCP
+```
+
+### NodePort
+
+**Use for:** Exposing service on each node's IP at a static port
+
+```yaml
+apiVersion: v1
+kind: Service
+metadata:
+ name: frontend
+ namespace: production
+spec:
+ type: NodePort
+ selector:
+ app: frontend
+ ports:
+ - name: http
+ port: 80
+ targetPort: 8080
+ nodePort: 30080 # Optional: 30000-32767 range
+ protocol: TCP
+```
+
+### LoadBalancer
+
+**Use for:** Exposing service externally using cloud provider's load balancer
+
+```yaml
+apiVersion: v1
+kind: Service
+metadata:
+ name: web
+ namespace: production
+ annotations:
+ service.beta.kubernetes.io/aws-load-balancer-type: nlb
+spec:
+ type: LoadBalancer
+ selector:
+ app: web
+ ports:
+ - name: http
+ port: 80
+ targetPort: 8080
+ - name: https
+ port: 443
+ targetPort: 8443
+```
+
+### Headless Service
+
+**Use for:** StatefulSet, direct pod-to-pod communication
+
+```yaml
+apiVersion: v1
+kind: Service
+metadata:
+ name: cassandra
+ namespace: production
+spec:
+ clusterIP: None # Headless
+ selector:
+ app: cassandra
+ ports:
+ - port: 9042
+ name: cql
+```
+
+## Ingress
+
+**Use for:** HTTP/HTTPS routing to services
+
+```yaml
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: myapp-ingress
+ namespace: production
+ annotations:
+ cert-manager.io/cluster-issuer: letsencrypt-prod
+ nginx.ingress.kubernetes.io/ssl-redirect: "true"
+ nginx.ingress.kubernetes.io/rate-limit: "100"
+spec:
+ ingressClassName: nginx
+ tls:
+ - hosts:
+ - myapp.example.com
+ secretName: myapp-tls
+ rules:
+ - host: myapp.example.com
+ http:
+ paths:
+ - path: /
+ pathType: Prefix
+ backend:
+ service:
+ name: frontend
+ port:
+ number: 80
+ - path: /api
+ pathType: Prefix
+ backend:
+ service:
+ name: backend
+ port:
+ number: 80
+```
+
+## Persistent Volumes
+
+### PersistentVolume (PV)
+
+```yaml
+apiVersion: v1
+kind: PersistentVolume
+metadata:
+ name: data-pv
+spec:
+ capacity:
+ storage: 100Gi
+ accessModes:
+ - ReadWriteOnce
+ persistentVolumeReclaimPolicy: Retain
+ storageClassName: fast-ssd
+ hostPath:
+ path: /data/pv
+```
+
+### PersistentVolumeClaim (PVC)
+
+```yaml
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: data-pvc
+ namespace: production
+spec:
+ accessModes:
+ - ReadWriteOnce
+ storageClassName: fast-ssd
+ resources:
+ requests:
+ storage: 50Gi
+```
+
+**Using PVC in Pod:**
+```yaml
+apiVersion: v1
+kind: Pod
+metadata:
+ name: myapp
+spec:
+ containers:
+ - name: myapp
+ image: myapp:1.0.0
+ volumeMounts:
+ - name: data
+ mountPath: /app/data
+ volumes:
+ - name: data
+ persistentVolumeClaim:
+ claimName: data-pvc
+```
+
+## Resource Management Commands
+
+### Get Resources
+
+```bash
+# Get all resources in namespace
+kubectl get all
+
+# Get specific resource types
+kubectl get deployments
+kubectl get pods
+kubectl get services
+kubectl get ingress
+
+# Get with additional details
+kubectl get pods -o wide
+kubectl get pods -o yaml
+kubectl get pods -o json
+
+# Get with labels
+kubectl get pods --show-labels
+kubectl get pods -l app=myapp
+kubectl get pods -l 'environment in (prod,staging)'
+
+# Get from all namespaces
+kubectl get pods --all-namespaces
+kubectl get pods -A
+```
+
+### Create Resources
+
+```bash
+# Apply from file
+kubectl apply -f deployment.yaml
+
+# Apply from directory
+kubectl apply -f ./manifests/
+
+# Apply from URL
+kubectl apply -f https://example.com/manifest.yaml
+
+# Create from stdin
+cat <<EOF | kubectl apply -f -
+apiVersion: v1
+kind: Namespace
+metadata:
+ name: test
+EOF
+```
+
+### Update Resources
+
+```bash
+# Apply changes
+kubectl apply -f deployment.yaml
+
+# Edit resource interactively
+kubectl edit deployment myapp
+
+# Patch resource
+kubectl patch deployment myapp -p '{"spec":{"replicas":5}}'
+
+# Replace resource (delete and recreate)
+kubectl replace -f deployment.yaml
+
+# Set image
+kubectl set image deployment/myapp myapp=myapp:v2.0.0
+```
+
+### Delete Resources
+
+```bash
+# Delete from file
+kubectl delete -f deployment.yaml
+
+# Delete by name
+kubectl delete deployment myapp
+kubectl delete pod myapp-pod
+
+# Delete with label selector
+kubectl delete pods -l app=myapp
+
+# Delete all resources in namespace
+kubectl delete all --all -n test
+
+# Force delete stuck pod
+kubectl delete pod myapp-pod --grace-period=0 --force
+```
+
+## Best Practices
+
+### Resource Naming
+
+- Use lowercase alphanumeric characters and hyphens
+- Maximum 253 characters
+- Start and end with alphanumeric character
+- Use descriptive names: `web-frontend`, `api-backend`
+
+### Labels
+
+**Recommended labels:**
+```yaml
+metadata:
+ labels:
+ app.kubernetes.io/name: myapp
+ app.kubernetes.io/instance: myapp-prod
+ app.kubernetes.io/version: "1.0.0"
+ app.kubernetes.io/component: backend
+ app.kubernetes.io/part-of: myplatform
+ app.kubernetes.io/managed-by: kubectl
+ environment: production
+ team: backend
+```
+
+### Annotations
+
+**Common annotations:**
+```yaml
+metadata:
+ annotations:
+ description: "Backend API service"
+ contact: "backend-team@example.com"
+ prometheus.io/scrape: "true"
+ prometheus.io/port: "8080"
+ prometheus.io/path: "/metrics"
+```
+
+### Resource Requests and Limits
+
+**Always set for production:**
+```yaml
+resources:
+ requests:
+ cpu: 100m # Minimum guaranteed
+ memory: 128Mi
+ limits:
+ cpu: 500m # Maximum allowed
+ memory: 512Mi
+```
+
+**Guidelines:**
+- Set requests based on average usage
+- Set limits 1.5-2x higher than requests
+- Monitor actual usage with `kubectl top pods`
+- Adjust based on metrics
+
+### Health Probes
+
+**Liveness Probe:** Restart container if unhealthy
+**Readiness Probe:** Remove from service endpoints if not ready
+**Startup Probe:** Allow slow-starting containers time to start
+
+```yaml
+livenessProbe:
+ httpGet:
+ path: /healthz
+ port: 8080
+ initialDelaySeconds: 30
+ periodSeconds: 10
+ timeoutSeconds: 5
+ failureThreshold: 3
+
+readinessProbe:
+ httpGet:
+ path: /ready
+ port: 8080
+ initialDelaySeconds: 5
+ periodSeconds: 5
+ timeoutSeconds: 3
+ failureThreshold: 3
+
+startupProbe:
+ httpGet:
+ path: /healthz
+ port: 8080
+ initialDelaySeconds: 0
+ periodSeconds: 5
+ timeoutSeconds: 3
+ failureThreshold: 30 # 150 seconds to start
+```
+
+## Validation and Testing
+
+```bash
+# Validate YAML syntax
+kubectl apply --dry-run=client -f manifest.yaml
+
+# Server-side validation
+kubectl apply --dry-run=server -f manifest.yaml
+
+# Preview changes
+kubectl diff -f manifest.yaml
+
+# Validate with kube-linter (external tool)
+kube-linter lint manifest.yaml
+
+# Check resource compliance
+kubectl-score manifest.yaml
+```
+
+## Resource Management Checklist
+
+- [ ] Use declarative YAML manifests
+- [ ] Set resource requests and limits
+- [ ] Configure health probes
+- [ ] Use appropriate labels and annotations
+- [ ] Set security context (non-root user)
+- [ ] Use Secrets for sensitive data
+- [ ] Use ConfigMaps for configuration
+- [ ] Define appropriate service type
+- [ ] Set up Ingress for external access
+- [ ] Use PVCs for persistent data
+- [ ] Validate manifests before applying
+- [ ] Version control all manifests
dots/.config/claude/skills/Kubernetes/workflows/Scaling.md
@@ -0,0 +1,678 @@
+# Scaling Workflow
+
+Kubernetes scaling strategies including manual scaling, Horizontal Pod Autoscaling (HPA), and Vertical Pod Autoscaling (VPA).
+
+## When to Use
+
+- Scaling applications based on load
+- Setting up autoscaling policies
+- Optimizing resource utilization
+- Handling traffic spikes
+
+## Manual Scaling
+
+### Scale Deployment
+
+```bash
+# Scale to specific number of replicas
+kubectl scale deployment myapp --replicas=5
+
+# Scale multiple deployments
+kubectl scale deployment myapp myapp2 --replicas=3
+
+# Scale with label selector
+kubectl scale deployment -l app=myapp --replicas=3
+
+# Scale replica set
+kubectl scale rs myapp-rs --replicas=5
+
+# Scale stateful set
+kubectl scale statefulset postgres --replicas=3
+```
+
+### Verify Scaling
+
+```bash
+# Check deployment status
+kubectl get deployment myapp
+
+# Watch scaling progress
+kubectl get pods -l app=myapp -w
+
+# Check replica set
+kubectl get rs -l app=myapp
+```
+
+## Horizontal Pod Autoscaler (HPA)
+
+### Prerequisites
+
+**Install metrics-server:**
+```bash
+kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
+```
+
+**Verify metrics-server:**
+```bash
+kubectl get deployment metrics-server -n kube-system
+kubectl top nodes
+kubectl top pods
+```
+
+### Create HPA (CPU-based)
+
+**Imperative:**
+```bash
+# Create HPA based on CPU utilization
+kubectl autoscale deployment myapp --cpu-percent=70 --min=2 --max=10
+
+# View HPA
+kubectl get hpa myapp
+
+# Describe HPA
+kubectl describe hpa myapp
+```
+
+**Declarative:**
+```yaml
+apiVersion: autoscaling/v2
+kind: HorizontalPodAutoscaler
+metadata:
+ name: myapp-hpa
+ namespace: production
+spec:
+ scaleTargetRef:
+ apiVersion: apps/v1
+ kind: Deployment
+ name: myapp
+ minReplicas: 2
+ maxReplicas: 10
+ metrics:
+ - type: Resource
+ resource:
+ name: cpu
+ target:
+ type: Utilization
+ averageUtilization: 70
+```
+
+### HPA with Multiple Metrics
+
+```yaml
+apiVersion: autoscaling/v2
+kind: HorizontalPodAutoscaler
+metadata:
+ name: myapp-hpa
+ namespace: production
+spec:
+ scaleTargetRef:
+ apiVersion: apps/v1
+ kind: Deployment
+ name: myapp
+ minReplicas: 2
+ maxReplicas: 20
+ behavior:
+ scaleDown:
+ stabilizationWindowSeconds: 300
+ policies:
+ - type: Percent
+ value: 50
+ periodSeconds: 60
+ - type: Pods
+ value: 2
+ periodSeconds: 60
+ selectPolicy: Min
+ scaleUp:
+ stabilizationWindowSeconds: 0
+ policies:
+ - type: Percent
+ value: 100
+ periodSeconds: 30
+ - type: Pods
+ value: 4
+ periodSeconds: 30
+ selectPolicy: Max
+ metrics:
+ # CPU utilization
+ - type: Resource
+ resource:
+ name: cpu
+ target:
+ type: Utilization
+ averageUtilization: 70
+ # Memory utilization
+ - type: Resource
+ resource:
+ name: memory
+ target:
+ type: Utilization
+ averageUtilization: 80
+ # Custom metric (requests per second)
+ - type: Pods
+ pods:
+ metric:
+ name: http_requests_per_second
+ target:
+ type: AverageValue
+ averageValue: "1000"
+```
+
+### HPA Based on Custom Metrics
+
+**Prometheus adapter example:**
+```yaml
+apiVersion: autoscaling/v2
+kind: HorizontalPodAutoscaler
+metadata:
+ name: myapp-hpa-custom
+ namespace: production
+spec:
+ scaleTargetRef:
+ apiVersion: apps/v1
+ kind: Deployment
+ name: myapp
+ minReplicas: 2
+ maxReplicas: 10
+ metrics:
+ - type: Pods
+ pods:
+ metric:
+ name: http_requests_per_second
+ target:
+ type: AverageValue
+ averageValue: "1000"
+ - type: Pods
+ pods:
+ metric:
+ name: queue_length
+ target:
+ type: AverageValue
+ averageValue: "30"
+```
+
+### Monitor HPA
+
+```bash
+# Get HPA status
+kubectl get hpa
+
+# Watch HPA in real-time
+kubectl get hpa -w
+
+# Describe HPA for details
+kubectl describe hpa myapp-hpa
+
+# View events
+kubectl get events --sort-by=.metadata.creationTimestamp | grep HorizontalPodAutoscaler
+
+# Check current metrics
+kubectl top pods -l app=myapp
+```
+
+### Test HPA
+
+**Load testing:**
+```bash
+# Generate load with kubectl run
+kubectl run -i --tty load-generator --rm --image=busybox --restart=Never -- /bin/sh -c "while sleep 0.01; do wget -q -O- http://myapp; done"
+
+# Watch HPA scale up
+kubectl get hpa myapp-hpa -w
+
+# Watch pods being created
+kubectl get pods -l app=myapp -w
+```
+
+### Delete HPA
+
+```bash
+# Delete HPA
+kubectl delete hpa myapp-hpa
+
+# Deployment will maintain last replica count
+kubectl scale deployment myapp --replicas=3
+```
+
+## Vertical Pod Autoscaler (VPA)
+
+### Install VPA
+
+```bash
+# Clone VPA repository
+git clone https://github.com/kubernetes/autoscaler.git
+cd autoscaler/vertical-pod-autoscaler
+
+# Install VPA
+./hack/vpa-up.sh
+
+# Verify installation
+kubectl get deployment -n kube-system | grep vpa
+```
+
+### Create VPA
+
+**Recommendation mode (does not modify pods):**
+```yaml
+apiVersion: autoscaling.k8s.io/v1
+kind: VerticalPodAutoscaler
+metadata:
+ name: myapp-vpa
+ namespace: production
+spec:
+ targetRef:
+ apiVersion: apps/v1
+ kind: Deployment
+ name: myapp
+ updatePolicy:
+ updateMode: "Off" # Recommendation only
+```
+
+**Auto mode (updates pods):**
+```yaml
+apiVersion: autoscaling.k8s.io/v1
+kind: VerticalPodAutoscaler
+metadata:
+ name: myapp-vpa
+ namespace: production
+spec:
+ targetRef:
+ apiVersion: apps/v1
+ kind: Deployment
+ name: myapp
+ updatePolicy:
+ updateMode: "Auto"
+ resourcePolicy:
+ containerPolicies:
+ - containerName: myapp
+ minAllowed:
+ cpu: 100m
+ memory: 128Mi
+ maxAllowed:
+ cpu: 2000m
+ memory: 4Gi
+ controlledResources: ["cpu", "memory"]
+```
+
+**Initial mode (sets resources on pod creation only):**
+```yaml
+apiVersion: autoscaling.k8s.io/v1
+kind: VerticalPodAutoscaler
+metadata:
+ name: myapp-vpa
+ namespace: production
+spec:
+ targetRef:
+ apiVersion: apps/v1
+ kind: Deployment
+ name: myapp
+ updatePolicy:
+ updateMode: "Initial"
+```
+
+### View VPA Recommendations
+
+```bash
+# Get VPA status
+kubectl get vpa myapp-vpa
+
+# Describe VPA for recommendations
+kubectl describe vpa myapp-vpa
+
+# View recommendations in YAML
+kubectl get vpa myapp-vpa -o yaml
+```
+
+**Example output:**
+```yaml
+recommendation:
+ containerRecommendations:
+ - containerName: myapp
+ lowerBound:
+ cpu: 150m
+ memory: 256Mi
+ target:
+ cpu: 200m
+ memory: 512Mi
+ uncappedTarget:
+ cpu: 250m
+ memory: 768Mi
+ upperBound:
+ cpu: 400m
+ memory: 1Gi
+```
+
+## Cluster Autoscaler
+
+### Cloud Provider Setup
+
+**AWS (EKS):**
+```yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: cluster-autoscaler
+ namespace: kube-system
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: cluster-autoscaler
+ template:
+ metadata:
+ labels:
+ app: cluster-autoscaler
+ spec:
+ serviceAccountName: cluster-autoscaler
+ containers:
+ - image: k8s.gcr.io/autoscaling/cluster-autoscaler:v1.27.0
+ name: cluster-autoscaler
+ command:
+ - ./cluster-autoscaler
+ - --v=4
+ - --stderrthreshold=info
+ - --cloud-provider=aws
+ - --skip-nodes-with-local-storage=false
+ - --expander=least-waste
+ - --node-group-auto-discovery=asg:tag=k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/my-cluster
+ - --balance-similar-node-groups
+ - --skip-nodes-with-system-pods=false
+```
+
+**GKE (automatically enabled):**
+```bash
+# Enable cluster autoscaler
+gcloud container clusters update my-cluster \
+ --enable-autoscaling \
+ --min-nodes=1 \
+ --max-nodes=10 \
+ --zone=us-central1-a
+```
+
+### Pod Disruption Budget (PDB)
+
+**Protect pods during scaling:**
+```yaml
+apiVersion: policy/v1
+kind: PodDisruptionBudget
+metadata:
+ name: myapp-pdb
+ namespace: production
+spec:
+ minAvailable: 2 # Or use maxUnavailable: 1
+ selector:
+ matchLabels:
+ app: myapp
+```
+
+**With percentage:**
+```yaml
+apiVersion: policy/v1
+kind: PodDisruptionBudget
+metadata:
+ name: myapp-pdb
+ namespace: production
+spec:
+ maxUnavailable: 25%
+ selector:
+ matchLabels:
+ app: myapp
+```
+
+## Scaling Best Practices
+
+### Resource Requests and Limits
+
+**Required for HPA:**
+```yaml
+resources:
+ requests:
+ cpu: 100m # HPA uses this for percentage calculation
+ memory: 128Mi
+ limits:
+ cpu: 500m
+ memory: 512Mi
+```
+
+### HPA Configuration
+
+**Recommended settings:**
+- `minReplicas`: 2+ for high availability
+- `maxReplicas`: 10-20x minReplicas
+- CPU target: 60-80% utilization
+- Memory target: 70-90% utilization
+- Scale-down stabilization: 300 seconds (5 minutes)
+- Scale-up stabilization: 0-60 seconds
+
+### Scaling Behavior
+
+**Conservative scaling:**
+```yaml
+behavior:
+ scaleDown:
+ stabilizationWindowSeconds: 300 # Wait 5 minutes before scaling down
+ policies:
+ - type: Percent
+ value: 25 # Scale down by max 25% at a time
+ periodSeconds: 60
+ scaleUp:
+ stabilizationWindowSeconds: 60
+ policies:
+ - type: Pods
+ value: 2 # Add max 2 pods at a time
+ periodSeconds: 30
+```
+
+**Aggressive scaling:**
+```yaml
+behavior:
+ scaleDown:
+ stabilizationWindowSeconds: 60
+ policies:
+ - type: Percent
+ value: 50
+ periodSeconds: 30
+ scaleUp:
+ stabilizationWindowSeconds: 0
+ policies:
+ - type: Percent
+ value: 100 # Double pods each time
+ periodSeconds: 15
+```
+
+### Anti-Patterns to Avoid
+
+1. **No resource requests** - HPA cannot calculate metrics
+2. **Too aggressive scaling** - Causes thrashing
+3. **VPA + HPA on same metric** - Conflicts
+4. **No PodDisruptionBudget** - Unsafe during scaling
+5. **Single replica minimum** - No high availability
+6. **No monitoring** - Cannot tune scaling
+
+## Scaling Strategies
+
+### Predictive Scaling
+
+**Schedule-based autoscaling (CronJob pattern):**
+```yaml
+apiVersion: batch/v1
+kind: CronJob
+metadata:
+ name: scale-up-morning
+ namespace: production
+spec:
+ schedule: "0 8 * * 1-5" # 8 AM Monday-Friday
+ jobTemplate:
+ spec:
+ template:
+ spec:
+ serviceAccountName: scaler
+ restartPolicy: OnFailure
+ containers:
+ - name: kubectl
+ image: bitnami/kubectl:latest
+ command:
+ - kubectl
+ - scale
+ - deployment/myapp
+ - --replicas=10
+---
+apiVersion: batch/v1
+kind: CronJob
+metadata:
+ name: scale-down-evening
+ namespace: production
+spec:
+ schedule: "0 18 * * 1-5" # 6 PM Monday-Friday
+ jobTemplate:
+ spec:
+ template:
+ spec:
+ serviceAccountName: scaler
+ restartPolicy: OnFailure
+ containers:
+ - name: kubectl
+ image: bitnami/kubectl:latest
+ command:
+ - kubectl
+ - scale
+ - deployment/myapp
+ - --replicas=3
+```
+
+### KEDA (Kubernetes Event-Driven Autoscaling)
+
+**Scale based on external metrics:**
+```yaml
+apiVersion: keda.sh/v1alpha1
+kind: ScaledObject
+metadata:
+ name: myapp-scaledobject
+ namespace: production
+spec:
+ scaleTargetRef:
+ name: myapp
+ minReplicaCount: 2
+ maxReplicaCount: 20
+ triggers:
+ # Scale based on Prometheus metric
+ - type: prometheus
+ metadata:
+ serverAddress: http://prometheus:9090
+ metricName: http_requests_per_second
+ threshold: '1000'
+ query: sum(rate(http_requests_total[2m]))
+ # Scale based on message queue
+ - type: rabbitmq
+ metadata:
+ queueName: tasks
+ queueLength: '50'
+ connectionFromEnv: RABBITMQ_URL
+```
+
+## Monitoring Scaling
+
+### Metrics to Track
+
+```bash
+# Current resource usage
+kubectl top pods -l app=myapp
+kubectl top nodes
+
+# HPA status
+kubectl get hpa myapp-hpa
+
+# Replica count over time
+kubectl get deployment myapp -w
+
+# Events
+kubectl get events --sort-by=.metadata.creationTimestamp | grep -i scale
+```
+
+### Prometheus Queries
+
+**Pod count:**
+```promql
+kube_deployment_status_replicas{deployment="myapp"}
+```
+
+**CPU utilization:**
+```promql
+rate(container_cpu_usage_seconds_total{pod=~"myapp-.*"}[5m])
+```
+
+**Memory usage:**
+```promql
+container_memory_usage_bytes{pod=~"myapp-.*"}
+```
+
+**HPA target metric:**
+```promql
+kube_horizontalpodautoscaler_status_current_replicas{horizontalpodautoscaler="myapp-hpa"}
+kube_horizontalpodautoscaler_status_desired_replicas{horizontalpodautoscaler="myapp-hpa"}
+```
+
+## Troubleshooting Scaling
+
+### HPA Not Scaling
+
+**Check metrics availability:**
+```bash
+kubectl get --raw /apis/metrics.k8s.io/v1beta1/nodes
+kubectl get --raw /apis/metrics.k8s.io/v1beta1/pods
+
+kubectl top nodes
+kubectl top pods -l app=myapp
+```
+
+**Check resource requests:**
+```bash
+kubectl get deployment myapp -o yaml | grep -A 5 resources
+```
+
+**Check HPA status:**
+```bash
+kubectl describe hpa myapp-hpa
+
+# Look for:
+# - Unable to get metrics
+# - Failed to compute desired number of replicas
+# - Resource requests not set
+```
+
+### VPA Not Working
+
+**Check VPA installation:**
+```bash
+kubectl get deployment -n kube-system | grep vpa
+```
+
+**Check VPA status:**
+```bash
+kubectl describe vpa myapp-vpa
+```
+
+### Cluster Autoscaler Issues
+
+**Check logs:**
+```bash
+kubectl logs -n kube-system -l app=cluster-autoscaler
+```
+
+**Check node status:**
+```bash
+kubectl get nodes
+kubectl describe nodes
+```
+
+## Scaling Checklist
+
+- [ ] Resource requests and limits defined
+- [ ] Metrics-server installed and working
+- [ ] HPA configured with appropriate thresholds
+- [ ] MinReplicas >= 2 for high availability
+- [ ] PodDisruptionBudget configured
+- [ ] Scaling behavior tuned for workload
+- [ ] Monitoring and alerting set up
+- [ ] Load testing performed
+- [ ] Cost implications considered
+- [ ] Documentation updated
dots/.config/claude/skills/Kubernetes/workflows/Security.md
@@ -0,0 +1,877 @@
+# Security Workflow
+
+Kubernetes security best practices including RBAC, Pod Security Standards, Network Policies, and cluster hardening.
+
+## When to Use
+
+- Setting up RBAC for applications or users
+- Implementing pod security controls
+- Creating network segmentation
+- Hardening cluster security
+- Security auditing and compliance
+
+## RBAC (Role-Based Access Control)
+
+### Core Concepts
+
+- **ServiceAccount**: Identity for pods
+- **Role**: Permissions within a namespace
+- **ClusterRole**: Cluster-wide permissions
+- **RoleBinding**: Binds Role to users/groups/ServiceAccounts in namespace
+- **ClusterRoleBinding**: Binds ClusterRole cluster-wide
+
+### Create ServiceAccount
+
+```yaml
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: myapp-sa
+ namespace: production
+```
+
+### Create Role (Namespace-scoped)
+
+```yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+ name: pod-reader
+ namespace: production
+rules:
+- apiGroups: [""]
+ resources: ["pods"]
+ verbs: ["get", "list", "watch"]
+- apiGroups: [""]
+ resources: ["pods/log"]
+ verbs: ["get"]
+```
+
+### Create ClusterRole (Cluster-wide)
+
+```yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: secret-reader
+rules:
+- apiGroups: [""]
+ resources: ["secrets"]
+ verbs: ["get", "list"]
+```
+
+### Create RoleBinding
+
+```yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+ name: read-pods
+ namespace: production
+subjects:
+- kind: ServiceAccount
+ name: myapp-sa
+ namespace: production
+roleRef:
+ kind: Role
+ name: pod-reader
+ apiGroup: rbac.authorization.k8s.io
+```
+
+### Create ClusterRoleBinding
+
+```yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: read-secrets-global
+subjects:
+- kind: ServiceAccount
+ name: myapp-sa
+ namespace: production
+roleRef:
+ kind: ClusterRole
+ name: secret-reader
+ apiGroup: rbac.authorization.k8s.io
+```
+
+### Common RBAC Patterns
+
+**Read-only access to pods:**
+```yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+ name: pod-reader
+ namespace: production
+rules:
+- apiGroups: [""]
+ resources: ["pods", "pods/log"]
+ verbs: ["get", "list", "watch"]
+```
+
+**Deployment manager:**
+```yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+ name: deployment-manager
+ namespace: production
+rules:
+- apiGroups: ["apps"]
+ resources: ["deployments", "replicasets"]
+ verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
+- apiGroups: [""]
+ resources: ["pods"]
+ verbs: ["get", "list", "watch"]
+```
+
+**ConfigMap and Secret manager:**
+```yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+ name: config-manager
+ namespace: production
+rules:
+- apiGroups: [""]
+ resources: ["configmaps", "secrets"]
+ verbs: ["get", "list", "create", "update", "patch"]
+```
+
+### Testing RBAC Permissions
+
+```bash
+# Check if current user can perform action
+kubectl auth can-i create deployments
+kubectl auth can-i get pods --namespace production
+
+# Check permissions for specific user
+kubectl auth can-i create deployments --as=user@example.com
+
+# Check permissions for ServiceAccount
+kubectl auth can-i list secrets --as=system:serviceaccount:production:myapp-sa
+
+# Check all permissions for current user
+kubectl auth can-i --list
+
+# Check permissions for ServiceAccount in namespace
+kubectl auth can-i --list --as=system:serviceaccount:production:myapp-sa -n production
+```
+
+### Using ServiceAccount in Pod
+
+```yaml
+apiVersion: v1
+kind: Pod
+metadata:
+ name: myapp
+ namespace: production
+spec:
+ serviceAccountName: myapp-sa
+ automountServiceAccountToken: true # Default: true
+ containers:
+ - name: myapp
+ image: myapp:1.0.0
+```
+
+## Pod Security Standards
+
+### Pod Security Levels
+
+1. **Privileged**: Unrestricted (for system components)
+2. **Baseline**: Minimally restrictive (prevents known privilege escalations)
+3. **Restricted**: Heavily restricted (security best practices)
+
+### Pod Security Admission
+
+**Namespace labels:**
+```yaml
+apiVersion: v1
+kind: Namespace
+metadata:
+ name: production
+ labels:
+ pod-security.kubernetes.io/enforce: restricted
+ pod-security.kubernetes.io/audit: restricted
+ pod-security.kubernetes.io/warn: restricted
+```
+
+### Secure Pod Template
+
+**Baseline security:**
+```yaml
+apiVersion: v1
+kind: Pod
+metadata:
+ name: secure-pod
+spec:
+ securityContext:
+ runAsNonRoot: true
+ runAsUser: 1000
+ fsGroup: 1000
+ containers:
+ - name: app
+ image: myapp:1.0.0
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+```
+
+**Restricted security (production):**
+```yaml
+apiVersion: v1
+kind: Pod
+metadata:
+ name: highly-secure-pod
+spec:
+ securityContext:
+ runAsNonRoot: true
+ runAsUser: 1000
+ fsGroup: 1000
+ seccompProfile:
+ type: RuntimeDefault
+ containers:
+ - name: app
+ image: myapp:1.0.0
+ securityContext:
+ allowPrivilegeEscalation: false
+ readOnlyRootFilesystem: true
+ runAsNonRoot: true
+ runAsUser: 1000
+ capabilities:
+ drop:
+ - ALL
+ volumeMounts:
+ - name: tmp
+ mountPath: /tmp
+ volumes:
+ - name: tmp
+ emptyDir: {}
+```
+
+### Security Context Fields
+
+**Pod-level:**
+- `runAsUser`: UID to run containers
+- `runAsGroup`: GID to run containers
+- `fsGroup`: Group for volume ownership
+- `runAsNonRoot`: Prevent running as root
+- `seccompProfile`: Seccomp profile
+- `seLinuxOptions`: SELinux options
+
+**Container-level:**
+- `allowPrivilegeEscalation`: Prevent privilege escalation
+- `readOnlyRootFilesystem`: Read-only root filesystem
+- `runAsNonRoot`: Prevent running as root
+- `runAsUser`: Override pod-level UID
+- `capabilities`: Linux capabilities
+- `seccompProfile`: Seccomp profile
+
+## Network Policies
+
+### Default Deny All Traffic
+
+**IMPORTANT: Apply this first, then whitelist allowed traffic**
+
+```yaml
+apiVersion: networking.k8s.io/v1
+kind: NetworkPolicy
+metadata:
+ name: default-deny-all
+ namespace: production
+spec:
+ podSelector: {}
+ policyTypes:
+ - Ingress
+ - Egress
+```
+
+### Allow Ingress from Specific Pods
+
+```yaml
+apiVersion: networking.k8s.io/v1
+kind: NetworkPolicy
+metadata:
+ name: allow-from-frontend
+ namespace: production
+spec:
+ podSelector:
+ matchLabels:
+ app: backend
+ policyTypes:
+ - Ingress
+ ingress:
+ - from:
+ - podSelector:
+ matchLabels:
+ app: frontend
+ ports:
+ - protocol: TCP
+ port: 8080
+```
+
+### Allow Ingress from Specific Namespace
+
+```yaml
+apiVersion: networking.k8s.io/v1
+kind: NetworkPolicy
+metadata:
+ name: allow-from-monitoring
+ namespace: production
+spec:
+ podSelector:
+ matchLabels:
+ app: backend
+ policyTypes:
+ - Ingress
+ ingress:
+ - from:
+ - namespaceSelector:
+ matchLabels:
+ name: monitoring
+ ports:
+ - protocol: TCP
+ port: 8080
+```
+
+### Allow Egress to Specific Services
+
+```yaml
+apiVersion: networking.k8s.io/v1
+kind: NetworkPolicy
+metadata:
+ name: allow-egress-to-database
+ namespace: production
+spec:
+ podSelector:
+ matchLabels:
+ app: backend
+ policyTypes:
+ - Egress
+ egress:
+ - to:
+ - podSelector:
+ matchLabels:
+ app: postgres
+ ports:
+ - protocol: TCP
+ port: 5432
+```
+
+### Allow DNS and External HTTPS
+
+```yaml
+apiVersion: networking.k8s.io/v1
+kind: NetworkPolicy
+metadata:
+ name: allow-dns-and-https
+ namespace: production
+spec:
+ podSelector:
+ matchLabels:
+ app: backend
+ policyTypes:
+ - Egress
+ egress:
+ # Allow DNS
+ - to:
+ - namespaceSelector:
+ matchLabels:
+ name: kube-system
+ podSelector:
+ matchLabels:
+ k8s-app: kube-dns
+ ports:
+ - protocol: UDP
+ port: 53
+ # Allow external HTTPS
+ - to:
+ - ipBlock:
+ cidr: 0.0.0.0/0
+ except:
+ - 169.254.169.254/32 # Block metadata service
+ ports:
+ - protocol: TCP
+ port: 443
+```
+
+### Complete Network Policy Example
+
+```yaml
+apiVersion: networking.k8s.io/v1
+kind: NetworkPolicy
+metadata:
+ name: backend-network-policy
+ namespace: production
+spec:
+ podSelector:
+ matchLabels:
+ app: backend
+ policyTypes:
+ - Ingress
+ - Egress
+ ingress:
+ # Allow from frontend
+ - from:
+ - podSelector:
+ matchLabels:
+ app: frontend
+ ports:
+ - protocol: TCP
+ port: 8080
+ # Allow from ingress controller
+ - from:
+ - namespaceSelector:
+ matchLabels:
+ name: ingress-nginx
+ ports:
+ - protocol: TCP
+ port: 8080
+ egress:
+ # Allow to database
+ - to:
+ - podSelector:
+ matchLabels:
+ app: postgres
+ ports:
+ - protocol: TCP
+ port: 5432
+ # Allow to Redis
+ - to:
+ - podSelector:
+ matchLabels:
+ app: redis
+ ports:
+ - protocol: TCP
+ port: 6379
+ # Allow DNS
+ - to:
+ - namespaceSelector:
+ matchLabels:
+ name: kube-system
+ podSelector:
+ matchLabels:
+ k8s-app: kube-dns
+ ports:
+ - protocol: UDP
+ port: 53
+```
+
+## Secrets Management
+
+### Best Practices
+
+1. **Never commit secrets to Git**
+2. **Use volume mounts instead of environment variables**
+3. **Enable encryption at rest**
+4. **Use external secret management (Vault, AWS Secrets Manager)**
+5. **Rotate secrets regularly**
+6. **Limit secret access with RBAC**
+
+### Using Secrets Securely
+
+**BAD - Environment variables:**
+```yaml
+# Secrets visible in pod spec and logs
+env:
+- name: API_KEY
+ valueFrom:
+ secretKeyRef:
+ name: myapp-secret
+ key: api_key
+```
+
+**GOOD - Volume mounts:**
+```yaml
+volumeMounts:
+- name: secrets
+ mountPath: /etc/secrets
+ readOnly: true
+volumes:
+- name: secrets
+ secret:
+ secretName: myapp-secret
+ defaultMode: 0400
+```
+
+### External Secrets Operator
+
+**CRD for syncing external secrets:**
+```yaml
+apiVersion: external-secrets.io/v1beta1
+kind: SecretStore
+metadata:
+ name: aws-secrets-manager
+ namespace: production
+spec:
+ provider:
+ aws:
+ service: SecretsManager
+ region: us-east-1
+ auth:
+ jwt:
+ serviceAccountRef:
+ name: external-secrets-sa
+---
+apiVersion: external-secrets.io/v1beta1
+kind: ExternalSecret
+metadata:
+ name: myapp-secret
+ namespace: production
+spec:
+ refreshInterval: 1h
+ secretStoreRef:
+ name: aws-secrets-manager
+ kind: SecretStore
+ target:
+ name: myapp-secret
+ creationPolicy: Owner
+ data:
+ - secretKey: api_key
+ remoteRef:
+ key: prod/myapp/api_key
+```
+
+### Sealed Secrets
+
+**Encrypt secrets for Git storage:**
+```bash
+# Install kubeseal
+# On NixOS: pkgs.kubeseal
+
+# Encrypt secret
+kubectl create secret generic myapp-secret \
+ --from-literal=api_key=supersecret \
+ --dry-run=client -o yaml | \
+ kubeseal -o yaml > sealed-secret.yaml
+
+# Commit sealed-secret.yaml to Git
+git add sealed-secret.yaml
+
+# Apply (controller decrypts)
+kubectl apply -f sealed-secret.yaml
+```
+
+## Image Security
+
+### Use Specific Tags
+
+**BAD:**
+```yaml
+image: nginx:latest
+```
+
+**GOOD:**
+```yaml
+image: nginx:1.25.3-alpine
+```
+
+### Image Pull Policies
+
+```yaml
+spec:
+ containers:
+ - name: app
+ image: myapp:1.0.0
+ imagePullPolicy: IfNotPresent # Or Always, Never
+```
+
+**Policies:**
+- `IfNotPresent`: Pull if not cached (default for tagged images)
+- `Always`: Always pull (default for :latest)
+- `Never`: Never pull, must be cached
+
+### Private Registry Authentication
+
+```bash
+# Create docker-registry secret
+kubectl create secret docker-registry regcred \
+ --docker-server=myregistry.com \
+ --docker-username=user \
+ --docker-password=pass \
+ --docker-email=user@example.com
+```
+
+```yaml
+spec:
+ imagePullSecrets:
+ - name: regcred
+```
+
+### Image Scanning
+
+**Trivy (vulnerability scanner):**
+```bash
+# Scan image
+trivy image myapp:1.0.0
+
+# Scan with severity threshold
+trivy image --severity HIGH,CRITICAL myapp:1.0.0
+
+# Scan Kubernetes manifests
+trivy config deployment.yaml
+```
+
+## Cluster Hardening
+
+### API Server Security
+
+**Recommended flags:**
+```yaml
+- --anonymous-auth=false
+- --enable-admission-plugins=NodeRestriction,PodSecurityPolicy
+- --audit-log-path=/var/log/audit.log
+- --audit-log-maxage=30
+- --enable-bootstrap-token-auth=false
+- --insecure-port=0
+```
+
+### Enable Audit Logging
+
+```yaml
+apiVersion: audit.k8s.io/v1
+kind: Policy
+rules:
+- level: Metadata
+ resources:
+ - group: ""
+ resources: ["secrets", "configmaps"]
+- level: RequestResponse
+ resources:
+ - group: ""
+ resources: ["pods"]
+ verbs: ["create", "update", "patch", "delete"]
+```
+
+### Kubelet Security
+
+**Recommended flags:**
+```
+--anonymous-auth=false
+--authorization-mode=Webhook
+--read-only-port=0
+--protect-kernel-defaults=true
+```
+
+## Security Scanning and Compliance
+
+### kube-bench (CIS Benchmark)
+
+```bash
+# Run CIS Kubernetes benchmark
+kubectl apply -f https://raw.githubusercontent.com/aquasecurity/kube-bench/main/job.yaml
+
+# View results
+kubectl logs -l app=kube-bench
+```
+
+### kube-hunter (Penetration Testing)
+
+```bash
+# Run security assessment
+kubectl apply -f https://raw.githubusercontent.com/aquasecurity/kube-hunter/main/job.yaml
+
+# View results
+kubectl logs -l app=kube-hunter
+```
+
+### Falco (Runtime Security)
+
+**Detect anomalous activity:**
+```yaml
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: falco-rules
+ namespace: falco
+data:
+ custom-rules.yaml: |
+ - rule: Unauthorized Process in Container
+ desc: Detect unauthorized process execution
+ condition: spawned_process and container and not proc.name in (allowed_processes)
+ output: Unauthorized process in container (user=%user.name command=%proc.cmdline)
+ priority: WARNING
+```
+
+## Security Checklist
+
+### Pod Security
+- [ ] Run as non-root user (`runAsNonRoot: true`)
+- [ ] Use read-only root filesystem (`readOnlyRootFilesystem: true`)
+- [ ] Drop all capabilities (`capabilities.drop: [ALL]`)
+- [ ] Disable privilege escalation (`allowPrivilegeEscalation: false`)
+- [ ] Set seccomp profile (`seccompProfile.type: RuntimeDefault`)
+- [ ] Define resource limits
+- [ ] Use specific image tags (not :latest)
+
+### RBAC
+- [ ] Use ServiceAccounts for applications
+- [ ] Follow principle of least privilege
+- [ ] Use Role instead of ClusterRole when possible
+- [ ] Regularly audit RBAC permissions
+- [ ] Disable auto-mounting of ServiceAccount tokens if not needed
+
+### Network Security
+- [ ] Implement default-deny network policies
+- [ ] Whitelist required traffic only
+- [ ] Segment namespaces with network policies
+- [ ] Use TLS for in-cluster communication
+- [ ] Block access to cloud metadata service
+
+### Secrets
+- [ ] Use external secret management (Vault, AWS Secrets Manager)
+- [ ] Mount secrets as volumes, not environment variables
+- [ ] Enable encryption at rest for secrets
+- [ ] Rotate secrets regularly
+- [ ] Limit secret access with RBAC
+
+### Cluster Hardening
+- [ ] Enable audit logging
+- [ ] Disable anonymous authentication
+- [ ] Use Pod Security Standards
+- [ ] Keep Kubernetes version up to date
+- [ ] Run CIS benchmark (kube-bench)
+- [ ] Implement admission controllers
+- [ ] Use private nodes (no public IPs)
+
+### Image Security
+- [ ] Scan images for vulnerabilities
+- [ ] Use minimal base images (alpine, distroless)
+- [ ] Use specific image tags
+- [ ] Sign and verify images
+- [ ] Use private registry with authentication
+
+### Monitoring
+- [ ] Enable audit logs
+- [ ] Monitor with Falco or similar
+- [ ] Set up alerts for security events
+- [ ] Regularly review logs
+- [ ] Implement intrusion detection
+
+## Example: Secure Application Deployment
+
+```yaml
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: secure-app
+ namespace: production
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+ name: secure-app-role
+ namespace: production
+rules:
+- apiGroups: [""]
+ resources: ["configmaps"]
+ resourceNames: ["app-config"]
+ verbs: ["get"]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+ name: secure-app-binding
+ namespace: production
+subjects:
+- kind: ServiceAccount
+ name: secure-app
+ namespace: production
+roleRef:
+ kind: Role
+ name: secure-app-role
+ apiGroup: rbac.authorization.k8s.io
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: secure-app
+ namespace: production
+spec:
+ replicas: 3
+ selector:
+ matchLabels:
+ app: secure-app
+ template:
+ metadata:
+ labels:
+ app: secure-app
+ spec:
+ serviceAccountName: secure-app
+ automountServiceAccountToken: true
+ securityContext:
+ runAsNonRoot: true
+ runAsUser: 1000
+ fsGroup: 1000
+ seccompProfile:
+ type: RuntimeDefault
+ containers:
+ - name: app
+ image: myregistry.com/secure-app:1.0.0
+ imagePullPolicy: IfNotPresent
+ securityContext:
+ allowPrivilegeEscalation: false
+ readOnlyRootFilesystem: true
+ runAsNonRoot: true
+ runAsUser: 1000
+ capabilities:
+ drop:
+ - ALL
+ resources:
+ requests:
+ cpu: 100m
+ memory: 128Mi
+ limits:
+ cpu: 500m
+ memory: 512Mi
+ volumeMounts:
+ - name: tmp
+ mountPath: /tmp
+ - name: secrets
+ mountPath: /etc/secrets
+ readOnly: true
+ volumes:
+ - name: tmp
+ emptyDir: {}
+ - name: secrets
+ secret:
+ secretName: app-secret
+ defaultMode: 0400
+ imagePullSecrets:
+ - name: regcred
+---
+apiVersion: networking.k8s.io/v1
+kind: NetworkPolicy
+metadata:
+ name: secure-app-netpol
+ namespace: production
+spec:
+ podSelector:
+ matchLabels:
+ app: secure-app
+ policyTypes:
+ - Ingress
+ - Egress
+ ingress:
+ - from:
+ - podSelector:
+ matchLabels:
+ app: frontend
+ ports:
+ - protocol: TCP
+ port: 8080
+ egress:
+ - to:
+ - namespaceSelector:
+ matchLabels:
+ name: kube-system
+ podSelector:
+ matchLabels:
+ k8s-app: kube-dns
+ ports:
+ - protocol: UDP
+ port: 53
+```
dots/.config/claude/skills/Kubernetes/SKILL.md
@@ -0,0 +1,225 @@
+---
+name: Kubernetes
+description: Kubernetes development and operations best practices. USE WHEN working with kubectl commands, K8s manifests, deployments, debugging pods, managing resources, RBAC, or cluster operations.
+---
+
+# Kubernetes
+
+Expert guidance on Kubernetes operations, kubectl command-line usage, and cloud-native development best practices.
+
+## Workflow Routing
+
+**When executing a workflow, output this notification directly:**
+
+```
+Running the **WorkflowName** workflow from the **Kubernetes** skill...
+```
+
+| Workflow | Trigger | File |
+|----------|---------|------|
+| **Debug** | "debug pod", "troubleshoot", "pod logs", "pod errors" | `workflows/Debug.md` |
+| **Deploy** | "deploy", "apply manifests", "rollout", "update deployment" | `workflows/Deploy.md` |
+| **Context** | "kubectl context", "namespace", "switch cluster" | `workflows/Context.md` |
+| **Resources** | "create resource", "manifest", "yaml", "configmap", "secret" | `workflows/Resources.md` |
+| **Security** | "RBAC", "pod security", "network policy", "security best practices" | `workflows/Security.md` |
+| **Scaling** | "scale deployment", "HPA", "autoscaling", "replicas" | `workflows/Scaling.md` |
+
+## kubectl Productivity
+
+### Essential Aliases
+
+```bash
+alias k=kubectl
+alias kgp='kubectl get pods'
+alias kgs='kubectl get svc'
+alias kgd='kubectl get deployments'
+alias kgn='kubectl get nodes'
+alias kdp='kubectl describe pod'
+alias kdd='kubectl describe deployment'
+alias kl='kubectl logs'
+alias kx='kubectl exec -it'
+alias kaf='kubectl apply -f'
+alias kdel='kubectl delete'
+```
+
+### Quick Commands
+
+**Get resources with custom output:**
+```bash
+kubectl get pods -o wide
+kubectl get pods -o yaml
+kubectl get pods -o json | jq '.items[].metadata.name'
+kubectl get pods --sort-by=.metadata.creationTimestamp
+```
+
+**Watch resources:**
+```bash
+kubectl get pods -w
+kubectl get events -w
+```
+
+**Context and namespace:**
+```bash
+kubectl config get-contexts
+kubectl config use-context <context>
+kubectl config set-context --current --namespace=<namespace>
+```
+
+## Key Best Practices
+
+### Resource Definitions
+
+**Always specify:**
+- Resource limits and requests
+- Readiness and liveness probes
+- Labels and selectors
+- Pod disruption budgets for production
+- Security context (non-root user, read-only filesystem)
+
+**Example deployment manifest:**
+```yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: myapp
+ labels:
+ app: myapp
+ version: v1.0.0
+spec:
+ replicas: 3
+ selector:
+ matchLabels:
+ app: myapp
+ template:
+ metadata:
+ labels:
+ app: myapp
+ version: v1.0.0
+ spec:
+ securityContext:
+ runAsNonRoot: true
+ runAsUser: 1000
+ fsGroup: 1000
+ containers:
+ - name: myapp
+ image: myapp:v1.0.0
+ ports:
+ - containerPort: 8080
+ resources:
+ requests:
+ cpu: 100m
+ memory: 128Mi
+ limits:
+ cpu: 500m
+ memory: 512Mi
+ livenessProbe:
+ httpGet:
+ path: /healthz
+ port: 8080
+ initialDelaySeconds: 30
+ periodSeconds: 10
+ readinessProbe:
+ httpGet:
+ path: /ready
+ port: 8080
+ initialDelaySeconds: 5
+ periodSeconds: 5
+ securityContext:
+ allowPrivilegeEscalation: false
+ readOnlyRootFilesystem: true
+ volumeMounts:
+ - name: tmp
+ mountPath: /tmp
+ volumes:
+ - name: tmp
+ emptyDir: {}
+```
+
+### Recommended Labels
+
+```yaml
+metadata:
+ labels:
+ app.kubernetes.io/name: myapp
+ app.kubernetes.io/instance: myapp-prod
+ app.kubernetes.io/version: "1.0.0"
+ app.kubernetes.io/component: backend
+ app.kubernetes.io/part-of: myplatform
+ app.kubernetes.io/managed-by: kubectl
+```
+
+### Anti-Patterns to Avoid
+
+1. **NEVER use `:latest` tag** - Always use specific version tags
+2. **NEVER skip health probes** - Always define readiness/liveness probes
+3. **NEVER run as root** - Use non-root user in security context
+4. **NEVER hardcode configuration** - Use ConfigMaps and Secrets
+5. **NEVER ignore resource limits** - Always set requests and limits
+6. **NEVER use default namespace** - Create and use specific namespaces
+7. **NEVER skip labels** - Use consistent labeling strategy
+8. **NEVER deploy without testing** - Use `kubectl apply --dry-run=client`
+9. **NEVER expose secrets in env** - Use volume mounts for secrets
+10. **NEVER skip RBAC** - Use principle of least privilege
+
+## Security Checklist
+
+- [ ] Run containers as non-root user
+- [ ] Use read-only root filesystem
+- [ ] Drop all capabilities, add only required ones
+- [ ] Enable Pod Security Standards (Baseline or Restricted)
+- [ ] Use Network Policies to restrict traffic
+- [ ] Scan images for vulnerabilities
+- [ ] Use secrets for sensitive data (never in env vars directly)
+- [ ] Enable RBAC with least privilege
+- [ ] Use service accounts per application
+- [ ] Enable audit logging
+
+## Debugging Workflow
+
+1. **Check pod status:** `kubectl get pods`
+2. **Describe pod:** `kubectl describe pod <pod-name>`
+3. **View logs:** `kubectl logs <pod-name> [-c <container>]`
+4. **Previous logs:** `kubectl logs <pod-name> --previous`
+5. **Exec into pod:** `kubectl exec -it <pod-name> -- /bin/sh`
+6. **Check events:** `kubectl get events --sort-by=.metadata.creationTimestamp`
+7. **Port forward:** `kubectl port-forward pod/<pod-name> 8080:8080`
+
+## Examples
+
+**Example 1: Debug failing pod**
+```
+User: "My pod is in CrashLoopBackOff, help me debug it"
+→ Invokes Debug workflow
+→ Checks pod status and events
+→ Reviews logs for errors
+→ Validates resource definitions
+→ Identifies root cause and suggests fix
+```
+
+**Example 2: Deploy application**
+```
+User: "Deploy my application to Kubernetes with best practices"
+→ Invokes Deploy workflow
+→ Creates manifest with security contexts
+→ Adds health probes and resource limits
+→ Validates with dry-run
+→ Applies and monitors rollout
+```
+
+**Example 3: Set up RBAC**
+```
+User: "Create RBAC for my application with minimal permissions"
+→ Invokes Security workflow
+→ Creates ServiceAccount
+→ Defines Role with specific permissions
+→ Creates RoleBinding
+→ Tests permissions
+```
+
+## Integration
+
+This skill integrates with:
+- **Git skill**: For version controlling manifests and GitOps workflows
+- **Golang skill**: For developing Kubernetes operators and controllers
+- **Nix skill**: For managing Kubernetes tools in NixOS environments
+- **Homelab skill**: For managing K3s/K8s clusters in homelab setup