← К программе курса

Модуль 15 / 19

Troubleshooting Kubernetes

KUBERNETES

Содержание
01

1. Цели модуля

Вы научитесь локализовать отказ по слоям Kubernetes, сохранять evidence до изменения системы и выбирать минимальное обратимое исправление.

  • scope и identity
  • controller, Pod и container states
  • scheduling, image и runtime
  • Service, EndpointSlice и DNS
  • ephemeral containers и Node debug
02

2. Теория: evidence-first диагностика

Troubleshooting — это проверка гипотез, а не перебор команд. Сначала сформулируйте наблюдаемый симптом и время начала, определите blast radius и recent changes, затем двигайтесь от внешнего эффекта к ближайшему сломанному слою.

До исправления сохраните object YAML, Conditions, Events, logs, revision и timestamps. После изменения повторите исходную проверку: зелёный rollout сам по себе не доказывает восстановление пользовательского запроса.

03

3. Теория: диагностические слои

  • Context, cluster, namespace и permissions
  • Workload controller: generation, observedGeneration, Conditions и revision
  • Pod: phase, Conditions, init/containerStatuses и nodeName
  • Container: waiting/terminated reason, exitCode, restartCount и previous logs
  • Scheduling и storage: Events, constraints, PVC/PV и Node allocatable
  • Network: Service selector, EndpointSlice readiness, DNS и NetworkPolicy
  • Application: health endpoint, dependencies, configuration и telemetry
04

4. Теория: как читать типовые состояния

Pending обычно указывает на scheduling, unbound storage или admission. ImagePullBackOff означает повторные попытки получить image: проверяйте имя, tag, registry, credentials и Events. CrashLoopBackOff — backoff между рестартами, а причина находится в lastState, exitCode и previous logs.

Running не означает Ready, а Service без ready EndpointSlice не получает backend. OOMKilled требует сопоставить memory limit, usage и поведение процесса; Evicted — давление Node, а не сбой container runtime.

05

5. Теория: exec, logs и kubectl debug

kubectl exec запускает процесс в работающем контейнере и бесполезен для distroless image без shell или уже завершившегося процесса. Ephemeral container добавляет инструменты в существующий Pod без restart, но требует права update на pods/ephemeralcontainers и не удаляется отдельно до удаления Pod.

kubectl debug может создать копию Pod или Node debug Pod. Для Node его filesystem доступен через /host, а host namespaces расширяют область воздействия. Profile sysadmin создаёт привилегированный контекст; используйте его только по утверждённой процедуре и удаляйте debug Pod после работы.

06

6. Методические указания

  • Одна итерация — одна проверяемая гипотеза
  • Сначала read-only команды, затем минимальное изменение
  • Не удаляйте проблемный Pod до сохранения logs --previous и Events
  • Не используйте force delete как диагностику
  • Проверяйте точный container, namespace и время события
  • Не устанавливайте пакеты в production container
  • Фиксируйте команды, UTC timestamps и результат для incident timeline
  • После восстановления устраните системную причину и обновите runbook
07

7. Лабораторная работа: четыре класса отказов

Сохраните manifest как troubleshooting-lab.yaml. Он намеренно создаёт рабочее приложение с ошибочным Service selector, bad image, crashing process и workload с невозможным nodeSelector.

terminal
apiVersion: v1
kind: Namespace
metadata: {name: lab-troubleshooting}
---
apiVersion: apps/v1
kind: Deployment
metadata: {name: api, namespace: lab-troubleshooting}
spec:
  replicas: 1
  selector:
    matchLabels: {app: api}
  template:
    metadata:
      labels: {app: api}
    spec:
      containers:
        - name: api
          image: busybox:1.37.0
          command: ["sh", "-c", "mkdir -p /www; echo ok > /www/index.html; exec httpd -f -p 8080 -h /www"]
          ports: [{name: http, containerPort: 8080}]
          readinessProbe:
            httpGet: {path: /, port: http}
---
apiVersion: v1
kind: Service
metadata: {name: api, namespace: lab-troubleshooting}
spec:
  selector: {app: api-typo}
  ports: [{name: http, port: 80, targetPort: http}]
---
apiVersion: apps/v1
kind: Deployment
metadata: {name: bad-image, namespace: lab-troubleshooting}
spec:
  replicas: 1
  selector:
    matchLabels: {app: bad-image}
  template:
    metadata:
      labels: {app: bad-image}
    spec:
      containers: [{name: web, image: "nginx:does-not-exist"}]
---
apiVersion: apps/v1
kind: Deployment
metadata: {name: crash, namespace: lab-troubleshooting}
spec:
  replicas: 1
  selector:
    matchLabels: {app: crash}
  template:
    metadata:
      labels: {app: crash}
    spec:
      containers:
        - name: worker
          image: busybox:1.37.0
          command: ["sh", "-c", "echo fatal: configuration missing >&2; exit 42"]
---
apiVersion: apps/v1
kind: Deployment
metadata: {name: unschedulable, namespace: lab-troubleshooting}
spec:
  replicas: 1
  selector:
    matchLabels: {app: unschedulable}
  template:
    metadata:
      labels: {app: unschedulable}
    spec:
      nodeSelector: {course.example.com/pool: absent}
      containers: [{name: sleeper, image: "busybox:1.37.0", command: ["sleep", "3600"]}]
08

8. Лабораторная работа: собираем evidence

Не исправляйте объекты при первом просмотре. Для каждого workload запишите симптом, evidence и только одну предполагаемую причину.

terminal
kubectl apply -f troubleshooting-lab.yaml
kubectl get deployment,pod,service,endpointslice -n lab-troubleshooting -o wide
kubectl events -n lab-troubleshooting --types=Warning
kubectl describe pod -n lab-troubleshooting -l app=bad-image
kubectl logs -n lab-troubleshooting -l app=crash -c worker --previous --tail=20
kubectl describe pod -n lab-troubleshooting -l app=unschedulable
kubectl get service api -n lab-troubleshooting -o jsonpath='{.spec.selector}{"\n"}'
kubectl get pod -n lab-troubleshooting -l app=api --show-labels
kubectl get endpointslice -n lab-troubleshooting -l kubernetes.io/service-name=api -o yaml

Ожидается: ImagePullBackOff у bad-image, exitCode 42 и previous log у crash, FailedScheduling у unschedulable, пустые ready endpoints у Service api.

09

9. Лабораторная работа: минимальные исправления

Исправьте каждый независимый дефект и повторно проверьте rollout и traffic endpoints.

terminal
kubectl set image deployment/bad-image web=nginx:1.29-alpine -n lab-troubleshooting
kubectl patch deployment crash -n lab-troubleshooting --type=json -p='[{"op":"replace","path":"/spec/template/spec/containers/0/command","value":["sleep","3600"]}]'
kubectl patch deployment unschedulable -n lab-troubleshooting --type=json -p='[{"op":"remove","path":"/spec/template/spec/nodeSelector"}]'
kubectl patch service api -n lab-troubleshooting --type=merge -p='{"spec":{"selector":{"app":"api"}}}'
kubectl rollout status deployment/bad-image -n lab-troubleshooting --timeout=120s
kubectl rollout status deployment/crash -n lab-troubleshooting --timeout=120s
kubectl rollout status deployment/unschedulable -n lab-troubleshooting --timeout=120s
kubectl get pod,endpointslice -n lab-troubleshooting -o wide

Критерий: четыре Deployments Available, Pods Ready, api EndpointSlice содержит ready address, новые Warning Events не появляются.

10

10. Диагностический контейнер и Node debug

Для работающего api добавьте ephemeral container. Интерактивная команда блокирует терминал; выйдите через exit. Видимость процессов через --target зависит от runtime.

terminal
POD="$(kubectl get pod -n lab-troubleshooting -l app=api -o jsonpath='{.items[0].metadata.name}')"
kubectl auth can-i update pods/ephemeralcontainers -n lab-troubleshooting
kubectl debug -n lab-troubleshooting -it "$POD" --image=busybox:1.37.0 --target=api --profile=general
kubectl describe pod "$POD" -n lab-troubleshooting
kubectl delete namespace lab-troubleshooting

Следующие команды приведены только для контролируемой административной диагностики Node. general profile не является privileged, но Pod получает host namespaces и /host. Не используйте sysadmin без отдельного согласования.

terminal
NODE="$(kubectl get node -o jsonpath='{.items[0].metadata.name}')"
kubectl create namespace node-debug
kubectl debug node/"$NODE" -n node-debug -it --image=busybox:1.37.0 --profile=general
kubectl get pod -n node-debug -o wide
kubectl delete namespace node-debug
11

11. Контроль и шпаргалка

  • Почему CrashLoopBackOff не является первопричиной?
  • Когда нужен logs --previous?
  • Почему Running не доказывает доступность Service?
  • Чем ephemeral container отличается от копии Pod?
  • Какие риски создаёт kubectl debug node?
  • Что нужно проверить после технического восстановления?

Модуль освоен, если вы классифицируете четыре отказа без случайных изменений, подтверждаете каждую причину evidence и проверяете пользовательский результат после исправления.

PDF для работы офлайн

Скачайте оформленную версию модуля для чтения без подключения к сети.

Скачать PDFPDF