Стадия жизненного цикла модуля: Общедоступная версия
У модуля есть требования для установки
Карта рантайм-поведения — это предварительная функция, по умолчанию она отключена.
Помимо статического сканирования (уязвимости образов, аудит конфигурации, CIS) модуль может наблюдать, что каждая рабочая нагрузка делает во время выполнения (рантайм), и превращать эти наблюдения в карту по каждой рабочей нагрузке.
Что содержит карта
При включении карты на каждом узле работает агент, который наблюдает за поведением каждого контейнера с помощью eBPF. Наблюдения агрегируются по рабочим нагрузкам (Deployment, DaemonSet, StatefulSet, …) в два объекта:
- ApplicationProfile — процессы, которые запускает рабочая нагрузка, файлы, которые она открывает, а также используемые ею Linux capabilities и системные вызовы (отпечаток приложения);
- NetworkNeighborhood — входящие и исходящие соединения рабочей нагрузки с указанием другой стороны соединения и порта (карта сети).
Оба объекта строятся по поведению, наблюдаемому в работающем кластере, а не по манифестам рабочих нагрузок.
Требования
Для работы карты рантайм-поведения требуется:
- ядра узлов Linux 5.4 или новее, предоставляющие BTF в
/sys/kernel/btf/vmlinux; - возможность запуска привилегированного агента с доступом к host PID. По умолчанию агент запускается на всех узлах;
ограничьте его параметром
nodeAgent.nodeSelector, если часть узлов не удовлетворяет требованию к ядру. Опциональный параметрnodeAgent.tolerationsуправляет запуском на узлах с taint; - StorageClass для данных модуля на базе блочных сетевых или локальных устройств или локальных путей (localpath).
Модуль хранит карту в собственной встроенной базе данных (security-storage), а не в etcd кластера.
Не используйте StorageClass на базе сетевых файловых или объектных хранилищ, например NFS, CephFS или S3.
Параметр
apiServerStorageClassзадаёт StorageClass для security-storage. Размер PVC задаётся параметромsecurityStoragePVCRequest(по умолчанию10ГиБ).
Включение
Включите карту рантайм-поведения в ModuleConfig operator-trivy:
apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
name: operator-trivy
spec:
settings:
nodeAgent:
enabled: true
learningPeriod: "1h"
version: 2learningPeriod задаёт, сколько времени наблюдается каждый контейнер, прежде чем его профиль считается завершённым.
В течение этого окна карта продолжает вбирать вновь увиденное поведение; после — профиль фиксируется.
Для рабочих нагрузок, поведение которых меняется в течение суток, используйте большее значение (например, 24h).
Просмотр карты
Объекты карты — namespaced-объекты, они находятся в тех же неймспейсах, что и рабочие нагрузки, которые они описывают.
Чтобы получить отпечатки приложений по всему кластеру, выполните:
d8 k get applicationprofiles -AЧтобы получить карты сети по всему кластеру, выполните:
d8 k get networkneighborhoods -AЧтобы получить полный отпечаток одной рабочей нагрузки, выполните:
d8 k -n <NAMESPACE> get applicationprofile <NAME> -o yamlГде:
<NAMESPACE>— неймспейс рабочей нагрузки;<NAME>— имя ApplicationProfile из вывода командыd8 k get applicationprofiles -A.
Записанные детали (процессы, файлы, capabilities, соединения) возвращает только запрос конкретного объекта по имени, например d8 k -n <NAMESPACE> get applicationprofile <NAME> -o yaml.
Любой списочный запрос, с -A или без, возвращает объекты без этих полей, поэтому в списке они всегда выглядят «пустыми».
Данные начинают появляться в течение нескольких минут после старта контейнера;
профиль продолжает расти и помечается завершённым по истечении периода обучения контейнера.
Дайте только что включённой рабочей нагрузке хотя бы learningPeriod, прежде чем ожидать полную карту.
Генерация политик с минимальными привилегиями
Когда карта рабочей нагрузки построена, модуль может превратить её в политики с минимальными привилегиями. Включите одну или обе генерации:
spec:
settings:
nodeAgent:
enabled: true
generatePolicies:
networkPolicy: true
seccomp: true
version: 2Сетевые политики
При networkPolicy: true из наблюдаемого NetworkNeighborhood каждой рабочей нагрузки вычисляется GeneratedNetworkPolicy — готовая к проверке Kubernetes NetworkPolicy, описывающая ровно тот трафик, который у рабочей нагрузки наблюдался.
Чтобы получить сгенерированные политики по всему кластеру, выполните:
d8 k get generatednetworkpolicies -AЧтобы получить политику одной рабочей нагрузки, выполните:
d8 k -n <NAMESPACE> get generatednetworkpolicy <NAME> -o yamlГде:
<NAMESPACE>— неймспейс рабочей нагрузки;<NAME>— имя GeneratedNetworkPolicy из вывода командыd8 k get generatednetworkpolicies -A.
Объект содержит стандартную NetworkPolicy в .spec.
Проверьте её, затем извлеките и примените, чтобы ограничить трафик минимально необходимым:
d8 k -n <NAMESPACE> get generatednetworkpolicy <NAME> -o json | jq '.spec' | d8 k apply -f -Seccomp-профили
При seccomp: true модуль генерирует SeccompProfile из наблюдаемых системных вызовов каждой рабочей нагрузки и обновляет его каждые 10 минут.
SeccompProfile содержит отдельный профиль для каждого контейнера рабочей нагрузки в .spec.containers[].spec.
Профили генерируются только для архитектур x86 (SCMP_ARCH_X86_64, SCMP_ARCH_X86, SCMP_ARCH_X32), поэтому используйте их только для подов, которые запускаются на узлах x86-64.
Чтобы получить список сгенерированных профилей, выполните:
d8 k get seccompprofiles.spdx.softwarecomposition.kubescape.io -AМодуль не копирует профили на узлы. Чтобы использовать профиль, выполните следующие шаги:
-
Извлеките профиль одного контейнера в файл:
d8 k -n <NAMESPACE> get seccompprofiles.spdx.softwarecomposition.kubescape.io <NAME> -o json | jq '.spec.containers[] | select(.name == "<CONTAINER_NAME>") | .spec' > <PROFILE_FILE>.jsonГде:
<NAMESPACE>— неймспейс рабочей нагрузки;<NAME>— имя SeccompProfile из вывода предыдущей команды;<CONTAINER_NAME>— имя контейнера;<PROFILE_FILE>— имя файла профиля.
-
Скопируйте файл в директорию seccomp kubelet
<KUBELET_ROOT>/seccomp/на каждом узле, где может запускаться под.<KUBELET_ROOT>— корневая директория kubelet, по умолчанию/var/lib/kubelet. -
Укажите профиль в security context контейнера. Путь в
localhostProfileзадаётся относительно<KUBELET_ROOT>/seccomp/:spec: containers: - name: <CONTAINER_NAME> securityContext: seccompProfile: type: Localhost localhostProfile: <PROFILE_FILE>.json
Всегда проверяйте сгенерированную политику перед её применением. Профиль отражает только то поведение, которое наблюдалось в период обучения; редко используемые ветки кода могут отсутствовать, поэтому сначала проверьте под характерной нагрузкой.