Kubernetes Observability: Audit Logs
IBM Senior DevOps Engineer & Integration Architect. Официальный DevOps ментор и коуч в IBM
Привет, Хабр!
Давайте поговорим о записи логов событий, происходящих в кластере Kubernetes. Эти логи можно использовать для устранения неполадок на уровне кластера, чтобы восстановить, когда и как конфигурация кластера была изменена, что привело к нежелательному или нарушенному поведению во время выполнения. Записи логов также можно использовать для отслеживания атаки, которая может происходить прямо сейчас, в качестве средства для принятия контрмер.
Kubernetes может хранить записи о событиях, инициированных конечными пользователями для любых запросов к серверу API или для событий, генерируемых самой плоскостью управления. Записи в журнале аудита существуют в формате строк JSON и могут содержать, помимо прочего, следующую информацию:
Кто спровоцировал событие?
Когда он был запущен?
Какое событие произошло?
Какой компонент Kubernetes обработал запрос?
Тип события и соответствующие данные запроса, которые должны быть записаны, определяются политикой аудита. Политика аудита представляет собой манифест YAML, определяющий эти правила, и должен быть предоставлен серверному процессу API.
Серверная часть аудита отвечает за хранение записанных событий аудита, как определено политикой аудита. У вас есть два настраиваемых параметра для бэкэнда:
Серверная часть логов, которая записывает события в файл.
Серверная часть вебхука, которая отправляет события во внешнюю службу через HTTP (S), например, с целью интеграции централизованной системы логгинга и мониторинга. Такой бэкенд может помочь во время дебагга упавшего приложения.
Файл политики аудита фактически является манифестом YAML для ресурса политики. Любое событие, полученное сервером API, сопоставляется в порядке определения с правилами, определенными в файле политики.
Событие регистрируется с объявленным уровнем аудита, если можно найти соответствующее правило. У нас есть несколько уровней айдита.
None
— ничего не обрабатываем.Metadata
— Записывать в логи только метаданные запроса для события.Request
— Записываем метаданные и тело запроса для события.RequestResponse
— Записываем метаданные, тело запроса и ответа для события.
Давайте же попрактикуемся.
Прежде всего, нам нужно улучшить существующий файл политики аудита.
Добавим правило, которое регистрирует события для ConfigMaps
и Secrets
на уровне метаданных. Добавимеще одно правило, которое регистрирует события для сервисов на уровне запроса.
Для этого изменим файл /etc/kubernetes/audit/rules/auditpolicy.yaml
Он изначально выглядит как
apiVersion: audit.k8s.io/v1
kind: Policy
omitStages:
- "RequestReceived"
rules:
- level: RequestResponse
resources:
- group: ""
resources: ["pods"]
Теперь изменим его на:
apiVersion: audit.k8s.io/v1
kind: Policy
omitStages:
- "RequestReceived"
rules:
- level: RequestResponse
resources:
- group: ""
resources: ["pods"]
- level: Metadata
resources:
- group: ""
resources: ["secrets", "configmaps"]
- level: Request
resources:
- group: ""
resources: ["services"]
Однако файл политики аудита еще не настроен для сервера API.
После создания файла политики аудита он может использоваться серверным процессом API. Мы должны добавить флаг --audit-policy-file
в процесс сервера API в файле /etc/kubernetes/manifests/kube-apiserver.yaml
. Присвоенное значение параметра — это полный путь к файлу политики аудита. Однако мы немного расширим нашу конфигурацию:
добавим правило, согласно которому логи должны записываться в файл /var/log/kubernetes/audit/logs/apiserver.log
и определяем максимальное количество дней для хранения логов аудита равное 5 (т.е. логи хранятся максимум 5 дней).
Настраиваем сервер API для использования файла политики аудита, редактируя файл /etc/kubernetes/manifests/kube-apiserver.yaml
. Предоставляем дополнительные конфигурации.
Чтобы настроить серверную часть логов на основе файлов, нам потребуется добавить три элемента конфигурации в файл /etc/kubernetes/manifests/kube-apiserver.yam
l:
Предоставим серверному процессу API два флага: флаг
--audit-policy-file
указывает на файл политики аудита, флаг--audit-log-path
указывает на выходной файл логов.Добавим путь монтирования тома (Volume) для файла политики лога аудита и выходного каталога лога.
Добавьте определение тома к пути хоста для файла политики лога аудита и выходной директории журнала.
...
spec:
containers:
- command:
- kube-apiserver
- --audit-policy-file=/etc/kubernetes/audit/rules/audit-policy.yaml
- --audit-log-path=/var/log/kubernetes/audit/logs/apiserver.log
- --audit-log-maxage=5
...
volumeMounts:
- mountPath: /etc/kubernetes/audit/rules/audit-policy.yaml
name: audit
readOnly: true
- mountPath: /var/log/kubernetes/audit/logs/
name: audit-log
readOnly: false
...
volumes:
- name: audit
hostPath:
path: /etc/kubernetes/audit/rules/audit-policy.yaml
type: File
- name: audit-log
hostPath:
path: /var/log/kubernetes/audit/logs/
type: DirectoryOrCreate
Под, на котором работает сервер API, должен автоматически перезапуститься. Этот процесс может занять пару минут. После полного перезапуска вы сможете запросить его.
Если команда отвечает ошибкой подключения, то под сервера API находится в процессе перезапуска или у вас ошибка конфигурации. Проверьте файлы логов сервера API в /var/log/pods
, если под больше не появляется по прошествии разумного времени.
Теперь посмотрим на создание зарегистрированного события.
Одним из регистрируемых ресурсов является ConfigMap
на уровне метаданных. Следующая команда создает пример объекта ConfigMap
.
kubectl create configmap db-user --from-literal=username=tom
Файл лога аудита теперь будет содержать запись для события:
cat /var/log/kubernetes/audit/logs/apiserver.log
{"kind":"Event","apiVersion":"audit.k8s.io/v1","level":"Metadata","auditID":"1fbb409a-3815-4da8-8a5e-d71c728b98b1","stage":"ResponseComplete","requestURI":"/api/v1/namespaces/default/configmaps?fieldManager=kubectl-create\u0026fieldValidation=Strict","verb": "create","user":{"username":"kubernetes-admin","groups": ["system:masters","system:authenticated"]},"sourceIPs":["192.168.56.10"], "userAgent":"kubectl/v1.24.4 (linux/amd64) kubernetes/95ee5ab", "objectRef":{"resource":"configmaps","namespace":"default", "name":"db-user","apiVersion":"v1"},"responseStatus":{"metadata": {},"code":201},"requestReceivedTimestamp":"2023-06-04T18:57:51.367219Z", "stageTimestamp":"2023-06-06T18:57:51.372094Z","annotations": {"authorization.k8s.io/decision":"allow","authorization.k8s.io/reason":""}}
Подводя итоги мониторинг и регистрация событий в кластере Kubernetes — важная обязанность каждого администратора.
Завершить статью хочу полезной рекомендацией. Уже скоро у моих коллег из OTUS пройдет бесплатный вебинар, на котором будет рассмотрено построение графиков из различных источников данных при помощи Grafana. Лекторы расскажут про историю проекта, использование различных источников, хранилище дашбордов, формирование и версионирование собственных дашбордов. Регистрация на вебинар доступна по ссылке ниже.