This commit is contained in:
Toby
2026-01-27 17:35:45 -05:00
commit 2639af6531
176 changed files with 27104 additions and 0 deletions
@@ -0,0 +1,516 @@
---
name: kubernetes-ops
description: Deploy, scale, and manage Kubernetes workloads. Create deployments, services, and configurations, manage cluster resources, troubleshoot pods, and implement production-ready Kubernetes patterns. Use when working with Kubernetes clusters, K8s deployments, or container orchestration.
license: MIT
metadata:
author: devops-skills
version: "1.0"
---
# Kubernetes Operations
Deploy and manage containerized applications on Kubernetes clusters.
## When to Use This Skill
Use this skill when:
- Deploying applications to Kubernetes
- Managing pods, deployments, and services
- Configuring resource limits and scaling
- Troubleshooting Kubernetes workloads
- Setting up networking and ingress
## Prerequisites
- kubectl installed and configured
- Access to a Kubernetes cluster
- Basic understanding of containers
## Core Resources
### Deployment
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
labels:
app: myapp
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:1.0.0
ports:
- containerPort: 8080
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: myapp-secrets
key: database-url
```
### Service
```yaml
apiVersion: v1
kind: Service
metadata:
name: myapp
spec:
selector:
app: myapp
ports:
- port: 80
targetPort: 8080
type: ClusterIP
---
# LoadBalancer for external access
apiVersion: v1
kind: Service
metadata:
name: myapp-external
spec:
selector:
app: myapp
ports:
- port: 80
targetPort: 8080
type: LoadBalancer
```
### Ingress
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
tls:
- hosts:
- myapp.example.com
secretName: myapp-tls
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp
port:
number: 80
```
## Configuration Management
### ConfigMap
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: myapp-config
data:
config.yaml: |
server:
port: 8080
logging:
level: info
APP_ENV: production
```
```yaml
# Using ConfigMap
containers:
- name: myapp
envFrom:
- configMapRef:
name: myapp-config
volumeMounts:
- name: config
mountPath: /etc/config
volumes:
- name: config
configMap:
name: myapp-config
```
### Secret
```yaml
apiVersion: v1
kind: Secret
metadata:
name: myapp-secrets
type: Opaque
stringData:
database-url: postgres://user:pass@host:5432/db
api-key: secret-key-value
```
```bash
# Create secret from command line
kubectl create secret generic myapp-secrets \
--from-literal=database-url='postgres://...' \
--from-file=tls.crt=cert.pem
```
## kubectl Commands
### Resource Management
```bash
# Apply configuration
kubectl apply -f deployment.yaml
# Get resources
kubectl get pods
kubectl get deployments
kubectl get services
kubectl get all -n myapp
# Describe resource
kubectl describe pod myapp-xxx
# Delete resource
kubectl delete -f deployment.yaml
kubectl delete pod myapp-xxx
# Edit resource
kubectl edit deployment myapp
```
### Debugging
```bash
# View logs
kubectl logs myapp-xxx
kubectl logs -f myapp-xxx --tail=100
kubectl logs myapp-xxx -c sidecar # specific container
# Execute command
kubectl exec -it myapp-xxx -- /bin/sh
# Port forward
kubectl port-forward svc/myapp 8080:80
kubectl port-forward pod/myapp-xxx 8080:8080
# View events
kubectl get events --sort-by='.lastTimestamp'
# Debug pod
kubectl debug myapp-xxx -it --image=busybox
```
### Scaling
```bash
# Manual scaling
kubectl scale deployment myapp --replicas=5
# Autoscaling
kubectl autoscale deployment myapp \
--min=2 --max=10 \
--cpu-percent=80
```
## Horizontal Pod Autoscaler
```yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: myapp
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: myapp
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 80
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
```
## Persistent Storage
### PersistentVolumeClaim
```yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: myapp-data
spec:
accessModes:
- ReadWriteOnce
storageClassName: standard
resources:
requests:
storage: 10Gi
---
# Using PVC
containers:
- name: myapp
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: myapp-data
```
## StatefulSet
```yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
spec:
serviceName: postgres
replicas: 3
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:15
ports:
- containerPort: 5432
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
```
## Jobs and CronJobs
### Job
```yaml
apiVersion: batch/v1
kind: Job
metadata:
name: migration
spec:
template:
spec:
containers:
- name: migrate
image: myapp:1.0.0
command: ["./migrate.sh"]
restartPolicy: Never
backoffLimit: 3
```
### CronJob
```yaml
apiVersion: batch/v1
kind: CronJob
metadata:
name: backup
spec:
schedule: "0 2 * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: backup-tool:latest
command: ["./backup.sh"]
restartPolicy: OnFailure
```
## Network Policies
```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: myapp-network-policy
spec:
podSelector:
matchLabels:
app: myapp
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
egress:
- to:
- podSelector:
matchLabels:
app: database
ports:
- protocol: TCP
port: 5432
```
## Resource Quotas
```yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: myapp-quota
namespace: myapp
spec:
hard:
requests.cpu: "10"
requests.memory: 20Gi
limits.cpu: "20"
limits.memory: 40Gi
pods: "20"
```
## Rolling Updates
```yaml
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
```
```bash
# Update image
kubectl set image deployment/myapp myapp=myapp:2.0.0
# Check rollout status
kubectl rollout status deployment/myapp
# View history
kubectl rollout history deployment/myapp
# Rollback
kubectl rollout undo deployment/myapp
kubectl rollout undo deployment/myapp --to-revision=2
```
## Common Issues
### Issue: Pod Stuck in Pending
**Problem**: Pod won't start
**Solution**: Check resource availability, node selector, PVC binding
```bash
kubectl describe pod myapp-xxx
kubectl get events
```
### Issue: CrashLoopBackOff
**Problem**: Container keeps restarting
**Solution**: Check logs, verify entrypoint, check probes
```bash
kubectl logs myapp-xxx --previous
kubectl describe pod myapp-xxx
```
### Issue: Service Not Accessible
**Problem**: Cannot connect to service
**Solution**: Check selector labels, verify endpoints exist
```bash
kubectl get endpoints myapp
kubectl describe svc myapp
```
### Issue: Image Pull Error
**Problem**: ImagePullBackOff
**Solution**: Check image name, verify registry credentials
```bash
kubectl create secret docker-registry regcred \
--docker-server=registry.example.com \
--docker-username=user \
--docker-password=pass
```
## Best Practices
- Always set resource requests and limits
- Implement liveness and readiness probes
- Use namespaces for isolation
- Apply network policies for security
- Use ConfigMaps and Secrets for configuration
- Implement pod disruption budgets for availability
- Use labels consistently for organization
- Enable RBAC for access control
## Related Skills
- [helm-charts](../helm-charts/) - Package management
- [argocd-gitops](../argocd-gitops/) - GitOps deployments
- [kubernetes-hardening](../../../security/hardening/kubernetes-hardening/) - Security
@@ -0,0 +1,166 @@
# Production-Ready Deployment Template
# Customize values marked with <REPLACE>
apiVersion: apps/v1
kind: Deployment
metadata:
name: <APP_NAME>
labels:
app: <APP_NAME>
version: v1
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app: <APP_NAME>
template:
metadata:
labels:
app: <APP_NAME>
version: v1
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8080"
prometheus.io/path: "/metrics"
spec:
serviceAccountName: <APP_NAME>
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: <APP_NAME>
topologyKey: kubernetes.io/hostname
containers:
- name: <APP_NAME>
image: <IMAGE>:<TAG>
imagePullPolicy: Always
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: <APP_NAME>-config
- secretRef:
name: <APP_NAME>-secrets
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
securityContext:
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
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
volumeMounts:
- name: tmp
mountPath: /tmp
- name: cache
mountPath: /var/cache
volumes:
- name: tmp
emptyDir: {}
- name: cache
emptyDir: {}
terminationGracePeriodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:
name: <APP_NAME>
labels:
app: <APP_NAME>
spec:
type: ClusterIP
ports:
- port: 80
targetPort: http
protocol: TCP
name: http
selector:
app: <APP_NAME>
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: <APP_NAME>
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: <APP_NAME>
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: <APP_NAME>
spec:
minAvailable: 2
selector:
matchLabels:
app: <APP_NAME>
@@ -0,0 +1,187 @@
# Kubernetes Best Practices
## Resource Management
### Always Set Resource Requests and Limits
```yaml
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
```
**Guidelines:**
- Requests = guaranteed resources
- Limits = maximum resources
- Set requests based on normal usage
- Set limits based on peak usage
- Memory limit = 2x request is common
- Avoid CPU limits in most cases (causes throttling)
### Use Horizontal Pod Autoscaler
```yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: myapp-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: myapp
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
```
## Pod Configuration
### Use Liveness and Readiness Probes
```yaml
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
```
### Configure Pod Disruption Budgets
```yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: myapp-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: myapp
```
### Use Anti-Affinity for High Availability
```yaml
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: myapp
topologyKey: kubernetes.io/hostname
```
## Security
### Run as Non-Root
```yaml
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
```
### Read-Only Root Filesystem
```yaml
securityContext:
readOnlyRootFilesystem: true
volumeMounts:
- name: tmp
mountPath: /tmp
volumes:
- name: tmp
emptyDir: {}
```
### Drop All Capabilities
```yaml
securityContext:
capabilities:
drop:
- ALL
```
## Networking
### Use Network Policies
```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
```
### Service Mesh for mTLS
- Istio, Linkerd, or Consul Connect
- Automatic encryption between services
- Traffic management capabilities
## Configuration Management
### Use ConfigMaps for Configuration
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
LOG_LEVEL: "info"
DATABASE_HOST: "postgres.default.svc"
```
### Use Secrets for Sensitive Data
```yaml
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
type: Opaque
stringData:
DATABASE_PASSWORD: "secret123"
```
### External Secrets for Production
- Use External Secrets Operator
- Integrate with Vault, AWS Secrets Manager, etc.
- Never commit secrets to git
## Observability
### Structured Logging
- Output JSON logs
- Include correlation IDs
- Use consistent field names
### Metrics
- Expose Prometheus metrics
- Use standard naming conventions
- Include SLI metrics
### Distributed Tracing
- Implement OpenTelemetry
- Propagate trace context
- Sample appropriately
@@ -0,0 +1,165 @@
# Kubernetes Troubleshooting Guide
## Common Issues and Solutions
### Pod Issues
#### Pod Stuck in Pending
```bash
# Check events
kubectl describe pod <pod-name> -n <namespace>
# Common causes:
# - Insufficient resources
kubectl describe nodes | grep -A 5 "Allocated resources"
# - No matching nodes (taints/tolerations)
kubectl get nodes -o json | jq '.items[].spec.taints'
# - PVC not bound
kubectl get pvc -n <namespace>
```
#### Pod in CrashLoopBackOff
```bash
# Check logs
kubectl logs <pod-name> -n <namespace> --previous
# Check container exit code
kubectl get pod <pod-name> -n <namespace> -o jsonpath='{.status.containerStatuses[0].lastState.terminated.exitCode}'
# Common exit codes:
# 0 - Success (check livenessProbe)
# 1 - Application error
# 137 - OOMKilled (increase memory)
# 139 - Segmentation fault
# 143 - SIGTERM received
```
#### Pod in ImagePullBackOff
```bash
# Check image name
kubectl get pod <pod-name> -n <namespace> -o jsonpath='{.spec.containers[0].image}'
# Verify image exists
docker pull <image>
# Check imagePullSecrets
kubectl get pod <pod-name> -n <namespace> -o jsonpath='{.spec.imagePullSecrets}'
kubectl get secret <secret-name> -n <namespace> -o jsonpath='{.data.\.dockerconfigjson}' | base64 -d
```
### Service Issues
#### Service Not Accessible
```bash
# Verify endpoints exist
kubectl get endpoints <service-name> -n <namespace>
# Check selector matches pod labels
kubectl get svc <service-name> -n <namespace> -o jsonpath='{.spec.selector}'
kubectl get pods -n <namespace> --show-labels
# Test from within cluster
kubectl run debug --rm -it --image=busybox -- wget -qO- http://<service>.<namespace>.svc.cluster.local
```
#### DNS Resolution Issues
```bash
# Test DNS from pod
kubectl run dns-test --rm -it --image=busybox -- nslookup kubernetes.default
# Check CoreDNS pods
kubectl get pods -n kube-system -l k8s-app=kube-dns
# Check CoreDNS logs
kubectl logs -n kube-system -l k8s-app=kube-dns
```
### Node Issues
#### Node NotReady
```bash
# Check node conditions
kubectl describe node <node-name> | grep -A 20 Conditions
# Check kubelet status
systemctl status kubelet
# Check kubelet logs
journalctl -u kubelet -f
# Common causes:
# - Disk pressure
# - Memory pressure
# - Network issues
# - Container runtime issues
```
#### Node Disk Pressure
```bash
# Check disk usage
kubectl describe node <node-name> | grep -A 3 "Allocated resources"
# Cleanup unused images
docker system prune -af
# Check for large logs
du -sh /var/log/containers/*
```
### Networking Issues
#### Pod-to-Pod Communication Fails
```bash
# Test connectivity
kubectl exec <pod-a> -- ping <pod-b-ip>
# Check network policies
kubectl get networkpolicies -n <namespace>
# Verify CNI plugin
kubectl get pods -n kube-system | grep -E "calico|weave|flannel|cilium"
```
### Storage Issues
#### PVC Stuck in Pending
```bash
# Check PVC events
kubectl describe pvc <pvc-name> -n <namespace>
# Verify StorageClass exists
kubectl get storageclass
# Check provisioner pods
kubectl get pods -n kube-system | grep provisioner
```
## Diagnostic Commands Cheat Sheet
```bash
# Cluster overview
kubectl cluster-info
kubectl get componentstatuses
# Resource usage
kubectl top nodes
kubectl top pods -n <namespace>
# Events
kubectl get events -n <namespace> --sort-by='.lastTimestamp'
# Logs
kubectl logs -f <pod> -n <namespace>
kubectl logs -f <pod> -n <namespace> --all-containers
# Exec into pod
kubectl exec -it <pod> -n <namespace> -- /bin/sh
# Port forward
kubectl port-forward <pod> 8080:80 -n <namespace>
# Copy files
kubectl cp <namespace>/<pod>:/path/to/file ./local-file
```
@@ -0,0 +1,78 @@
#!/bin/bash
# Kubernetes Cluster Health Check Script
# Usage: ./cluster-health-check.sh [namespace]
set -euo pipefail
NAMESPACE="${1:-default}"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
echo "========================================="
echo "Kubernetes Cluster Health Check"
echo "========================================="
echo ""
# Check cluster connectivity
echo -n "Checking cluster connectivity... "
if kubectl cluster-info &>/dev/null; then
echo -e "${GREEN}OK${NC}"
else
echo -e "${RED}FAILED${NC}"
exit 1
fi
# Node status
echo ""
echo "Node Status:"
echo "------------"
kubectl get nodes -o wide
# Check for NotReady nodes
NOT_READY=$(kubectl get nodes --no-headers | grep -v " Ready" | wc -l)
if [ "$NOT_READY" -gt 0 ]; then
echo -e "${RED}WARNING: $NOT_READY node(s) not ready${NC}"
fi
# Pod status in namespace
echo ""
echo "Pod Status in namespace '$NAMESPACE':"
echo "--------------------------------------"
kubectl get pods -n "$NAMESPACE" -o wide
# Check for failed pods
FAILED_PODS=$(kubectl get pods -n "$NAMESPACE" --no-headers | grep -E "Error|CrashLoopBackOff|ImagePullBackOff" | wc -l)
if [ "$FAILED_PODS" -gt 0 ]; then
echo -e "${RED}WARNING: $FAILED_PODS pod(s) in error state${NC}"
fi
# Resource usage
echo ""
echo "Resource Usage:"
echo "---------------"
kubectl top nodes 2>/dev/null || echo "Metrics server not available"
# Recent events
echo ""
echo "Recent Warning Events:"
echo "----------------------"
kubectl get events -n "$NAMESPACE" --field-selector type=Warning --sort-by='.lastTimestamp' | tail -10
# PVC status
echo ""
echo "PersistentVolumeClaim Status:"
echo "-----------------------------"
kubectl get pvc -n "$NAMESPACE" 2>/dev/null || echo "No PVCs found"
# Service status
echo ""
echo "Services:"
echo "---------"
kubectl get svc -n "$NAMESPACE"
echo ""
echo "========================================="
echo "Health check complete"
echo "========================================="
@@ -0,0 +1,75 @@
#!/bin/bash
# Kubernetes Namespace Cleanup Script
# Removes completed jobs, failed pods, and unused resources
# Usage: ./namespace-cleanup.sh <namespace> [--dry-run]
set -euo pipefail
NAMESPACE="${1:-}"
DRY_RUN="${2:-}"
if [ -z "$NAMESPACE" ]; then
echo "Usage: $0 <namespace> [--dry-run]"
exit 1
fi
if [ "$DRY_RUN" == "--dry-run" ]; then
echo "DRY RUN MODE - No changes will be made"
DELETE_CMD="echo [DRY RUN] Would delete:"
else
DELETE_CMD="kubectl delete"
fi
echo "========================================="
echo "Namespace Cleanup: $NAMESPACE"
echo "========================================="
echo ""
# Delete completed jobs
echo "Cleaning up completed Jobs..."
COMPLETED_JOBS=$(kubectl get jobs -n "$NAMESPACE" -o jsonpath='{.items[?(@.status.succeeded==1)].metadata.name}' 2>/dev/null)
if [ -n "$COMPLETED_JOBS" ]; then
for job in $COMPLETED_JOBS; do
$DELETE_CMD job "$job" -n "$NAMESPACE" 2>/dev/null || true
done
else
echo "No completed jobs found"
fi
# Delete failed pods
echo ""
echo "Cleaning up failed Pods..."
FAILED_PODS=$(kubectl get pods -n "$NAMESPACE" --field-selector status.phase=Failed -o name 2>/dev/null)
if [ -n "$FAILED_PODS" ]; then
for pod in $FAILED_PODS; do
$DELETE_CMD "$pod" -n "$NAMESPACE" 2>/dev/null || true
done
else
echo "No failed pods found"
fi
# Delete evicted pods
echo ""
echo "Cleaning up evicted Pods..."
EVICTED_PODS=$(kubectl get pods -n "$NAMESPACE" -o json | jq -r '.items[] | select(.status.reason=="Evicted") | .metadata.name' 2>/dev/null)
if [ -n "$EVICTED_PODS" ]; then
for pod in $EVICTED_PODS; do
$DELETE_CMD pod "$pod" -n "$NAMESPACE" 2>/dev/null || true
done
else
echo "No evicted pods found"
fi
# Delete orphaned ReplicaSets (0 replicas, no owner)
echo ""
echo "Cleaning up orphaned ReplicaSets..."
kubectl get rs -n "$NAMESPACE" -o json | jq -r '.items[] | select(.spec.replicas==0) | .metadata.name' 2>/dev/null | while read rs; do
if [ -n "$rs" ]; then
$DELETE_CMD rs "$rs" -n "$NAMESPACE" 2>/dev/null || true
fi
done
echo ""
echo "========================================="
echo "Cleanup complete"
echo "========================================="
@@ -0,0 +1,71 @@
#!/bin/bash
# Kubernetes Pod Debugging Script
# Usage: ./pod-debug.sh <pod-name> [namespace]
set -euo pipefail
POD_NAME="${1:-}"
NAMESPACE="${2:-default}"
if [ -z "$POD_NAME" ]; then
echo "Usage: $0 <pod-name> [namespace]"
echo ""
echo "Available pods in namespace '$NAMESPACE':"
kubectl get pods -n "$NAMESPACE" --no-headers | awk '{print " " $1}'
exit 1
fi
echo "========================================="
echo "Debugging Pod: $POD_NAME"
echo "Namespace: $NAMESPACE"
echo "========================================="
echo ""
# Pod details
echo "Pod Details:"
echo "------------"
kubectl get pod "$POD_NAME" -n "$NAMESPACE" -o wide
# Pod describe
echo ""
echo "Pod Description:"
echo "----------------"
kubectl describe pod "$POD_NAME" -n "$NAMESPACE"
# Container logs
echo ""
echo "Container Logs (last 50 lines):"
echo "--------------------------------"
CONTAINERS=$(kubectl get pod "$POD_NAME" -n "$NAMESPACE" -o jsonpath='{.spec.containers[*].name}')
for CONTAINER in $CONTAINERS; do
echo ""
echo "=== Container: $CONTAINER ==="
kubectl logs "$POD_NAME" -n "$NAMESPACE" -c "$CONTAINER" --tail=50 2>/dev/null || echo "No logs available"
done
# Previous container logs (if crashed)
echo ""
echo "Previous Container Logs (if any):"
echo "----------------------------------"
for CONTAINER in $CONTAINERS; do
echo ""
echo "=== Container: $CONTAINER (previous) ==="
kubectl logs "$POD_NAME" -n "$NAMESPACE" -c "$CONTAINER" --previous --tail=20 2>/dev/null || echo "No previous logs"
done
# Resource usage
echo ""
echo "Resource Usage:"
echo "---------------"
kubectl top pod "$POD_NAME" -n "$NAMESPACE" 2>/dev/null || echo "Metrics not available"
# Events for this pod
echo ""
echo "Related Events:"
echo "---------------"
kubectl get events -n "$NAMESPACE" --field-selector involvedObject.name="$POD_NAME" --sort-by='.lastTimestamp'
echo ""
echo "========================================="
echo "Debug information complete"
echo "========================================="