Стадия жизненного цикла модуля: Общедоступная версия
У модуля есть требования для установки
Как собирать события?
Поды runtime-audit-engine выводят все события в стандартный вывод.
Далее агенты log-shipper могут собирать их и отправлять в хранилище логов.
Пример конфигурации ClusterLoggingConfig для модуля log-shipper:
apiVersion: deckhouse.io/v1alpha2
kind: ClusterLoggingConfig
metadata:
name: falco-events
spec:
destinationRefs:
- xxxx
kubernetesPods:
namespaceSelector:
labelSelector:
matchExpressions:
- key: "kubernetes.io/metadata.name"
operator: In
values: [d8-runtime-audit-engine]
labelFilter:
- operator: Regex
values: ["\\{.*"] # Для сбора логов только в формате JSON.
field: "message"
type: KubernetesPodsКак оповещать о критических событиях?
Оповещения о критических событиях настраиваются двумя способами: через модуль security-events-manager либо через собственное правило Prometheus.
Основной способ — модуль security-events-manager. Он собирает события Falco из логов, приводит их к единому формату и вычисляет по ним правила оповещения, поэтому правило описывается в терминах событий безопасности, а не метрик.
Интеграция поставляется вместе с модулем runtime-audit-engine: для встроенных правил Falco создаются ресурсы SecurityEventDefinition и PodSecurityEventShipper, поэтому события попадают в конвейер обработки сразу после включения обоих модулей. Настройка правил оповещения описана в разделе «Алертинг по событиям безопасности».
Второй способ — правило Prometheus по метрикам, которые модуль экспортирует автоматически. Он не требует дополнительных модулей, но оперирует счётчиками событий, а не их содержимым.
Чтобы включить оповещения, добавьте в кластер правило CustomPrometheusRule.
Пример настройки такого правила:
apiVersion: deckhouse.io/v1
kind: CustomPrometheusRules
metadata:
name: falco-critical-alerts
spec:
groups:
- name: falco-critical-alerts
rules:
- alert: FalcoCriticalAlertsAreFiring
for: 1m
annotations:
description: |
There is a suspicious activity on a node {{ $labels.node }}.
Check you events journal for more details.
summary: Falco detects a critical security incident
expr: |
sum by (node) (rate(falcosecurity_falcosidekick_falco_events_total{priority_raw="critical"}[5m]) > 0)В метрике falcosecurity_falcosidekick_falco_events_total уровень важности события передаётся двумя лейблами: priority содержит числовое значение, а priority_raw — название уровня строчными буквами. Фильтруйте события по лейблу priority_raw; соответствие числовых и текстовых значений приведено в разделе «Просмотр метрик».
Пример выше охватывает только уровни от emergency до debug. У события, пришедшего без приоритета, лейбл priority_raw пустой, и ни один селектор по priority_raw его не выбирает — если такие события нужно учитывать, добавьте в алерт условие по priority.
Алерты лучше всего работают в комбинации с хранилищами событий, такими как Elasticsearch или Loki. Их задача — оповестить пользователя о подозрительном поведении на узле. После получения алерта рекомендуется обратиться к хранилищу и посмотреть на события, которые его вызвали.
Как применить правила для Falco, найденные в интернете?
Структура правил Falco отличается от схемы CRD. Это связано со сложностями при проверке правильности ресурсов в Kubernetes.
Скрипт для конвертации правил Falco в ресурсы FalcoAuditRules встроен в функционал утилиты d8.
С его помощью можно применять правила Falco в Deckhouse:
d8 tools far-converter /path/to/falco/rule_example.yaml > ./my-rules-cr.yamlПример результата работы скрипта:
# /path/to/falco/rule_example.yaml
- macro: spawned_process
condition: (evt.type in (execve, execveat) and evt.dir=<)
- rule: Linux Cgroup Container Escape Vulnerability (CVE-2022-0492)
desc: "This rule detects an attempt to exploit a container escape vulnerability in the Linux Kernel."
condition: container.id != "" and proc.name = "unshare" and spawned_process and evt.args contains "mount" and evt.args contains "-o rdma" and evt.args contains "/release_agent"
output: "Detect Linux Cgroup Container Escape Vulnerability (CVE-2022-0492) (user=%user.loginname uid=%user.loginuid command=%proc.cmdline args=%proc.args)"
priority: CRITICAL
tags: [process, mitre_privilege_escalation]# ./my-rules-cr.yaml
apiVersion: deckhouse.io/v1alpha1
kind: FalcoAuditRules
metadata:
name: rule-example
spec:
rules:
- macro:
name: spawned_process
condition: (evt.type in (execve, execveat) and evt.dir=<)
- rule:
name: Linux Cgroup Container Escape Vulnerability (CVE-2022-0492)
condition: container.id != "" and proc.name = "unshare" and spawned_process and evt.args contains "mount" and evt.args contains "-o rdma" and evt.args contains "/release_agent"
desc: This rule detects an attempt to exploit a container escape vulnerability in the Linux Kernel.
output: Detect Linux Cgroup Container Escape Vulnerability (CVE-2022-0492) (user=%user.loginname uid=%user.loginuid command=%proc.cmdline args=%proc.args)
priority: Critical
tags:
- process
- mitre_privilege_escalationКак настраивать ресурсы для DaemonSet?
Модуль runtime-audit-engine позволяет гибко настраивать запросы ресурсов для своего DaemonSet. Это особенно полезно в гетерогенных кластерах, где узлы имеют разную производительность.
Режимы управления ресурсами
Вы можете выбрать один из двух режимов управления запросами ресурсов с помощью параметра resourcesRequests.mode:
- Static: вы явно указываете ресурсы для подов. См. resourcesRequests.static.
- VPA: ресурсы управляются автоматически с помощью Vertical Pod Autoscaler. См. resourcesRequests.vpa.
Пример статической конфигурации:
spec:
settings:
resourcesRequests:
mode: Static
static:
cpu: "100m"
memory: "256Mi"Разделение рекомендаций VPA (Scoping)
VPA Scoping — это механизм, который позволяет Vertical Pod Autoscaler генерировать независимые рекомендации по ресурсам для разных групп подов внутри одного DaemonSet. Это критически важно для кластеров с гетерогенными узлами, где одна и та же нагрузка (например, Falco) может потреблять существенно разное количество ресурсов в зависимости от характеристик узла.
Как это работает
По умолчанию в Deckhouse версии 1.76 и выше модуль использует параметр resourcesRequests.vpa.scopeLabel со стандартным значением node.deckhouse.io/group.
VPA отслеживает указанную метку на узлах и автоматически разделяет поды DaemonSet на подгруппы:
__absent__: узлы, на которых указанный ключ метки отсутствует.""(пустая строка): узлы, на которых ключ метки существует, но не имеет значения.- Конкретные значения: для каждого уникального значения метки создается отдельная группа рекомендаций (например,
worker,system,gpu).
Когда требуется изменение метки области видимости
Вам может потребоваться изменить scopeLabel, если потребление ресурсов зависит от факторов, отличных от стандартных групп узлов Deckhouse. Например, в Yandex Cloud вы можете захотеть сгруппировать рекомендации по физическому размеру (flavor) инстанса или по кастомным маркерам оборудования.
Пример: группировка по типу инстанса Yandex Cloud с использованием метки node.kubernetes.io/instance-type:
apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
name: runtime-audit-engine
spec:
version: 1
enabled: true
settings:
resourcesRequests:
mode: VPA
vpa:
mode: Auto
scopeLabel: "node.kubernetes.io/instance-type"При такой конфигурации под, запущенный на инстансе c3-m8, получит от VPA рекомендацию, отличную от пода на инстансе s2-m2, что обеспечит оптимальное распределение ресурсов во всей вашей облачной инфраструктуре.
Взаимодействие LimitRange и VPA
LimitRange опционален и по умолчанию не используется.
Используйте resourcesRequests.limitRange так:
false— явно не создаватьLimitRange;- объект — создать
LimitRangeс указанными ограничениями.
Важно: при использовании VPA значения LimitRange действуют как жесткие границы. Рекомендации VPA будут ограничены значениями max и дополнены значениями min, определенными в LimitRange.
Как заполнить LimitRange
Параметр limitRange принимает только false или объект. Значение true не проходит валидацию.
Ключи containerDefault, containerDefaultRequest, containerMax и containerMin
указывайте внутри limitRange, а не рядом с ним.
Пример ниже задаёт запросы ресурсов для Falco и лимиты для всех контейнеров модуля:
apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
name: runtime-audit-engine
spec:
version: 1
enabled: true
settings:
resourcesRequests:
mode: Static
static: # Запросы ресурсов контейнера Falco.
cpu: 150m
memory: 256Mi
limitRange: # На одном уровне со static, а не внутри него.
containerDefault: # Лимиты каждого контейнера модуля.
cpu: 2000m
memory: 1Gi
containerMax: # Верхняя граница лимитов и запросов.
cpu: 2000m
memory: 1GiМодуль создаст LimitRange falco-leak-limiting в неймспейсе d8-runtime-audit-engine.
Чтобы проверить его, выполните команду:
d8 k -n d8-runtime-audit-engine get limitrange falco-leak-limiting -o yamlОграничения LimitRange
LimitRange действует на все контейнеры неймспейса d8-runtime-audit-engine, а не только на Falco.
Выбирайте значения с учётом следующих правил:
containerDefaultстановится лимитом каждого контейнера модуля, включая Falco, потому что сам модуль лимиты контейнерам не задаёт. По умолчанию лимит памяти —1Gi. Потребление памяти Falco растёт с числом CPU узла, поэтому перед уменьшением лимита проверьте Grafana-дашбордRuntime audit engine. ЗадавайтеcontainerDefaultне ниже запросов ресурсов Falco из секцииstatic. Иначе лимит Falco окажется ниже запроса, и API-сервер отклонит под.containerMaxдолжен быть не нижеcontainerDefaultи запросов ресурсов Falco из секцииstatic. В режимеVPAзапросы ресурсов Falco задаёт VPA — не больше100mCPU и300Miпамяти.containerMinдействует на запросы ресурсов каждого контейнера. Задавайте его не выше наименьшего запроса среди контейнеров модуля:5mCPU и10Miпамяти. Если ограничение снизу не требуется, не указывайтеcontainerMin.containerDefaultRequestприменяется к контейнерам, у которых при создании пода нет запросов CPU или памяти. В режимеStaticзапросы ресурсов заданы у всех контейнеров модуля, поэтому параметр ни на что не влияет. В режимеVPAон применяется к контейнерамfalco,falcosidekick,rules-loaderиkube-rbac-proxyDaemonSet, пока VPA не заменит их запросы своей рекомендацией. Задавайте его в пределах отcontainerMinдоcontainerMax.
Если задан containerDefault.cpu, а containerDefaultRequest.cpu — нет,
Kubernetes использует containerDefault.cpu как запрос CPU по умолчанию.
В режиме VPA, пока у VPA нет рекомендации, например сразу после включения модуля,
каждый из четырёх контейнеров DaemonSet выше запросит весь лимит CPU, например 2000m.
Чтобы этого избежать, задайте containerDefaultRequest.cpu явно, например 10m.
Контейнеры модуля запрашивают следующие ресурсы:
| Контейнер | CPU | Память |
|---|---|---|
falco |
static.cpu, по умолчанию 50m |
static.memory, по умолчанию 64Mi |
falcosidekick |
5m |
10Mi |
rules-loader |
10m |
25Mi |
rules-preload (init-контейнер) |
10m |
25Mi |
kube-rbac-proxy |
10m |
25Mi |
k8s-metacollector |
10m |
25Mi |
В режиме VPA запросы ресурсов контейнеров DaemonSet задаёт VPA в границах LimitRange.
Запрос ниже значения из таблицы VPA не устанавливает, для falco — ниже 50m CPU и 64Mi памяти.
Если запрос ресурсов контейнера ниже containerMin, API-сервер отклонит под и поды модуля не будут созданы.
Почему Falco потребляет на одном узле больше ресурсов, чем на другом?
Потребление ресурсов Falco зависит в основном от нагрузки на узле.
Потребление памяти зависит также от числа CPU узла:
Falco выделяет кольцевой буфер ядра на каждые два CPU.
Чтобы найти причину, сравните узлы в строке Node load comparison
Grafana-дашборда Runtime audit engine.
Строка содержит следующие панели:
Kernel events rate— число событий ядра в секунду, которые Falco получает на узле. Потребление CPU процессом Falco растёт вместе с этим значением. Число событий зависит от числа процессов и от их файловой и сетевой активности.Rule matches rate— число срабатываний правил в секунду в разрезе источников событий. Falco тратит процессорное время на формирование каждого события и его отправку вfalcosidekick.Dropped kernel events rate— число событий ядра в секунду, которые Falco потерял, в основном из-за переполнения кольцевого буфера между ядром и Falco.Containers on node— число контейнеров, которые Falco отслеживает на узле.Top rule matches— десять правил с наибольшим числом срабатываний за выбранный период на каждом узле.
События аудита Kubernetes поступают только на узлы control plane.
На этих узлах Falco обрабатывает также события аудита,
поэтому потребление CPU и число срабатываний правил с источником k8s_audit на них выше, чем на остальных узлах.
Чтобы выяснить, почему узел потребляет больше ресурсов, выполните следующие шаги:
- Сравните панель
CPUв строкеFalcoс панельюKernel events rate. Если потребление CPU пропорционально числу событий, разница вызвана нагрузкой на узле. Такое поведение ожидаемо. - Если на одном из узлов значение
Rule matches rateзаметно выше, найдите в таблицеTop rule matchesправила, которые срабатывают на этом узле. Дополнительную нагрузку создают эти правила и приложения, которые их вызывают. - Сравните панель
Memoryс панелямиContainers on nodeиScap threads. Falco хранит каждый процесс узла в таблице потоков, поэтому потребление памяти растёт с числом контейнеров и процессов. На узлах с большим числом CPU к потреблению памяти добавляются кольцевые буферы. - Если значение
Dropped kernel events rateбольше нуля, Falco не успевает обрабатывать события узла, и правила могут пропустить активность на нём. Убедитесь, что CPU узла не загружен полностью. Убедитесь также, что параметр resourcesRequests.limitRange не задаёт для контейнера Falco низкий лимит CPU.
В режиме VPA в Deckhouse версии 1.76 и выше
Vertical Pod Autoscaler рассчитывает рекомендации по ресурсам отдельно для каждой группы узлов.
В более ранних версиях Deckhouse VPA рассчитывает одну рекомендацию для всех узлов,
и совет ниже неприменим.
Если сильно нагруженные узлы находятся в одной группе со слабо нагруженными, перенесите их в отдельную группу узлов
или укажите в параметре resourcesRequests.vpa.scopeLabel
метку, которая их разделяет.
Falco экспортирует эти метрики при каждом опросе Prometheus. Детализация данных на дашборде равна интервалу опроса Prometheus.