
Ландшафт безопасности
Предприятия всех размеров — крупные, малые и средние — используют Kubernetes в качестве отраслевого стандарта. Отчет Dynatrace «Kubernetes in the wild report 2023» демонстрирует ежегодный прирост числа кластеров Kubernetes в облаке на 127% и на 27% для локальных кластеров. Также сообщается, что 48% организаций ожидают значительного (50-100%) или резкого (100%+) роста количества своих кластеров K8s.
Кажется, что чем больше кластеров, тем лучше, поскольку Kubernetes предназначен для решения проблем, с которыми мы все сталкиваемся. Это действительно оптимизирует операции, ускоряет доставку, повышает ежедневную скорость развертывания и т. д. Но что может пойти не так?
Обзор стандартов безопасности
Одним из самых известных является Kubernetes CIS Benchmark и содержит конкретные инструкции о том, как обеспечить безопасность кластера K8s — вплоть до того, какие флаги установить для сервера API. Вот что он проверяет в настройках Kubernetes:
- Компоненты плоскости управления:
- Файлы конфигурации узла;
- Плоскость управления;
- API-сервер;
- Диспетчер контроллеров;
- Планировщик и т.д.;
- Конфигурация плоскости управления:
- Аутентификация и авторизация;
- Ведение журнала и аудит;
- Рабочие узлы:
- Файлы конфигурации рабочего узла;
- Конфигурация Kubelet;
- Политики: RBAC, сервисные учетные записи, стандарты безопасности Pod и сетевые политики.
Существует множество других стандартов как коммерческих, так и некоммерческих организаций. Они дополняются всевозможными таблицами данных и контрольными списками от компаний, разрабатывающих ПО, связанное с безопасностью Kubernetes.
Модель 4С подсказывает:
- Начните с кода, чтобы защитить используемые приложения и библиотеки;
- Просканируйте контейнеры на уязвимости, проконтролируйте и защитите среду исполнения;
- Ограничьте доступ к плоскости управления Kubernetes и узлам кластера;
- Настройте безопасный доступ к облачным API и инфраструктуре.

Излишне говорить, что в случае, если злоумышленник получит доступ к облачному API, уже не имеет значения, какие уровни защиты ниже, т.е. насколько безопасен код в контейнере. Злоумышленник просто удалит виртуальные машины, сманипулирует данными на дисках и так далее.
Пять шагов к безопасности Kubernetes
- Правильная настройка кластеров Kubernetes;
- Сканирование образа;
- Сетевая безопасность;
- Контроль запущенных приложений;
- Аудит и регистрация событий.
Шаг №1: Правильная конфигурация кластера Kubernetes
- Начните с запуска эталонного теста CIS и проверьте, соответствуют ли настройки узла и уровня управления тем, которые указаны в стандарте. Kube-bench и Kubescape идеально подходят для этого. Все, что вам нужно сделать, это запустить один из них, изучить результаты теста и исправить все проблемы, о которых сообщается в предупреждениях.
- Если возможно, рекомендуется ограничить сетевой доступ к API Kubernetes, настроить белые списки, разрешить доступ только через VPN и т. д.
- Каждый пользователь, который обращается к Kubernetes API, должен быть идентифицирован. Это важно для последующих проверок и понимания, кто что сделал; он также пригодится для грануляции RBAC.
- Каждому пользователю должны быть предоставлены только те RBAC, которые ему необходимы. Предположим, что какой-то оператор в кластере получает список всех модулей. В этом случае ему не нужно позволять видеть все секреты, а тем более редактировать их.
Все это кажется достаточно простым. Тем не менее, есть реальный живой пример для рассмотрения.
Сотрудник Palark развернул кластеры Kubernetes у нескольких облачных провайдеров и провел тест CIS. Ошибок и предупреждений практически не было. Протестировал только рабочие узлы, поскольку не все провайдеры предлагают доступ к узлам плоскости управления. Затем он посмотрел, как реализован доступ к только что развернутому кластеру.
Изучив kubeconfig, он обнаружил, что группа system:masters использовалась. Хотя в первом пункте контрольного списка безопасности Kubernetes четко указано, что после развертывания кластера никто не должен проходить в нем аутентификацию как system:masters. Если злоумышленник получит доступ к этому kubeconfig, все ЦС в кластере придется переоформить, потому что без этого отозвать доступ у группы system:masters невозможно.
Как видите, даже облачные провайдеры могут нарушать правила безопасности, поэтому вам всегда следует помнить о них.
Шаг № 2: Сканирование образа
Пришло время подумать, какое программное обеспечение мы собираемся запускать в кластере и как обеспечить его безопасность. Очевидное решение — сканировать образы контейнеров, которые мы используем.
Вы можете сделать это на разных этапах, например:
- Сканировать их на этапе конвейера CI/CD,
- Настроить сканирование реестра по расписанию,
- Просканировать все образы, используемые в кластере Kubernetes.
Есть много инструментов для этого: например, Trivy от Aqua Security и Grype от Anchore.
После сканирования проанализируйте его результаты:
- Обязательно ищите критические проблемы и предупреждения, а также исследуйте найденные уязвимости. Оценивайте проблему рационально: даже если мы нашли критическую уязвимость, это не значит, что она на самом деле такая.
- Используйте базовые образы. Если у вас есть золотой образ и вы нашли в нем CVE, можете начать с простой замены образа контейнера и перезапуска конвейера CI/CD.
- Избегайте добавления ненужных зависимостей. Например, инструменты отладки всех видов никогда не должны попадать в рабочие образы.
- Для компилируемых языков необходимо собрать артефакт, скомпилировать в нем бинарник, скопировать его в золотой образ, а затем запустить его в продакшене.
Помните: чем больше количество избыточных зависимостей, тем выше риск наличия у них CVE.
Шаг № 3: Безопасность сети
- CNI в кластере должен поддерживать сетевые политики;
- Политики входа и выхода должны быть настроены для всех компонентов кластера;
- Установите «запретить все» в качестве политики по умолчанию и вручную разрешите всё необходимое.
Случай из реальной жизни. Клиент просит провести аудит настройки Kubernetes. Выглядит все нормально: K8s запущен, везде используются сертификаты, а разработчики имеют доступ только к пространству имен stage.
Однако это многопользовательский кластер. Разработчики ограничены stage, но на самом деле они могут попасть оттуда буквально куда угодно (например, добраться до производственных баз данных), так какотсутствует сегментация и изоляция сети. Что можно с этим сделать?
Например, использовать Cilium. Он имеет визуальный редактор, который позволяет настроить правильную политику всего за несколько кликов. Эта политика позволит разработчику работать только в пределах своего пространства имен и получать доступ к DNS Kubernetes. Вот как может выглядеть созданная политика исходящего трафика:

