Зачем Kubernetes audit log нужен в реальной эксплуатации
Kubernetes audit log — это журнал действий на уровне Kubernetes API: кто и что делал через kube-apiserver, с какими объектами, откуда пришёл запрос и чем он закончился. В отличие от логов приложений и компонентов кластера, аудит фокусируется на действиях (API-запросах) и часто становится единственным источником правды при разборе инцидентов: утечка токенов, неожиданные изменения RBAC, создание привилегированных Pod, подмена образов, отключение admission-контуров.
Ключевая идея: аудит включается и настраивается политикой (audit policy), а не «как получится». Если включить всё подряд в максимальной детализации, вы утонете в объёмах, задержках и стоимости хранения. Если включить слишком мало — расследование будет слепым.
Ниже — практический подход: какие события действительно нужны, как выбрать уровень логирования, как включить аудит через флаги apiserver, как отправлять события в webhook backend и как продумать ретеншн.
Как устроен аудит в kube-apiserver: события, уровни и стадии
Аудит в Kubernetes генерируется на kube-apiserver и описывается объектом audit event. Вы управляете тем, какие события писать и сколько данных включать, через audit policy.
Уровни (level): Metadata / Request / RequestResponse
Metadata — минимум: метаданные запроса (кто, что, к чему, результат). Это базовый уровень для большинства ресурсов.
Request — добавляется тело запроса. Полезно, когда важно видеть, что именно пытались изменить (например, patch RBAC или PodSpec).
RequestResponse — добавляется и запрос, и ответ. Самый шумный и рискованный по данным уровень (может утянуть лишнее), но иногда незаменим для расследования сложных кейсов.
Практическое правило: RequestResponse применяйте точечно — для узкого списка ресурсов и только там, где вы уверены, что не «засветите» чувствительные данные и не взорвёте объём.
Стадии (stages) и omitStages
Запрос к API проходит несколько стадий. Наиболее полезны:
RequestReceived— запрос пришёл, но ещё не авторизован и не выполнен.ResponseStarted— актуально для watch/streaming.ResponseComplete— запрос обработан полностью (обычно это то, что нужно для расследований).Panic— если apiserver паниковал (редко, но важно).
Чтобы убрать «дубликаты», часто используют omitStages. Самый частый выбор — исключить RequestReceived и оставить ResponseComplete (и иногда Panic). Так вы сохраняете итог запроса, не раздувая лог на каждый вызов двумя-тремя событиями.
Если ваша цель — incident response и расследование «кто изменил объект», то почти всегда достаточно событий стадии
ResponseComplete: они содержат пользователя, ресурс, вердикт авторизации и код ответа.

