Salta ai contenuti

App shop-demo con guasti

Un componente sano di riferimento e sei componenti, ciascuno rotto in modo diverso. La tabella è il “risultato atteso” contro cui valutare i tool AI.

Componente Guasto Sintomo Segnale principale
catalog nessuno Running, Ready baseline
frontend tag immagine inesistente ImagePullBackOff evento Failed to pull image
api memory limit sotto il consumo OOMKilled → CrashLoopBackOff lastState.terminated.reason: OOMKilled
worker ConfigMap mancante CreateContainerConfigError evento configmap "worker-config" not found
checkout readiness probe su porta sbagliata Running, 0/1 Ready evento Readiness probe failed
checkout-svc selector errato Service senza endpoint endpoints vuoti
orders-db PVC su StorageClass inesistente PVC e pod Pending evento storageclass "fast-ssd" not found
Finestra del terminale
mkdir -p ~/Downloads/K8S-AI/lab && cd ~/Downloads/K8S-AI/lab
Finestra del terminale
cat > shop-demo.yaml <<'EOF2'
apiVersion: v1
kind: Namespace
metadata:
name: shop-demo
labels:
purpose: ai-debug-lab
---
# baseline: healthy
apiVersion: apps/v1
kind: Deployment
metadata:
name: catalog
namespace: shop-demo
spec:
replicas: 1
selector:
matchLabels: { app: catalog }
template:
metadata:
labels: { app: catalog }
spec:
containers:
- name: podinfo
image: ghcr.io/stefanprodan/podinfo:6.7.1
ports: [{ containerPort: 9898, name: http }]
readinessProbe:
httpGet: { path: /readyz, port: http }
resources:
requests: { cpu: 10m, memory: 32Mi }
limits: { memory: 64Mi }
---
apiVersion: v1
kind: Service
metadata:
name: catalog
namespace: shop-demo
spec:
selector: { app: catalog }
ports: [{ port: 80, targetPort: http }]
---
# fault 1: image tag does not exist
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
namespace: shop-demo
spec:
replicas: 1
selector:
matchLabels: { app: frontend }
template:
metadata:
labels: { app: frontend }
spec:
containers:
- name: nginx
image: nginx:1.27-doesnotexist
resources:
requests: { cpu: 10m, memory: 16Mi }
---
# fault 2: memory limit below real usage -> OOMKilled
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
namespace: shop-demo
spec:
replicas: 1
selector:
matchLabels: { app: api }
template:
metadata:
labels: { app: api }
spec:
containers:
- name: stress
image: polinux/stress
command: ["stress", "--vm", "1", "--vm-bytes", "200M", "--vm-hang", "1"]
resources:
requests: { cpu: 10m, memory: 32Mi }
limits: { memory: 64Mi }
---
# fault 3: references a ConfigMap that does not exist
apiVersion: apps/v1
kind: Deployment
metadata:
name: worker
namespace: shop-demo
spec:
replicas: 1
selector:
matchLabels: { app: worker }
template:
metadata:
labels: { app: worker }
spec:
containers:
- name: worker
image: busybox:1.36
command: ["sh", "-c", "echo queue=$QUEUE_URL; sleep 3600"]
env:
- name: QUEUE_URL
valueFrom:
configMapKeyRef: { name: worker-config, key: queue_url }
resources:
requests: { cpu: 5m, memory: 8Mi }
---
# fault 4: readiness probe on the wrong port
apiVersion: apps/v1
kind: Deployment
metadata:
name: checkout
namespace: shop-demo
spec:
replicas: 1
selector:
matchLabels: { app: checkout }
template:
metadata:
labels: { app: checkout }
spec:
containers:
- name: podinfo
image: ghcr.io/stefanprodan/podinfo:6.7.1
ports: [{ containerPort: 9898, name: http }]
readinessProbe:
httpGet: { path: /readyz, port: 8080 }
periodSeconds: 5
resources:
requests: { cpu: 10m, memory: 32Mi }
limits: { memory: 64Mi }
---
# fault 5: selector does not match any pod
apiVersion: v1
kind: Service
metadata:
name: checkout-svc
namespace: shop-demo
spec:
selector: { app: check-out }
ports: [{ port: 80, targetPort: 9898 }]
---
# fault 6: PVC on a StorageClass that does not exist
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: orders-db-data
namespace: shop-demo
spec:
accessModes: [ReadWriteOnce]
storageClassName: fast-ssd
resources:
requests: { storage: 1Gi }
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: orders-db
namespace: shop-demo
spec:
replicas: 1
selector:
matchLabels: { app: orders-db }
template:
metadata:
labels: { app: orders-db }
spec:
containers:
- name: redis
image: redis:7
volumeMounts: [{ name: data, mountPath: /data }]
resources:
requests: { cpu: 10m, memory: 32Mi }
volumes:
- name: data
persistentVolumeClaim: { claimName: orders-db-data }
EOF2
Finestra del terminale
kubectl apply -f shop-demo.yaml
Finestra del terminale
kubectl -n shop-demo get pods,svc,endpoints,pvc
Finestra del terminale
kubectl -n shop-demo get events --sort-by=.lastTimestamp | tail -25
Finestra del terminale
kubectl -n shop-demo get pods -o custom-columns=NAME:.metadata.name,READY:.status.containerStatuses[0].ready,RESTARTS:.status.containerStatuses[0].restartCount,WAITING:.status.containerStatuses[0].state.waiting.reason,LAST:.status.containerStatuses[0].lastState.terminated.reason

kube-prometheus-stack include già le regole che scattano su questi guasti, dopo la durata for: (5–15 minuti):

Alert Componenti
KubePodCrashLooping api
KubePodNotReady frontend, worker, checkout, orders-db
KubeDeploymentReplicasMismatch tutti i deployment rotti
KubeContainerWaiting frontend, worker
Finestra del terminale
curl -s localhost:9093/api/v2/alerts | jq -r '.[] | select(.labels.namespace=="shop-demo") | "\(.labels.alertname)\t\(.labels.pod // .labels.deployment)"'
Finestra del terminale
curl -s 'localhost:9090/api/v1/query' --data-urlencode 'query=ALERTS{namespace="shop-demo",alertstate="firing"}' | jq -r '.data.result[].metric | "\(.alertname) \(.pod // .deployment // "")"'