egress:
- toEndpoints:
- matchLabels:
io.kubernetes.pod.namespace: kube-system
k8s-app: kube-dns
toPorts:
- ports:
- port: "53"
protocol: UDP
rules:
dns:
- matchPattern: "*"
- toEndpoints:
- {}
В этом случае разработчик может получить доступ к базе данных только в среде stage.

- Не стоит надеяться, что все, что развернуто в частной среде, по умолчанию защищено. Мы должны следить за этими вещами и понимать, кто куда идет и что делает.
- Подход «политики как код» также важен. Подобно подходу «инфраструктура как код» (IaC), это означает, что политики безопасности хранятся в репозитории Git и развертываются вместе с приложением.
- Наконец, вы должны внедрить все эти вещи в самом начале. При внедрении нового компонента необходимо сразу наметить его сетевые взаимодействия и обозначить политики. Для установки политик в уже работающую инфраструктуру требуется гораздо больше усилий.
Шаг №4: Контроль запущенных приложений
Когда мы рассмотрели сетевую безопасность, необходимо обсудить концепцию среды выполнения — хоста, на котором запускаются контейнеры.
В Kubernetes запросы проходят по довольно длинной цепочке. Одна из его особенностей — Admission Controller, которая проверяет объекты, созданные в кластере. В Kubernetes 1.23 есть Pod Security Admission, который отвечает требованиям безопасности. Также есть стандарты безопасности подов, которые запрещают запуск подов от имени пользователя root, использование хост-сети и так далее. Если этих политик недостаточно, вы можете использовать один из вариантов:
Когда стандартов безопасности Pod недостаточно, можно организовать CRD OperationPolicy. Он работает поверх ресурсов Gatekeeper. Вот как выглядит его конфигурация:
apiVersion: deckhouse.io/v1alpha1
kind: OperationPolicy
metadata:
name: common
spec:
policies:
allowedRepos:
- myregistry.example.com
requiredResources:
limits:
- memory
requests:
- cpu
- memory
disallowedImageTags:
- latest
requiredProbes:
- livenessProbe
- readinessProbe
maxRevisionHistoryLimit: 3
imagePullPolicy: Always
priorityClassNames:
- production-high
checkHostNetworkDNSPolicy: true
checkContainerDuplicates: true
match:
namespaceSelector:
labelSelector:
matchLabels:
operation-policy.deckhouse.io/enabled: "true"
В нем вы можете обозначить передовые методы безопасности:
- Разрешены только trusted registries. Разработчикам не разрешается использовать образы Docker Hub для определенных пространств имен;
- Ресурсы pod (запросы, лимиты) должны быть указаны;
- Probes должны быть указаны;
- Применяется ограничение revision history limit;
- Требуется использование priorityClasses;
- Тег latest запрещен.
Определение политик безопасности приложений является обязательным. Больше контроля означает меньшую вероятность возникновения ошибки и раскрытия уязвимости.
Шаг № 5: Аудит и регистрация событий
Теперь, когда приложение запущено и работает, вам нужно посмотреть, что происходит в Kubernetes и системе в целом. Речь идет именно об аудите событий.
В Kubernetes есть встроенный аккуратный аудит «из коробки» — аудит Kubernetes API, который легко настроить. Журналы собираются и возвращаются в систему регистрации для дальнейшего анализа. Ниже приведен пример базовой политики сбора запросов, отправляемых модулям:
apiVersion: audit.k8s.io/v1
kind: Policy
omitStages:
- RequestReceived
rules:
- level: RequestResponse
resources:
- group: ""
resources: ["pods"]
Эта политика приведет к тому, что журнал будет выглядеть следующим образом:
{
"kind": "Event",
"apiVersion": "audit.k8s.io/v1",
"level": "RequestResponse",
"auditID": "28eff2fc-2e81-41c1-980b-35d446480e77",
"stage": "ResponseComplete",
"requestURI": "/api/v1/namespaces/default/pods/nginx-6799fc88d8-5p7x5",
"verb": "delete",
"user": {
"username": "system:serviceaccount:d8-service-accounts:gitlab-runner-deploy",
"uid": "fd5a6209-c893-4b77-adf7-90500ecd2723",
"groups": [
"system:serviceaccounts",
"system:serviceaccounts:d8-service-accounts",
"system:authenticated"
]
},
...
Недостаточно просто собирать такие события. Вы должны проанализировать их. Предположим, учетная запись службы удалила какой-то модуль или создала ресурс в продашкене. В этом случае это, вероятно, часть процесса развертывания. Однако, если бы это был обычный пользователь, было бы неплохо получать уведомления о его действиях.
Также необходимо регистрировать события в хост-ОС и в среде выполнения. Например, команда crictl exec может быть проигнорирована аудитом API Kubernetes, и мы можем не знать, что кто-то вошел в модуль. Кроме того, важно знать, какие процессы выполняются внутри контейнеров.
В можете использовать Falco. Он делает следующее:
- разбирает системные вызовы на хосте;
- извлекает журнал аудита из Kubernetes API через серверную часть веб-перехватчика;
- проверяет поток событий по настроенным правилам;
- отправляет оповещения, если правила нарушены.
Однако недостаточно просто генерировать метрики. Администратор кластера должен быть уведомлен, если в кластере происходит какая-либо подозрительная активность. Так как все метрики отправляются в Prometheus, для них нужно создать правило:
apiVersion: deckhouse.io/v1
kind: CustomPrometheusRules
metadata:
name: runtime-audit-pod-exec
spec:
groups:
- name: runtime-audit-pod-exec
rules:
- alert: RuntimeAuditPodExecAlerts
annotations:
description: |
There are suspicious attach/exec operations.
Check your events journal for more details.
summary: Falco detected a security incident
expr: |
sum(rate(falco_events{rule="Attach/Exec Pod"}[5m])) > 0
Falco полезен для решения реальных инцидентов, в том числе не связанных с безопасностью. Например, вы можете использовать его для поиска неисправного оператора в кластере, который незаконно удалил некоторые модули.
Наконец, одним из наиболее важных компонентов аудита и ведения журналов является реагирование на угрозы.
Заключение
Обеспечение безопасности — это итеративный процесс. Всегда есть возможности для улучшения, поскольку в Kubernetes есть много других важных аспектов безопасности, которые администраторы (и не только инженеры DevSecOps!) должны учитывать:
- Аутентификация и авторизация;
- Аудит RBAC;
- Управление секретами;
- Безопасность цепочки поставок:
- Предотвращение запуска образов с уязвимостями;
- Запуск только подписанных образов и использование cosign;
- Автоматическое создание политик с использованием режима обучения;
- Автоматические ответы на события аудита.
