Zum Inhalt

Troubleshooting für Plattform Administratoren

Dieses Dokument beschreibt systematische Troubleshooting-Prozeduren für die ayedo Software Delivery Plattform. Als Plattform Administrator helfen Ihnen diese Guides, Probleme schnell zu identifizieren und zu beheben.

Zielgruppe

Diese Troubleshooting-Guides richten sich an Plattform Administratoren. Anwendungsentwickler finden relevante Guides in der Delivery-Dokumentation.

Troubleshooting-Strategie

Wenn Sie nicht wissen, wo Sie anfangen sollen, arbeiten Sie sich von unten nach oben durch den Stack:

  1. Physische/VM-Ebene: Nodes erreichbar? Hardware ok?
  2. Betriebssystem-Ebene: Systemd ok? Disk/Memory/CPU ausreichend?
  3. Kubernetes-Ebene: Nodes Ready? Control-Plane healthy?
  4. Platform-Ebene: Pods Running? Services erreichbar?
  5. Application-Ebene: Application-Logs? Performance-Metriken?

1. Physische/VM-Ebene

Nodes erreichbar?

# Alle Nodes per SSH testen
kubectl get nodes -o wide

# SSH auf Node
ssh <node-ip>

Nodes "gesund"?

Kernel-Messages prüfen (OOM, Hardware-Fehler):

ssh <node>
sudo dmesg | tail -50

Uptime und Load prüfen:

ssh <node>
uptime

# Load sollte < Anzahl CPUs sein
# z.B. bei 8 CPUs: Load < 8

CPU-Auslastung prüfen:

ssh <node>
top -b -n 1 | head -20

# Oder top Processes
ps -Ao user,pid,pcpu,pmem,cmd --sort=-pcpu | head -10

Disk-Space prüfen:

ssh <node>
df -h

# Alle Filesystems sollten < 80% voll sein
# Kritische Pfade:
# - / (root)
# - /var/lib/kubelet
# - /var/lib/containerd

Memory prüfen:

ssh <node>
free -h

# Mindestens 1-2 GB "available" Memory

Internet-Zugriff prüfen:

ssh <node>
curl -I https://google.com
ping -c 3 8.8.8.8

Zeit-Synchronisation prüfen (kritisch für TLS!):

ssh <node>
timedatectl status

# Sollte zeigen:
# System clock synchronized: yes
# NTP service: active

2. Betriebssystem-Ebene

OS-Version prüfen

# Ubuntu
ssh <node>
lsb_release -a

# CentOS/RHEL
ssh <node>
cat /etc/redhat-release

Systemd-Status prüfen

ssh <node>
systemctl is-system-running

# Sollte "running" sein (nicht "degraded")

# Failed Units finden
systemctl list-units --state=failed

Kubelet-Status prüfen

ssh <node>
sudo systemctl status kubelet

# Falls kubelet nicht läuft:
sudo journalctl -u kubelet -n 100 --no-pager

Containerd-Status prüfen

ssh <node>
sudo systemctl status containerd

# Container Images prüfen
sudo crictl images

# Running Containers prüfen
sudo crictl ps

3. Kubernetes-Ebene

Nodes Ready?

kubectl get nodes

# Alle Nodes sollten "Ready" sein
# Falls "NotReady" → siehe Runbooks

# Node-Details
kubectl describe node <node-name>

Control-Plane healthy?

# Control-Plane-Pods
kubectl get pods -n kube-system

# Kritische Pods:
# - kube-apiserver
# - kube-controller-manager
# - kube-scheduler
# - etcd

# API-Server-Health
kubectl get --raw /healthz
kubectl get --raw /livez
kubectl get --raw /readyz

etcd healthy?

# etcd-Pods
kubectl get pods -n kube-system -l component=etcd

# etcd-Health
kubectl exec -n kube-system etcd-<node> -- etcdctl \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  endpoint health

# etcd-Status
kubectl exec -n kube-system etcd-<node> -- etcdctl \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  member list

Pods Running?

# Alle Pods anzeigen
kubectl get pods -A

# Nicht-Running Pods finden
kubectl get pods -A | grep -vE "Running|Completed"

# Pod-Details
kubectl describe pod <pod-name> -n <namespace>

# Pod-Logs
kubectl logs <pod-name> -n <namespace>

# Vorherige Pod-Logs (falls CrashLoopBackOff)
kubectl logs <pod-name> -n <namespace> --previous

Deployments healthy?

# Deployments
kubectl get deployments -A

# Deployments mit Problemen finden
kubectl get deployments -A | awk '$3 != $4 {print}'

# Deployment-Details
kubectl describe deployment <deployment-name> -n <namespace>

DaemonSets healthy?

# DaemonSets
kubectl get daemonsets -A

