Модуль 15 / 19
Troubleshooting Kubernetes
Содержание
1. Цели модуля
Вы научитесь локализовать отказ по слоям Kubernetes, сохранять evidence до изменения системы и выбирать минимальное обратимое исправление.
- scope и identity
- controller, Pod и container states
- scheduling, image и runtime
- Service, EndpointSlice и DNS
- ephemeral containers и Node debug
2. Теория: evidence-first диагностика
Troubleshooting — это проверка гипотез, а не перебор команд. Сначала сформулируйте наблюдаемый симптом и время начала, определите blast radius и recent changes, затем двигайтесь от внешнего эффекта к ближайшему сломанному слою.
До исправления сохраните object YAML, Conditions, Events, logs, revision и timestamps. После изменения повторите исходную проверку: зелёный rollout сам по себе не доказывает восстановление пользовательского запроса.
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
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.
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 после работы.
6. Методические указания
- Одна итерация — одна проверяемая гипотеза
- Сначала read-only команды, затем минимальное изменение
- Не удаляйте проблемный Pod до сохранения logs --previous и Events
- Не используйте force delete как диагностику
- Проверяйте точный container, namespace и время события
- Не устанавливайте пакеты в production container
- Фиксируйте команды, UTC timestamps и результат для incident timeline
- После восстановления устраните системную причину и обновите runbook
7. Лабораторная работа: четыре класса отказов
Сохраните manifest как troubleshooting-lab.yaml. Он намеренно создаёт рабочее приложение с ошибочным Service selector, bad image, crashing process и workload с невозможным nodeSelector.
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"]}]8. Лабораторная работа: собираем evidence
Не исправляйте объекты при первом просмотре. Для каждого workload запишите симптом, evidence и только одну предполагаемую причину.
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.
9. Лабораторная работа: минимальные исправления
Исправьте каждый независимый дефект и повторно проверьте rollout и traffic endpoints.
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. Диагностический контейнер и Node debug
Для работающего api добавьте ephemeral container. Интерактивная команда блокирует терминал; выйдите через exit. Видимость процессов через --target зависит от runtime.
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 без отдельного согласования.
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-debug11. Контроль и шпаргалка
- Почему CrashLoopBackOff не является первопричиной?
- Когда нужен logs --previous?
- Почему Running не доказывает доступность Service?
- Чем ephemeral container отличается от копии Pod?
- Какие риски создаёт kubectl debug node?
- Что нужно проверить после технического восстановления?
Модуль освоен, если вы классифицируете четыре отказа без случайных изменений, подтверждаете каждую причину evidence и проверяете пользовательский результат после исправления.
PDF для работы офлайн
Скачайте оформленную версию модуля для чтения без подключения к сети.