Включение аудита: флаги apiserver и обязательные файлы
Дальше зависит от того, как у вас развёрнут control plane: kubeadm, managed Kubernetes или «самосбор». Но принципы одинаковые: вы задаёте audit policy и настраиваете backend(ы), куда kube-apiserver будет писать события.
Минимальный набор флагов для файлового бэкенда
Для записи в файл обычно нужны:
--audit-policy-file— путь к YAML с audit policy.--audit-log-path— куда писать audit log (если пусто — файл не пишется).--audit-log-maxage,--audit-log-maxbackup,--audit-log-maxsize— базовая ротация на стороне apiserver.--audit-log-format— обычноjson.
Пример (значения подберите под свои диски и требования):
--audit-policy-file=/etc/kubernetes/audit-policy.yaml
--audit-log-path=/var/log/kubernetes/audit.log
--audit-log-format=json
--audit-log-maxage=7
--audit-log-maxbackup=10
--audit-log-maxsize=100
Локальный файл на control-plane — полезная страховка, но не финальная цель. Для поиска, корреляции и долгого хранения аудит почти всегда нужно централизовать.
Webhook backend: отправка аудита во внешнюю систему
Webhook backend отправляет audit events на удалённый приёмник (лог-агрегатор, SIEM, собственный сервис). В kube-apiserver включается флагом --audit-webhook-config-file. Конфиг по формату похож на kubeconfig: кластер, CA, адрес и учётные данные.
Webhook — это сеть и потенциальные проблемы доставки. Заранее продумайте:
буферизацию или очередь на стороне приёмника;
SLO на доступность endpoint’а;
поведение при деградации: что происходит, если приёмник недоступен (задержки, дропы, backpressure).
Типовой набор флагов:
--audit-policy-file=/etc/kubernetes/audit-policy.yaml
--audit-webhook-config-file=/etc/kubernetes/audit-webhook.yaml
--audit-webhook-mode=batch
Режим batch обычно снижает накладные расходы, но требует, чтобы приёмник корректно обрабатывал пачки и переживал пики.
Практичный audit policy: пишем важное и не пишем лишнее
Audit policy — это набор правил (rules), которые матчатся сверху вниз. Первое совпадение определяет действие: логировать на нужном уровне или не логировать вовсе.
Ниже — шаблон, от которого удобно отталкиваться. Он показывает ключевые техники: omitStages, точечный RequestResponse, исключение шумных эндпоинтов и акцент на критичные изменения.
apiVersion: audit.k8s.io/v1
kind: Policy
omitStages:
- "RequestReceived"
rules:
- level: None
nonResourceURLs:
- "/healthz*"
- "/readyz*"
- "/livez*"
- "/metrics"
- level: Metadata
resources:
- group: ""
resources: ["pods", "services", "configmaps", "namespaces", "serviceaccounts"]
- group: "apps"
resources: ["deployments", "daemonsets", "statefulsets", "replicasets"]
- level: Request
resources:
- group: "rbac.authorization.k8s.io"
resources: ["roles", "rolebindings", "clusterroles", "clusterrolebindings"]
- group: "admissionregistration.k8s.io"
resources: ["validatingwebhookconfigurations", "mutatingwebhookconfigurations"]
- level: RequestResponse
verbs: ["create", "update", "patch", "delete", "deletecollection"]
resources:
- group: ""
resources: ["secrets"]
- level: Metadata
Что здесь важно и что нужно адаптировать
Сначала выкидываем неинформативное:
/healthz,/readyz,/livez,/metrics. Эти вызовы частые и обычно не помогают расследованиям.База — Metadata на массовые ресурсы. Это даёт «кто/что/где/когда/результат» без лишнего объёма.
Повышаем детализацию для контуров контроля: RBAC и admission webhooks. Любые изменения тут часто означают попытку закрепиться или расширить привилегии.
Secrets — отдельная история.
RequestResponseна secrets почти всегда спорен: вы можете занести чувствительные данные в audit log и затем долго жить с риском утечки уже из системы логирования. Нередко разумнее оставитьMetadata(фиксировать факт доступа/изменения), а содержимое защищать другими механизмами. Если всё же включаетеRequestResponse, обеспечьте строгий доступ к логам, шифрование и понятный ретеншн.Последнее правило — «ловим остальное» на Metadata, чтобы не потерять неизвестное поведение.
Если вам нужно глубже закрыть тему «кто входил на ноды и что делал», полезно дополнить аудит Kubernetes логированием SSH и системных событий. См. заметку про алерты на SSH-входы через PAM и journald.
Где хранить audit log и как продумать retention
Retention — это не только «сколько дней держать». Это компромисс между требованиями безопасности и комплаенса, стоимостью хранения и удобством расследований.
Ротация на apiserver vs централизованное хранение
Флаги --audit-log-maxage, --audit-log-maxbackup, --audit-log-maxsize помогают не забить диск на control-plane, но не решают задачу долгого хранения и поиска. Как минимум, аудит стоит вывозить в централизованную систему: через webhook backend или агент, который читает файл и отправляет дальше.
Типовой подход:
локально: 1–7 дней для «быстрых разборов» и на случай проблем с доставкой;
централизованно: 30–180+ дней в зависимости от требований;
«холодный» архив: если нужно хранить год и больше, делайте отдельный контур с редким доступом.
Контроль объёма: что чаще всего раздувает лог
watch-запросы (особенно от контроллеров и операторов);
RequestResponse на широких ресурсах;
частые запросы системных компонентов к apiserver;
дубли из-за стадий, если не настроен
omitStages.
Если видите взрыв объёма — первым делом проверьте omitStages и правила с высоким level на массовых ресурсах.

