Безопасность Kubernetes: практическое руководство по RBAC, NetworkPolicies и управлению секретами | AdminWiki

Безопасность Kubernetes: практическое руководство по RBAC, NetworkPolicies и управлению секретами

16 августа 2026 9 мин. чтения

Введение: почему безопасность Kubernetes требует особого внимания

Kubernetes управляет контейнерами на тысячах узлов, и каждая ошибка в настройке доступа открывает путь к компрометации всего кластера. По данным CNCF, число production-кластеров растет на 28% ежегодно, а вместе с ними растет и число атак на cloud-native инфраструктуру. Злоумышленники ищут открытые API, избыточные права и секреты в открытом виде.

Безопасность кластера держится на трех опорах: контроль доступа, сетевая сегментация и защита чувствительных данных. Если RBAC настроен с избыточными правами, NetworkPolicies отсутствуют, а секреты лежат в base64, кластер уязвим. В этом руководстве вы настроите каждую из этих областей на практике: создадите роли с минимальными привилегиями, изолируете сетевой трафик между сервисами и выстроите безопасное хранение секретов. В конце получите готовый чек-лист для аудита.

Материал адресован администраторам и DevOps-инженерам, которые отвечают за безопасность контейнерных платформ. Все команды и YAML-манифесты проверены на Kubernetes 1.30 и совместимы с актуальными версиями.

RBAC: детальное разделение прав доступа

RBAC (Role-Based Access Control) определяет, кто и что может делать в кластере. Без него любой пользователь с доступом к API получает права администратора. Настройка RBAC снижает риск несанкционированных действий и ограничивает ущерб при компрометации учетной записи.

Основные понятия RBAC: Role, ClusterRole, Binding

Role действует в пределах одного namespace. ClusterRole работает на уровне всего кластера. Разница принципиальна: Role не может выдать права на узлы, PersistentVolumes или другие cluster-scoped ресурсы.

Binding связывает субъектов с ролями. RoleBinding применяет Role к пользователям, группам или ServiceAccount в конкретном namespace. ClusterRoleBinding применяет ClusterRole ко всему кластеру. Субъектами могут быть пользователи, группы и ServiceAccount.

Пример Role, которая разрешает чтение подов в namespace development:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: development
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]

Связывание этой роли с ServiceAccount команды разработки:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: dev-pod-reader
  namespace: development
subjects:
- kind: ServiceAccount
  name: dev-team
  namespace: development
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

Пошаговая настройка RBAC для команды разработки

Сценарий: команда разработки должна управлять подами в своем namespace development, но не иметь доступа к другим namespace и cluster-scoped ресурсам.

Шаг 1. Создайте namespace и ServiceAccount:

kubectl create namespace development
kubectl create serviceaccount dev-team -n development

Шаг 2. Создайте Role с правами на управление подами, деплойментами и сервисами:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: development
  name: dev-full-access
