Kubernetes Observability: Audit Logs

5b631d3f32f1062df844840db1c6d8d6.png

7c9440165e9ccec76b4865af4f20b03d.jpgАвтор статьи: Рустем Галиев

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.yaml:

  • Предоставим серверному процессу 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, должен автоматически перезапуститься. Этот процесс может занять пару минут. После полного перезапуска вы сможете запросить его.

e4ffd530acc626e808b3013befab854b.png

Если команда отвечает ошибкой подключения, то под сервера 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. Лекторы расскажут про историю проекта, использование различных источников, хранилище дашбордов, формирование и версионирование собственных дашбордов. Регистрация на вебинар доступна по ссылке ниже.

© Habrahabr.ru