kube-bench, це open-source CLI-інструмент від Aqua Security, який перевіряє Kubernetes-кластер на відповідність CIS Kubernetes Benchmark і повідомляє PASS/FAIL/WARN для кожного контролю з control-plane, etcd, kubelet і policies. У 2026 році kube-bench підтримує CIS Benchmark v1.10 для kubeadm 1.29–1.31, а також окремі профілі для EKS, GKE, AKS, RKE2 і k3s. У цьому посібнику я покажу, як встановити його як CronJob, підключити до CI/CD і (найважливіше) не потонути в шумі результатів.
Найкращий спосіб запуску в production, це Kubernetes Job або DaemonSet зі змонтованими /etc, /var і hostPID.
JSON-вивід (--json) плюс jq-фільтр перетворюють kube-bench у прохідний gate для GitHub Actions і GitLab CI.
Managed-кластери (EKS, GKE, AKS) вимагають окремих target-профілів, бо control-plane перевірки там повертають скіп, і це нормально.
Реалістична стратегія: відсіювати accepted-risk чеки через --check/--skip і фейлити pipeline тільки на нових FAIL.
Що таке kube-bench і навіщо CIS-аудит
kube-bench, це Go-бінарник, який зчитує YAML-набір тестів під cfg/, виконує ps, читає файли конфігурацій (/etc/kubernetes/manifests/*.yaml, /var/lib/kubelet/config.yaml) і зіставляє результати з контролями CIS Kubernetes Benchmark. Кожен контроль повертає PASS, FAIL, WARN або INFO разом з remediation-полем, у якому CIS описує, як саме виправити знахідку.
Чому це важливо у 2026? Більшість регуляторних баз (PCI DSS 4.0, HIPAA Security Rule, EU CRA) вимагають підтверджувати, що control-plane і kubelet налаштовані згідно з визнаним промисловим стандартом. CIS у цьому сенсі, найдешевша й найшвидша ланка: жодних платних сканерів, жодних SaaS-агентів, тільки бінарник плюс YAML.
З точки зору DevSecOps-інженера kube-bench цікавий тим, що він майже нульової залежності: сам бінарник, YAML-тести й ps. Немає runtime-агента, немає webhook-контролера, немає постійного скану. Це робить його ідеальним для запуску як Kubernetes Job у CI-конвеєрі або як CronJob для регулярних щоденних перевірок. Я особисто починаю кожен новий кластер із kube-bench run, ще до того як розгортати Falco для runtime-безпеки на eBPF. Базовий хардненінг control-plane важливіший за eBPF-детектори, бо якщо apiserver дірявий, ніяка runtime-телеметрія його не врятує.
Які версії CIS Benchmark підтримує kube-bench у 2026
Станом на серпень 2026 актуальний реліз, це kube-bench v0.9.5, який покриває CIS Kubernetes Benchmark v1.10 (опубліковано CIS у жовтні 2025) для kubeadm 1.29, 1.30 і 1.31. Разом з ним постачаються окремі target-набори:
cis-1.10, стандартний kubeadm-профіль
eks-1.5.0, Amazon EKS
gke-1.6.0, Google GKE Standard і GKE Autopilot
aks-1.5.0, Azure AKS
rke2-cis-1.24, k3s-cis-1.8 для Rancher-стеків
ack-1.0, Alibaba ACK
Кожен target виключає ті контролі, які не мають сенсу на цій платформі. Наприклад, у EKS ви фізично не маєте доступу до etcd або kube-apiserver-хосту, тому kube-bench для EKS пропускає весь Master-розділ і концентрується на node-checks, IAM ролі та Secrets Manager.
Це важливо. Якщо ви запускаєте kube-bench run на EKS без явного --targets node,policies, ви отримаєте купу FAIL типу «cannot read /etc/kubernetes/manifests» і невірно вирішите, що ваш кластер небезпечний. Я сам колись півдня згаяв на це, поки не перечитав офіційну документацію по targets.
Як встановити kube-bench у Kubernetes
Є три способи розгорнути kube-bench, і в кожного своє місце. Для одноразового аудиту з ноутбука, статичний бінарник. Для CI-pipeline, контейнер. Для регулярного моніторингу production, Job або CronJob всередині кластера.
Локальний бінарник для швидкого тесту
# Завантаження останньої версії з GitHub Releases
KB_VERSION=0.9.5
curl -sSL -o kube-bench.tar.gz \
https://github.com/aquasecurity/kube-bench/releases/download/v${KB_VERSION}/kube-bench_${KB_VERSION}_linux_amd64.tar.gz
tar -xzf kube-bench.tar.gz
sudo mv kube-bench /usr/local/bin/
sudo mkdir -p /etc/kube-bench && sudo cp -r cfg /etc/kube-bench/
# Аудит вузла (потрібен sudo для читання kubelet конфігів)
sudo kube-bench run --targets node,policies --benchmark cis-1.10
Змонтуйте hostPath-и тільки в read-only, бо kube-bench нічого не пише на хост. Прапорець hostPID: true потрібен, щоб ps aux усередині Pod показував процеси хоста (kube-apiserver, etcd), інакше половина перевірок повернеться WARN. Так, це страшнувато для security-мислення (запускати щось із hostPID), але kube-bench, це read-only процес і образ від Aqua підписаний.
Як запустити kube-bench як Job і DaemonSet
Для одноразового CI-pipeline достатньо Job. Для щоденного моніторингу production я використовую CronJob плюс DaemonSet-варіант. DaemonSet гарантує, що перевірка node-checks запуститься на кожному worker, а CronJob обгортає master/etcd-профілі раз на добу. Ось шаблон CronJob:
Звіти складаємо у PVC kube-bench-reports, а зверху навішуємо sidecar Fluent Bit або promtail, який відправляє JSON у Loki/Elastic. У такому режимі ви отримуєте trending на дашборді Grafana: скільки FAIL сьогодні порівняно з минулим тижнем, який worker раптово регресує. У мене був випадок, коли новий AMI на EKS-нодах змінив дефолтний seccomp-профіль, і kube-bench підсвітив це вже через 4 години після rolling-update, ще до того як security-команда встигла помітити.
Як інтегрувати kube-bench у CI/CD pipeline
Головна ідея pipeline-first підходу: не «kube-bench колись пробіжить у cron», а «PR, який ламає CIS-контроль, не мержиться». Реалізується це двома кроками: (1) запустити kube-bench у ephemeral-кластері (kind, minikube або k3d), (2) розпарсити JSON і зафейлити job, якщо з'явилися нові FAIL, порівняно з baseline у репозиторії.
GitHub Actions приклад
# .github/workflows/kube-bench.yml
name: kube-bench CIS audit
on:
pull_request:
paths:
- "manifests/**"
- "cluster/**"
- ".github/workflows/kube-bench.yml"
jobs:
cis-audit:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Set up kind cluster
uses: helm/kind-action@v1
with:
cluster_name: cis-test
version: v0.24.0
kubectl_version: v1.31.0
- name: Deploy manifests under test
run: kubectl apply -f manifests/
- name: Run kube-bench
run: |
docker run --rm --pid=host \
-v /etc:/etc:ro -v /var:/var:ro \
docker.io/aquasec/kube-bench:v0.9.5 \
run --targets=node,policies --benchmark=cis-1.10 --json \
> kube-bench.json
- name: Fail on new CIS violations
run: |
NEW_FAIL=$(jq '[.Controls[].tests[].results[] | select(.status=="FAIL")] | length' kube-bench.json)
BASELINE=$(jq '.baseline_fail // 0' cluster/kube-bench-baseline.json)
echo "FAIL count: $NEW_FAIL (baseline: $BASELINE)"
if [ "$NEW_FAIL" -gt "$BASELINE" ]; then
jq '.Controls[].tests[].results[] | select(.status=="FAIL") | {id: .test_number, desc: .test_desc}' kube-bench.json
exit 1
fi
- uses: actions/upload-artifact@v4
with:
name: kube-bench-report
path: kube-bench.json
І ще одна пораду про --junit. Починаючи з v0.8, kube-bench підтримує вивід у форматі JUnit XML через прапорець --junit. Це критично для GitLab, GitHub Actions test-reporter, Jenkins і Azure DevOps: усі вони автоматично рендерять кожен CIS-контроль як тест і показують дифер на PR. Такий досвід у 10 разів приємніший, ніж копирсатися у JSON-звіті вручну.
Як усунути типові failed checks kube-bench
Після першого запуску у свіжому kubeadm-кластері ви типово побачите 15–25 FAIL. Більшість з них, це швидкі виправлення в маніфестах kube-apiserver і kubelet. Чесно, я стикаюся з тими самими 4–5 контролями у майже кожному новому кластері. Ось найпоширеніші у 2026:
1.2.16 Ensure that the admission control plugin PodSecurity is set
З виходом Kubernetes 1.25 PodSecurityPolicy видалено, і CIS вимагає ввімкнути вбудований admission controller PodSecurity. Виправлення полягає у додаванні рядка у /etc/kubernetes/manifests/kube-apiserver.yaml:
4.2.6 Ensure that the --protect-kernel-defaults argument is set to true
Kubelet за замовчуванням дозволяє sysctl-и, які перевизначають kernel-параметри. Відредагуйте /var/lib/kubelet/config.yaml:
protectKernelDefaults: true
Далі виконайте systemctl restart kubelet. Якщо kubelet не стартує, значить ваш pod намагається змінити sysctl без allowedUnsafeSysctls, і це власне те, що CIS і хоче відловити.
5.1.5 Ensure that default service accounts are not actively used
Створіть окремий SA для кожного workload, а в дефолтному встановіть automountServiceAccountToken: false:
Додайте у kubelet-конфіг podPidsLimit: 4096, це запобігає fork-bomb атакам всередині одного pod. Значення 4096 достатнє для більшості робочих навантажень; для JVM-важких workload-ів підніміть до 8192.
Для системного контексту цих виправлень раджу подивитись посібник з auditd на Linux і MITRE ATT&CK правил: kubelet і apiserver-події корисно паралельно логувати через auditd, щоб мати аудит-слід поза самим Kubernetes.
kube-bench vs kube-hunter vs Trivy K8s: порівняння
Три інструменти часто плутають, хоча вони розв'язують різні задачі. Ось коротка порівняльна таблиця, яку я використовую під час onboarding-ів:
Критерій
kube-bench
kube-hunter
Trivy K8s
Тип перевірки
Конфігурація (CIS)
Penetration probing
CVE + misconfig
Джерело правил
CIS Benchmark v1.10
Kube-hunter DB
Trivy DB + Kubernetes NSA
Runtime у кластері
Job/DaemonSet
Job або external scan
CronJob через trivy-operator
Формат виводу
JSON, JUnit, plain
JSON, plain
JSON, SARIF, table
Найкраще для
Compliance аудит control-plane
Атакерська перспектива
Vulnerability + policy як у SAST
Активність (2026)
Активний, v0.9.5
Архівний з 2024
Активний, v0.55+
Мій робочий сетап у команді: kube-bench у CI + CronJob для compliance-звітності, Trivy K8s Operator для CVE/misconfig-скану runtime-workload-ів, а kube-hunter я більше не тримаю. З березня 2024 Aqua Security перевела його у read-only архів, тож CVE у самому інструменті вже не патчаться. Для pentest-перспективи краще брати peirates або платний Panoptica scan.
Як зменшити шум від kube-bench у production
Після другого-третього циклу вам обов'язково доведеться навчитися глушити accepted-risk контролі. kube-bench має три механізми для цього:
--check 1.2.16,1.2.20, запустити тільки перелічені контролі.
--skip 4.2.6,5.1.5, пропустити перелічені (позначаються INFO у звіті).
Кастомізація YAML у cfg/cis-1.10/master.yaml: можна відредагувати text, audit, tests і навіть додати власні контролі.
Найправильніший підхід, це тримати файл cluster/kube-bench-allowlist.yaml у git з коментарем «чому пропускаємо» і посиланням на Jira/GitHub Issue. Приклад:
# cluster/kube-bench-allowlist.yaml
skip:
- id: "3.2.1"
reason: "Audit log ingested by Vector via journald, not via --audit-log-path"
ticket: "SEC-482"
- id: "1.2.22"
reason: "OIDC provider is not required for internal clusters"
ticket: "SEC-501"
У CI-скрипті парсимо цей YAML і збираємо аргумент --skip динамічно. Так кожен «пропуск» проходить code review і не забувається на роки. Для розширеної стратегії reduce-noise у security-tooling див. посібник з Lynis для host-хардненінгу. Там детально розглядається філософія baseline-diff підходу, яка чудово переноситься на Kubernetes.
Метрики kube-bench у Prometheus і Grafana
Готового exporter-а офіційно немає, але спільнота підтримує kube-bench-exporter як sidecar, який парсить JSON і публікує метрики у форматі Prometheus. Приклад PromQL для дашборду:
# Кількість FAIL за node
sum by (node) (kube_bench_control_status{status="FAIL"})
# Trend FAIL за 7 днів
increase(kube_bench_control_status{status="FAIL"}[7d])
# Топ 10 найчастіших порушень
topk(10, count by (control_id, control_desc) (kube_bench_control_status{status="FAIL"}))
Такий дашборд закриває питання «а покажи мені drift compliance-и за квартал» і рятує від годинного пошуку в JSON. Для налаштування SIEM-конвеєра, який паралельно споживає kube-bench JSON плюс runtime-alert-и, я тримаю відкритим у сусідній вкладці офіційний Kubernetes Security Checklist. Він добре доповнює CIS практичними порадами, яких у самому benchmark іноді не вистачає.
Часті питання
Чи потрібен root-доступ для запуску kube-bench?
Так, для читання kubelet-конфігів (/var/lib/kubelet/config.yaml), маніфестів control-plane (/etc/kubernetes/manifests/) і systemd-юнітів потрібен root або privileged-контейнер з hostPID: true. Read-only mount кореневих директорій хоста плюс hostPID достатні, жодних змін на файловій системі kube-bench не робить.
Як часто треба запускати kube-bench у продакшн-кластері?
Мінімум щодня через CronJob плюс кожен PR, який чіпає маніфести control-plane чи kubelet-конфіги. Для регульованих середовищ (PCI DSS 4.0, HIPAA) корисно тримати weekly full-report з архівом за 12 місяців, це закриває вимогу до безперервного моніторингу конфігураційних змін.
Чи працює kube-bench у managed Kubernetes (EKS, GKE, AKS)?
Так, але треба явно вказати відповідний target: --benchmark eks-1.5.0, gke-1.6.0 або aks-1.5.0. У managed-кластерах control-plane закритий, тому перевіряються тільки node-компоненти й Kubernetes-об'єкти. Cloud-provider частину CIS-контролів (IAM, KMS, VPC) kube-bench не покриває, для цього використовуйте окремі cloud-native інструменти на кшталт Prowler або Steampipe.
Як інтегрувати результати kube-bench у Grafana або SIEM?
Найпростіше, вивантажувати JSON у PVC й перекидати Fluent Bit-ом у Loki/Elastic або S3. Для Grafana-дашбордів спільнотний kube-bench-exporter публікує kube_bench_control_status метрику з лейблами control_id, node, status. У SIEM (Wazuh, Splunk, Sentinel) відправляйте JUnit XML, більшість парсить його одразу.
Що робити, якщо kube-bench повертає FAIL для контролю, який ми свідомо не виконуємо?
Задокументуйте виняток у git-репозиторії (kube-bench-allowlist.yaml) з причиною та ticket-посиланням, і додайте контроль у --skip у CI-джобі. Ніколи не редагуйте YAML-тести всередині контейнера, бо це втратиться при апгрейді. Регулярно (раз на квартал) переглядайте allowlist: обставини змінюються, і accepted risk може стати непотрібним.
Практичний посібник з налаштування auditd для Linux: від базової конфігурації до правил MITRE ATT&CK, оптимізації продуктивності та інтеграції з SIEM через Laurel. Готові набори правил для продакшн-серверів.