rules:
- apiGroups: [""]
  resources: ["pods", "services", "configmaps"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

Шаг 3. Создайте RoleBinding:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: dev-full-access-binding
  namespace: development
subjects:
- kind: ServiceAccount
  name: dev-team
  namespace: development
roleRef:
  kind: Role
  name: dev-full-access
  apiGroup: rbac.authorization.k8s.io

Шаг 4. Проверьте доступ:

kubectl auth can-i create pods --as=system:serviceaccount:development:dev-team -n development
# yes
kubectl auth can-i create pods --as=system:serviceaccount:development:dev-team -n production
# no

Команда kubectl auth can-i показывает, какие действия разрешены для конкретного субъекта. Это основной инструмент проверки RBAC.

Лучшие практики RBAC

Используйте группы для управления доступом, а не отдельные привязки для каждого пользователя. Привязывайте роли к группам через ClusterRoleBinding с указанием группы в subjects. Это упрощает управление при росте команды.

Избегайте использования cluster-admin для повседневных задач. Выдавайте cluster-admin только при начальной настройке кластера и для аварийного восстановления. Для регулярной работы создавайте роли с минимальными правами.

Регулярно аудируйте роли. Команда kubectl get rolebindings --all-namespaces показывает все привязки. Ищите субъектов с правами на delete, update для критичных ресурсов. Подробнее об аудите RBAC читайте в руководстве по аудиту безопасности Kubernetes.

Принцип наименьших привилегий работает так: если команде не нужны права на удаление, не выдавайте их. Лучше добавить права позже, чем удалять после инцидента.

NetworkPolicies: сегментация сетевого трафика

По умолчанию все поды в кластере могут общаться друг с другом. Это удобно для разработки, но опасно для production: если атакующий получит доступ к одному поду, он сможет атаковать все остальные. NetworkPolicies ограничивают сетевые взаимодействия на уровне подов.

Как работают NetworkPolicies: селекторы и правила

NetworkPolicy использует podSelector для выбора подов, к которым применяется политика. policyTypes указывает, какие направления трафика контролируются: Ingress, Egress или оба. Правила ingress и egress определяют, от кого и куда разрешен трафик.

Пример политики, которая разрешает входящий трафик только от подов с меткой app=frontend:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-from-frontend
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - protocol: TCP
      port: 8080

Если в namespace нет ни одной NetworkPolicy, весь трафик разрешен. Первая политика с podSelector, который выбирает все поды (пустой matchLabels), запускает режим default deny.

Практические примеры: изоляция приложений

Пример 1. Default deny для всего namespace:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: production
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress

Эта политика блокирует весь входящий и исходящий трафик для всех подов в namespace production. После ее применения нужно явно разрешать каждый легитимный поток.

Пример 2. Разрешение трафика от ingress controller:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-from-ingress
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: web
  policyTypes:
  - Ingress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: ingress-nginx
    ports:
    - protocol: TCP
      port: 80
    - protocol: TCP
      port: 443

Пример 3. Разрешение egress только к определенному внешнему ресурсу:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-egress-to-db
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
  - Egress
  egress:
  - to:
    - ipBlock:
        cidr: 10.0.0.0/24
    ports:
    - protocol: TCP
      port: 5432

Выбор CNI-плагина с поддержкой NetworkPolicies

NetworkPolicy - это API-объект, но его применяет CNI-плагин. Не все CNI поддерживают политики. Calico, Cilium и Weave Net реализуют полную поддержку NetworkPolicy. Flannel не поддерживает политики без дополнительных компонентов.

Calico - проверенное решение для production-кластеров, поддерживает NetworkPolicy и расширенные сетевые политики. Cilium использует eBPF и предлагает более высокую производительность и наблюдаемость. Weave Net проще в настройке, но менее распространен в крупных кластерах. Выбор зависит от требований к производительности и функциональности. Для большинства сценариев Calico или Cilium - оптимальный выбор.

Управление секретами: от нативных Secrets до внешних систем

Секреты содержат пароли, токены, ключи API. Их компрометация дает атакующему доступ к базам данных, внешним сервисам и внутренним системам. Управление секретами требует отдельного подхода.

Проблемы нативных Kubernetes Secrets

Нативные Secrets хранятся в etcd в base64. Base64 - это кодирование, а не шифрование. Любой, кто получит доступ к etcd или к объекту Secret через API, сможет декодировать данные. По умолчанию etcd не шифрует данные на диске.

Доступ к Secret через API означает доступ к данным. Если у пользователя есть права get на secrets в namespace, он видит все пароли этого namespace. Это создает риск при избыточных RBAC-правах. Подробнее о работе с нативными Secrets читайте в полном руководстве по Kubernetes Secrets.

Sealed Secrets: шифрование секретов для GitOps

Sealed Secrets решает проблему хранения секретов в Git. Вы шифруете секрет с помощью kubeseal, получаете манифест SealedSecret, который можно безопасно коммитить в репозиторий. Расшифровать его может только контроллер Sealed Secrets в кластере.

Установка контроллера:

kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.27.1/controller.yaml

Шифрование секрета:

kubectl create secret generic db-password --from-literal=password=MySecret123 -n production --dry-run=client -o yaml | kubeseal --format yaml > sealed-secret.yaml

Полученный sealed-secret.yaml можно коммитить в Git. Контроллер в кластере расшифрует его и создаст обычный Secret. Приватный ключ хранится только в кластере, что делает манифест бесполезным для посторонних.

Интеграция с HashiCorp Vault

HashiCorp Vault централизует управление секретами: хранение, ротацию, аудит и доступ. Интеграция с Kubernetes позволяет синхронизировать секреты из Vault в Kubernetes Secrets или монтировать их напрямую через CSI driver.

Практичный способ - External Secrets Operator. Он создает Kubernetes Secrets из секретов Vault по расписанию. Установка:

helm repo add external-secrets https://charts.external-secrets.io
helm install external-secrets external-secrets/external-secrets -n external-secrets --create-namespace

Настройка SecretStore для подключения к Vault:

apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
  name: vault-backend
  namespace: production
spec:
  provider:
    vault:
      server: "https://vault.example.com"
      path: "secret"
      auth:
        kubernetes:
          mountPath: "kubernetes"
          role: "k8s-role"

Создание ExternalSecret для синхронизации:

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: db-credentials
  namespace: production
spec:
  refreshInterval: "1h"
  secretStoreRef:
    name: vault-backend
    kind: SecretStore
  target:
    name: db-credentials
    creationPolicy: Owner
  data:
  - secretKey: password
    remoteRef:
      key: db/password
      property: value

Преимущества Vault: автоматическая ротация, детальный аудит, единое хранилище для всех кластеров. Сравнение нативных Secrets и внешних систем читайте в статье о выборе хранилища секретов.

Шифрование Secrets at rest

Даже при использовании внешних систем нативные Secrets остаются в etcd. Включите шифрование at rest, чтобы защитить их на диске.

Создайте файл EncryptionConfiguration:

apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
  - secrets
  providers:
  - aescbc:
      keys:
      - name: key1
        secret: 
  - identity: {}

Передайте файл в kube-apiserver через флаг --encryption-provider-config. После включения шифрования все новые секреты будут зашифрованы. Существующие секреты нужно пересоздать: kubectl get secrets --all-namespaces -o json | kubectl replace -f -.

Сохраните резервную копию ключа шифрования. Потеря ключа означает невозможность расшифровать секреты.

Чек-лист аудита безопасности кластера

Этот чек-лист поможет проверить соответствие требованиям и выявить уязвимости. Выполняйте его регулярно, минимум раз в квартал или после значительных изменений в кластере.

Проверка RBAC

  • Выполните kubectl get clusterrolebindings и найдите всех субъектов с cluster-admin. Их должно быть минимальное количество.
  • Выполните kubectl auth can-i --list --as=system:serviceaccount:default:default для проверки прав сервисного аккаунта по умолчанию.
  • Проверьте, что нет RoleBinding, которые выдают права на secrets для широкого круга пользователей.
  • Используйте kubectl get rolebindings --all-namespaces -o yaml и ищите подозрительные привязки.

Проверка NetworkPolicies

  • Убедитесь, что в каждом production-namespace есть default deny политика.
  • Проверьте, что CNI-плагин поддерживает NetworkPolicy: kubectl get pods -n kube-system | grep calico или cilium.
  • Протестируйте доступ между подами: kubectl exec -it pod-a -- curl pod-b. Если доступ есть, а политика запрещает, CNI не применяет политики.
  • Проверьте, что egress-трафик ограничен там, где это необходимо.

Проверка управления секретами

  • Проверьте, включено ли шифрование at rest: kubectl get secrets --all-namespaces -o json | grep -c "aescbc". Если 0, шифрование не работает.
  • Убедитесь, что секреты не хранятся в образах: сканируйте образы на наличие паролей и ключей.
  • Проверьте, что секреты не закоммичены в Git в открытом виде.
  • Если используются внешние системы, проверьте настройки ротации и аудита.

Дополнительные проверки

  • Примените Pod Security Standards: kubectl label namespace production pod-security.kubernetes.io/enforce=restricted.
  • Проверьте версии компонентов: kubectl version. Обновляйте Kubernetes минимум раз в 6 месяцев.
  • Настройте аудит API server и проверяйте логи на подозрительные действия.
  • Сканируйте образы на уязвимости с помощью Trivy или Grype.
  • Запустите kube-bench для проверки соответствия CIS Benchmark.

Полный план аудита безопасности с готовыми командами читайте в практическом плане аудита IT-инфраструктуры.

Заключение

Безопасность Kubernetes - это три уровня: RBAC ограничивает доступ, NetworkPolicies сегментируют сеть, управление секретами защищает чувствительные данные. Каждый уровень требует настройки и регулярной проверки.

Начните с RBAC: создайте роли с минимальными привилегиями, избегайте cluster-admin, используйте группы. Затем примените NetworkPolicies: включите default deny в production-namespace и явно разрешите легитимный трафик. Защитите секреты: включите шифрование at rest, используйте Sealed Secrets для GitOps или интегрируйтесь с Vault через External Secrets Operator.

Безопасность - непрерывный процесс. Запускайте чек-лист аудита регулярно, обновляйте компоненты, сканируйте образы. Каждая проверка снижает риск компрометации. Для углубленного изучения настройки RBAC читайте практическое руководство по RBAC, а для настройки аудита API server - руководство по аудиту безопасности.

Поделиться:
Сохранить гайд? В закладки браузера