Incident response: какие вопросы audit log должен закрывать
При инциденте вы почти всегда пытаетесь ответить на несколько конкретных вопросов. Хорошая audit policy должна помогать отвечать на них быстро и с достаточной точностью.
Чек-лист вопросов к audit log
Кто выполнил действие: пользователь, группы, serviceAccount, impersonation.
Откуда: source IP, user-agent, иногда — цепочка прокси (если вы её прокидываете).
Что именно сделали: verb, resource, namespace/name.
Результат: код ответа, отказ authn/authz, ошибки admission.
Когда и как часто: временная шкала, повторяющиеся попытки.
Сценарии, под которые стоит «заточить» политику
Неожиданное расширение прав: изменения
clusterrolebindings, привязкаcluster-admin, создание ролей с чрезмерными правами.Изменения admission-контуров: подмена или удаление validating/mutating webhook конфигураций.
Изменение критичных workload: patch Deployment/DaemonSet с добавлением привилегий, hostPath, hostNetwork, токенов.
Работа с secrets: массовые чтения, изменения, попытки доступа из неожиданных serviceAccount.
Для incident response важно не «логировать всё», а гарантировать, что изменения контуров контроля (RBAC, admission, authn/authz) пишутся стабильно и доступны достаточно долго.
Тонкие места безопасности: доступ к логам, приватность и «утечки через аудит»
Audit log сам по себе становится чувствительным активом. В нём есть структура кластера, имена namespace, serviceAccount, а при высоких уровнях — фрагменты payload. Поэтому:
ограничьте доступ к audit log на уровне ОС и системы логирования (минимум прав, отдельные роли);
шифруйте хранение и транспорт, особенно при webhook backend (и проверьте доверие к CA/сертификатам приёмника);
не включайте
RequestResponse«широко», особенно на ресурсах, где потенциально есть секреты или персональные данные;согласуйте ретеншн с внутренними требованиями и режимом доступа к логам.
Если вы публикуете API наружу (например, через прокси или балансировщик), не забудьте про базовую гигиену TLS на внешнем контуре и внутри лог-пайплайна: корректная валидация, актуальные цепочки, контроль истечения. При необходимости можно оформить и централизованно управлять сертификатами через SSL-сертификаты.
Проверка, что политика работает: быстрый sanity-check
После включения аудита важно убедиться, что события реально приходят и соответствуют ожиданиям по детализации и шуму.
Минимальная проверка через kubectl
Сделайте несколько безопасных действий (создать namespace, применить ConfigMap, посмотреть список Pod) и проверьте, что в логе появляются события нужного уровня.
Если аудит пишется в файл на control-plane, для первичной проверки достаточно найти события по полям "verb", "objectRef" и пользователю:
sudo grep '"verb":"create"' /var/log/kubernetes/audit.log | head -n 20
sudo grep '"objectRef"' /var/log/kubernetes/audit.log | head -n 20
Симптомы проблем
Лог пустой: не подключен backend (нет
--audit-log-pathи/или--audit-webhook-config-file), неверный путь к policy, нет прав на запись.Слишком много событий: нет
omitStages, логируются nonResourceURLs и health-check’и, высокий level на массовых ресурсах.Не хватает данных для расследования: слишком агрессивные исключения, нет повышенного уровня для RBAC/admission/критичных изменений.
Итог: базовая стратегия audit policy для продакшена
Начинайте с
Metadataпочти везде и фиксируйте итоговую стадиюResponseComplete.Используйте
omitStages, чтобы убрать дубли и снизить шум.Повышайте уровень до
Request(и точечно доRequestResponse) для RBAC, admission и других контуров контроля.Относитесь к audit log как к чувствительному активу: доступ, шифрование, ретеншн, аудит доступа к логам.
Не полагайтесь только на локальные файлы: централизуйте хранение и обеспечьте поиск.
При таком подходе audit policy становится не формальностью, а рабочим инструментом эксплуатации: и для расследований, и для постоянного контроля изменений в кластере.