# DaemonSets mit Problemen finden
kubectl get daemonsets -A | awk '$2 != $3 {print}'

# DaemonSet-Details
kubectl describe daemonset <ds-name> -n <namespace>

StatefulSets healthy?

# StatefulSets
kubectl get statefulsets -A

# StatefulSet-Details
kubectl describe statefulset <sts-name> -n <namespace>

Services erreichbar?

# Services
kubectl get services -A

# Service-Details
kubectl describe service <svc-name> -n <namespace>

# Endpoints prüfen (sollten nicht leer sein!)
kubectl get endpoints <svc-name> -n <namespace>

4. Platform-Ebene

Grafana erreichbar?

# Grafana-Pods
kubectl get pods -n monitoring -l app.kubernetes.io/name=grafana

# Grafana-Service
kubectl get svc -n monitoring grafana

# Grafana-HTTP-Test
curl -I https://grafana.example.com

# Grafana-Logs
kubectl logs -n monitoring -l app.kubernetes.io/name=grafana --tail=50

VictoriaMetrics erreichbar?

# VictoriaMetrics-Pods
kubectl get pods -n monitoring -l app.kubernetes.io/name=victoria-metrics

# VictoriaMetrics-HTTP-Test
kubectl port-forward -n monitoring svc/victoria-metrics 8428:8428
curl http://localhost:8428/metrics

# Metriken werden gesammelt?
kubectl logs -n monitoring -l app.kubernetes.io/name=victoria-metrics --tail=50

Harbor erreichbar?

# Harbor-Pods
kubectl get pods -n harbor

# Harbor-HTTP-Test
curl -I https://harbor.example.com

# Harbor-Database-Status
kubectl exec -n harbor harbor-database-0 -- \
  psql -U postgres -c "SELECT version();"

# Harbor-Logs
kubectl logs -n harbor -l app=harbor-core --tail=50

Ingress-Controller healthy?

# Ingress-Pods
kubectl get pods -n ingress-nginx

# Ingress-Controller-Logs
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx --tail=50

# Ingresses auflisten
kubectl get ingress -A

Cert-Manager healthy?

# Cert-Manager-Pods
kubectl get pods -n cert-manager

# Certificates prüfen
kubectl get certificates -A

# Ablaufende Certificates finden
kubectl get certificates -A -o json | \
  jq -r '.items[] | select(.status.notAfter != null) |
  [.metadata.namespace, .metadata.name, .status.notAfter] | @tsv' | \
  awk -v date="$(date -d '+30 days' -u +%Y-%m-%dT%H:%M:%SZ)" '$3 < date'

# Cert-Manager-Logs
kubectl logs -n cert-manager -l app=cert-manager --tail=50

5. Application-Ebene

Application-Pods Running?

# Application-Pods
kubectl get pods -n production

# Pod-Logs
kubectl logs -n production <pod-name>

# Pod-Events
kubectl get events -n production --field-selector involvedObject.name=<pod-name> --sort-by='.lastTimestamp'

Application-Performance

# CPU/Memory-Usage
kubectl top pods -n production

# Top-Pods nach CPU
kubectl top pods -n production --sort-by=cpu | head -10

# Top-Pods nach Memory
kubectl top pods -n production --sort-by=memory | head -10
curl -u "${OS_USER}:${OS_PASS}" \
  -X POST "${OS_URL}/kubernetes-*/_search?pretty" \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "bool": {
        "must": [
          { "match": { "kubernetes.namespace_name": "production" } },
          { "match": { "kubernetes.pod_name": "my-app-*" } }
        ]
      }
    },
    "size": 10,
    "sort": [{ "@timestamp": { "order": "desc" } }]
  }'

Häufige Probleme

Problem: ImagePullBackOff

Symptom: Pod Status ImagePullBackOff oder ErrImagePull

Ursache: - Container-Image existiert nicht - Image-Pull-Secret fehlt oder ist falsch - Harbor nicht erreichbar

Lösung:

# Image-Details prüfen
kubectl describe pod <pod-name> -n <namespace> | grep -A 5 "Failed"

# Image manuell pullen testen
docker pull harbor.example.com/production/my-app:v1.0.0

# Image-Pull-Secret prüfen
kubectl get secret -n <namespace> | grep docker

# Image-Pull-Secret erstellen (falls fehlt)
kubectl create secret docker-registry harbor-pull-secret \
  --docker-server=harbor.example.com \
  --docker-username=<username> \
  --docker-password=<password> \
  -n <namespace>

Problem: CrashLoopBackOff

Symptom: Pod Status CrashLoopBackOff

Ursache: - Application crasht beim Start - Liveness/Readiness-Probe schlägt fehl - ConfigMap/Secret fehlt - Resource-Limits zu niedrig

Lösung:

# Vorherige Logs prüfen
kubectl logs <pod-name> -n <namespace> --previous

# Pod-Events prüfen
kubectl describe pod <pod-name> -n <namespace>

# Resource-Limits prüfen
kubectl get pod <pod-name> -n <namespace> -o yaml | grep -A 10 resources

# ConfigMaps/Secrets prüfen
kubectl get configmap,secret -n <namespace>

Problem: Pending Pods

Symptom: Pod Status Pending

Ursache: - Keine Nodes mit ausreichenden Ressourcen - PVC kann nicht gebunden werden - Taints/Tolerations passen nicht - Node-Affinity nicht erfüllt

Lösung:

# Pod-Events prüfen
kubectl describe pod <pod-name> -n <namespace>

# Nodes-Kapazität prüfen
kubectl top nodes

# PVC-Status prüfen
kubectl get pvc -n <namespace>

# Node-Taints prüfen
kubectl get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints

Problem: Service nicht erreichbar

Symptom: Service-URL gibt Timeout oder 404

Ursache: - Service hat keine Endpoints - Ingress falsch konfiguriert - DNS nicht aufgelöst - Network-Policy blockiert Traffic

Lösung:

# Service-Endpoints prüfen
kubectl get endpoints <service-name> -n <namespace>

# Falls keine Endpoints → Pod-Selector prüfen
kubectl get svc <service-name> -n <namespace> -o yaml | grep selector
kubectl get pods -n <namespace> --show-labels | grep <selector>

# Ingress prüfen
kubectl describe ingress <ingress-name> -n <namespace>

# DNS-Auflösung testen
kubectl run -it --rm debug --image=busybox --restart=Never -- nslookup <service-name>.<namespace>.svc.cluster.local

# Network-Policy prüfen
kubectl get networkpolicies -n <namespace>

Problem: PVC Pending

Symptom: PVC Status Pending

Ursache: - StorageClass existiert nicht - Kein verfügbares PV - VolumeBindingMode: WaitForFirstConsumer (braucht Pod)

Lösung:

# PVC-Events prüfen
kubectl describe pvc <pvc-name> -n <namespace>

# StorageClass prüfen
kubectl get storageclass

# PVs prüfen
kubectl get pv

# Falls WaitForFirstConsumer → Pod erstellen

Debug-Tools

Pod-Shell

# Exec in Running Pod
kubectl exec -it <pod-name> -n <namespace> -- /bin/sh

# Debug-Container starten (falls Pod crasht)
kubectl debug <pod-name> -n <namespace> --image=busybox -it -- /bin/sh

Network-Debug

# Debug-Pod für Network-Tests
kubectl run debug-network --image=nicolaka/netshoot -it --rm -- /bin/bash

# Dann im Pod:
# ping <service-name>
# nslookup <service-name>
# curl http://<service-name>:<port>
# traceroute <service-name>

DNS-Debug

# DNS-Test-Pod
kubectl run dns-test --image=busybox:1.28 --rm -it --restart=Never -- nslookup kubernetes.default

# CoreDNS-Logs
kubectl logs -n kube-system -l k8s-app=kube-dns --tail=50

Resource-Debug

# Node-Ressourcen
kubectl top nodes

# Pod-Ressourcen
kubectl top pods -A

# Resource-Quotas prüfen
kubectl get resourcequota -A

# LimitRanges prüfen
kubectl get limitrange -A

Logs sammeln für Support

Falls Sie den ayedo Support kontaktieren müssen, sammeln Sie bitte folgende Informationen:

# 1. Cluster-Info
kubectl cluster-info
kubectl version

# 2. Node-Status
kubectl get nodes -o wide

# 3. Problem-Pods
kubectl get pods -A | grep -vE "Running|Completed"

# 4. Pod-Details (für problematische Pods)
kubectl describe pod <pod-name> -n <namespace> > pod-describe.txt
kubectl logs <pod-name> -n <namespace> > pod-logs.txt
kubectl logs <pod-name> -n <namespace> --previous > pod-previous-logs.txt

# 5. Events
kubectl get events -A --sort-by='.lastTimestamp' | tail -50 > events.txt

# 6. PVCs (falls Storage-Problem)
kubectl get pvc -A -o wide > pvcs.txt

# 7. Platform-Komponenten-Logs
kubectl logs -n monitoring -l app.kubernetes.io/name=grafana --tail=100 > grafana-logs.txt
kubectl logs -n opensearch opensearch-0 --tail=100 > opensearch-logs.txt
kubectl logs -n harbor -l app=harbor-core --tail=100 > harbor-logs.txt

# Alle Logs als Tarball
tar czf ayedo-debug-$(date +%Y%m%d-%H%M%S).tar.gz *.txt

Weiterführende Dokumentation

Support

Bei Fragen zum Troubleshooting: