Введение: почему даже опытные инженеры ошибаются в Kubernetes
Kubernetes остаётся стандартом оркестрации контейнеров в 2026 году, но сложность системы приводит к регулярным инцидентам даже в зрелых командах. Спешка при первичной настройке, устаревшая документация и недостаток практики в production-среде создают благоприятную почву для ошибок. По данным внутреннего аудита нашей базы знаний, 8 из 10 обращений по Kubernetes связаны с одними и теми же проблемами: неправильные requests/limits, слишком широкие RBAC-права и отсутствие мониторинга. Эта статья разбирает 10 типичных ошибок и даёт проверенные решения. Материал рассчитан на DevOps-инженеров и системных администраторов, которые хотят сократить время отладки и предотвратить инциденты до их влияния на бизнес.
Каждый раздел содержит конкретные команды, примеры манифестов и практические рекомендации. Если вы уже сталкивались с нестабильностью кластера, начните с чек-листа в заключении: он поможет быстро найти слабые места.
Ошибка 1: Игнорирование requests и limits для контейнеров
Отсутствие requests и limits нарушает планирование ресурсов. Планировщик Kubernetes не может принять адекватное решение о размещении подов, а kubelet не знает, когда нужно вмешаться. Это приводит к перегрузке узлов, хаотичному вытеснению подов и деградации сервисов. В production-среде такая ошибка часто проявляется как случайные OOMKilled и непредсказуемые задержки ответа API.
Requests определяют минимальный объём CPU и памяти, который гарантируется контейнеру при планировании. Limits задают верхнюю границу потребления. При отсутствии limits контейнер с утечкой памяти может забрать все ресурсы узла и нарушить работу соседних подов. При отсутствии requests планировщик размещает поды без учёта реальной нагрузки, что ведёт к переподписке и деградации.
Как правильно установить requests и limits: пошаговая инструкция
Настройка ресурсов требует данных о реальном потреблении. Действуйте по алгоритму:
- Запустите приложение без limits на тестовом окружении.
- Соберите метрики потребления за 7-14 дней с помощью
kubectl top podsили Prometheus. - Установите requests на уровне 70-80% от среднего потребления.
- Установите limits на уровне 150-200% от пикового потребления.
- Настройте Vertical Pod Autoscaler в режиме рекомендаций для дальнейшей корректировки.
Пример манифеста с корректными значениями:
apiVersion: v1
kind: Pod
metadata:
name: web-app
spec:
containers:
- name: nginx
image: nginx:1.25
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"Не задавайте requests и limits одинаковыми для всех контейнеров. Базы данных требуют больше памяти, чем статические веб-серверы. Проверяйте фактические метрики перед фиксацией значений.
Типичные последствия: OOMKilled, вытеснение подов, просадки производительности
Симптомы неправильной настройки ресурсов:
- Статус
OOMKilledв выводеkubectl describe pod. - Частые перезапуски контейнеров без видимой причины.
- Поды в статусе
Evictedпри достаточном объёме свободной памяти на узлах. - Рост latency API server при высокой нагрузке.
Для диагностики используйте kubectl describe node и проверяйте секцию Allocated resources. Если сумма requests превышает доступные ресурсы узла, планировщик не сможет размещать новые поды. Если limits слишком низкие, контейнеры будут убиваться при пиковых нагрузках.
Ошибка 2: Недостаточная настройка RBAC: риски безопасности
RBAC (Role-Based Access Control) управляет правами пользователей и сервисных аккаунтов. Ошибка здесь открывает доступ к секретам, конфигурациям и управлению кластером. Частая проблема: использование cluster-admin для всех сервисных аккаунтов или привязка ролей на уровне кластера вместо namespace. Это нарушает принцип наименьших привилегий и расширяет поверхность атаки.
Если злоумышленник получает доступ к поду с привилегированным сервисным аккаунтом, он может прочитать все секреты в namespace или выйти за его пределы. Аудит безопасности Kubernetes начинается именно с проверки RBAC.
Практическое руководство: создание ролей и привязок с минимальными правами
Для типового сценария разработчика, которому нужен доступ только к подам в своём namespace:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: development
name: developer-role
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
namespace: development
name: developer-binding
subjects:
- kind: User
name: "dev-user"
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: developer-role
apiGroup: rbac.authorization.k8s.ioИспользуйте Role и RoleBinding для ограничения прав в рамках namespace. ClusterRole и ClusterRoleBinding применяйте только для действительно кластерных ресурсов: узлы, PersistentVolumes, namespace'ы.
Аудит RBAC: как найти и исправить избыточные разрешения
Проверьте, какие действия разрешены текущему пользователю:
kubectl auth can-i --list --namespace=developmentДля поиска всех привязок к cluster-admin:
kubectl get clusterrolebindings -o json | jq '.items[] | select(.roleRef.name=="cluster-admin") | .subjects'Инструменты kube-bench и RBAC-lookup автоматизируют проверку. Регулярный аудит прав доступа снижает риск компрометации. Подробный пятишаговый алгоритм проверки кластера описан в нашем руководстве по аудиту безопасности Kubernetes.
Ошибка 3: Использование устаревших версий Kubernetes и компонентов
Kubernetes поддерживает три последние минорные версии. Эксплуатация более старых версий означает наличие известных уязвимостей без исправлений. В 2026 году кластеры на версиях 1.24 и ниже не получают обновлений безопасности. Это прямой риск компрометации production-среды.
Устаревшие версии также несовместимы с новыми API. Манифесты, написанные для актуальных версий, могут не работать на старых кластерах, и наоборот. Обновление откладывается из-за страха даунтайма, но без него кластер становится всё более уязвимым.
Стратегия безопасного обновления кластера без даунтайма
План обновления:
- Создайте резервную копию etcd и манифестов.
- Проверьте совместимость манифестов с целевой версией через
kubectl convert. - Обновите control plane по одной мастер-ноде.
- Обновите worker nodes по одной, с drain и cordon.
- Проверьте работу кластера после каждого шага.
Для кластеров на kubeadm используйте kubeadm upgrade plan и kubeadm upgrade apply. Перед обновлением проверьте, что все критичные поды имеют реплики и распределены по разным узлам. Это позволит избежать простоя при drain.
Ошибка 4: Некорректная конфигурация сети: проблемы связности и безопасности
Сетевая конфигурация определяет, как поды общаются друг с другом и с внешним миром. Ошибки здесь проявляются как таймауты между сервисами, недоступность API и утечки трафика. Частая проблема: отсутствие NetworkPolicy, что позволяет любому поду обращаться к любому другому поду в кластере.
Выбор CNI-плагина влияет на производительность и функциональность. Calico и Cilium поддерживают NetworkPolicy и обеспечивают хорошую производительность. Flannel проще, но не поддерживает сетевые политики.
Настройка NetworkPolicy для изоляции трафика: примеры
Политика, разрешающая трафик только от подов из namespace frontend к подам с меткой app: backend:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-policy
namespace: production
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: frontend
ports:
- protocol: TCP
port: 8080Проверяйте связность с помощью kubectl exec и tcpdump внутри подов. Диагностика сетевых проблем требует системного подхода: сначала проверьте DNS, затем маршруты, затем политики.
Ошибка 5: Отсутствие мониторинга и алертов: как не пропустить инцидент
Кластер без мониторинга работает вслепую. Вы узнаёте о проблеме только когда пользователи начинают жаловаться. Это увеличивает время восстановления и усложняет поиск корневой причины. Мониторинг обязателен для production-среды.
Стек Prometheus + Grafana стал стандартом для Kubernetes. Prometheus собирает метрики с API server, kubelet и подов. Grafana визуализирует их в дашбордах. Alertmanager отправляет уведомления при нарушении порогов.
Минимальный набор метрик для Kubernetes-кластера
Отслеживайте эти метрики:
node_cpu_usage- загрузка CPU на узлах.node_memory_usage- потребление памяти на узлах.pod_memory_usage- потребление памяти подами.apiserver_request_duration_seconds- задержка API server.kubelet_running_pods- количество запущенных подов.
Настройте алерты на использование ресурсов выше 80%, на рост количества перезапусков подов и на задержку API server выше 500 мс. Быстрая диагностика через метрики описана в руководстве по диагностике Kubernetes.
Ошибка 6: Игнорирование лимитов на количество объектов в кластере
Большое количество объектов перегружает etcd и API server. Каждый запрос к API server обрабатывается дольше, а etcd растёт в размерах. Это замедляет все операции в кластере. Без квот одна команда может создать тысячи подов и нарушить работу остальных.
Установите ResourceQuota для ограничения количества объектов в namespace:
apiVersion: v1
kind: ResourceQuota
metadata:
name: object-counts
namespace: development
spec:
hard:
pods: "100"
services: "20"
secrets: "50"
configmaps: "50"LimitRange задаёт ограничения по умолчанию для подов, которые не указывают requests и limits. Регулярно очищайте неиспользуемые ресурсы: завершённые Job'ы, старые ReplicaSet'ы, неиспользуемые ConfigMap'ы и Secrets.
Ошибка 7: Неправильное управление секретами: хранение чувствительных данных
Секреты в Kubernetes хранятся в etcd в base64-кодировке. Это не шифрование, а кодирование. Любой, кто получит доступ к etcd, прочитает все секреты. Хранение паролей и токенов в открытом виде в манифестах - прямой путь к компрометации.
Используйте внешние системы управления секретами: HashiCorp Vault, Sealed Secrets или External Secrets Operator. Они интегрируются с Kubernetes и обеспечивают шифрование. Включите шифрование etcd на уровне кластера:
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- aescbc:
keys:
- name: key1
secret:
- identity: {} Никогда не храните секреты в образах контейнеров или в переменных окружения, которые видны через kubectl describe pod. Используйте secretKeyRef для монтирования секретов как файлов или переменных окружения.
Ошибка 8: Отсутствие резервного копирования и плана восстановления
Потеря etcd означает потерю всего состояния кластера: поды, сервисы, конфигурации. Без резервной копии восстановление невозможно. Человеческая ошибка, сбой диска или атака могут уничтожить кластер за секунды.
Бэкапируйте три компонента: etcd, манифесты приложений и данные в Persistent Volumes. Для etcd используйте встроенный механизм снапшотов:
ETCDCTL_API=3 etcdctl snapshot save /backup/etcd-snapshot.db \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.keyДля комплексного восстановления используйте Velero. Он бэкапит объекты Kubernetes и данные PV в внешнее хранилище. Полное руководство по аварийному восстановлению кластера доступно в материале по восстановлению Kubernetes. Тестируйте восстановление регулярно: бэкап, который не проверяли, не считается бэкапом.
Ошибка 9: Пренебрежение безопасностью пода: запуск с привилегиями
Запуск контейнеров с root-правами или с привилегированным режимом расширяет поверхность атаки. Если злоумышленник эксплуатирует уязвимость в таком контейнере, он получает доступ к узлу. Это позволяет ему читать секреты других подов, изменять конфигурацию кластера и распространять атаку.
Настройте SecurityContext для каждого пода:
apiVersion: v1
kind: Pod
metadata:
name: secure-pod
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 2000
containers:
- name: app
image: myapp:1.0
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: trueВключите Pod Security Admission на уровне namespace. Это предотвращает запуск подов с привилегиями и root-правами. Проверяйте образы на уязвимости перед развёртыванием.
Ошибка 10: Недостаточное тестирование изменений перед применением в production
Прямое применение манифестов в production без тестирования - частая причина инцидентов. Ошибка в конфигурации может привести к удалению сервиса, потере данных или нарушению сетевой связности. Ручные изменения не отслеживаются и затрудняют откат.
Используйте GitOps-подход с ArgoCD или Flux. Все изменения проходят через git-репозиторий, тестируются в staging-окружении и автоматически применяются в production. Это обеспечивает воспроизводимость и возможность отката.
Внедрите canary-развёртывания для новых версий приложений. Направляйте небольшой процент трафика на новую версию и следите за метриками. При обнаружении проблем автоматически откатывайтесь. Для инфраструктурных изменений используйте тестовые кластеры, идентичные production по конфигурации.
Заключение: чек-лист для предотвращения ошибок в Kubernetes
Проверьте свой кластер по этому списку:
- Все контейнеры имеют requests и limits, значения основаны на реальных метриках.
- RBAC настроен по принципу наименьших привилегий, нет лишних cluster-admin.
- Версия Kubernetes входит в три последние поддерживаемые.
- NetworkPolicy ограничивают трафик между namespace'ами.
- Prometheus и Alertmanager собирают метрики и отправляют алерты.
- ResourceQuota и LimitRange установлены для всех namespace'ов.
- Секреты зашифрованы в etcd и управляются через внешние системы.
- Резервные копии etcd и PV создаются регулярно и проверяются.
- Поды запускаются без root-прав и привилегированного режима.
- Изменения применяются через GitOps с тестированием в staging.
Каждый пункт этого чек-листа закрывает конкретный риск. Начните с аудита текущего состояния и устраняйте проблемы по приоритету. Для углублённого изучения самовосстановления и отказоустойчивости обратитесь к материалу о механизмах самовосстановления Kubernetes.