Запуск CLI-инструментов в Kubernetes
TRON ASOC позволяет запускать CLI-инструменты безопасности в виде временных подов Kubernetes. Под разворачивается на время сканирования, получает данные из репозитория, формирует отчет и передаёт его в ASOC как нативная интеграция. После завершения сканирования под останавливается автоматически.
На текущий момент поддерживается запуск следующих инструментов:
- Semgrep;
- PVS;
- Trivy;
- Grype;
- KICS;
- Manual — сторонний инструмент, из которого можно загрузить результаты сканирований в систему, которые будут учитываться при дальнейшей обработке данных. Результаты загружаются в формате JSON с теми же требованиями, которые представлены в разделе выше Загрузка внешнего отчета.
Очень важно запускать CLI-инструменты в том же пространстве (namespace), в котором запущен и TRON ASOC. Любые попытки запуска инструментов в другом пространстве будут неуспешными.
Для создания и запуска инструмента необходимо выполнить следующие шаги:
- Перейти в раздел Интеграции → Инструменты безопасности.
- Нажать кнопку Добавить инструмент безопасности.
- Выбрать инструмент, поддерживающий запуск в Kubernetes (см. список выше).
- В открывшемся окне заполнить информацию об инструменте безопасности.
- Активировать переключатель Выполнять в Kubernetes

- Заполнить YAML-шаблон запуска инструмента в Kubernetes.

YAML-шаблон должен содержать следующие обязательные элементы:
- переменную
RESULT_PATH— путь внутри контейнера, по которому инструмент сохраняет отчет о сканировании и который передается в систему. Значение переменной заполняется в рамках плейсхолдера{{result_path}}; - маркер завершения — строка, выводимая в лог контейнера строка, которая передает в TRON ASOC уведомление о состоянии задания.
Маркеры завершения представлены ниже:
Semaphore finished— этот маркер означает, что сканирование завершено успешно и отчет доступен по пути, указанном в переменнойRESULT_PATH;Semaphore error:— этот маркер означает, что сканирование завершено с ошибкой.
- После заполнения нажать кнопку Создать.
Далее необходимо создать проверку и запустить сканирование.
Примеры YAML-шаблонов представлены в разделе ниже.
Особенности запуска CLI-инструментов
При создании и запуске необходимо учитывать следующие особенности:
- Задачи отправляются в кластер Kubernetes без очереди — каждая задача запускается немедленно при получении. Параллельный запуск обеспечивается внутренним воркером
k8worker; по умолчанию доступно 10 воркеров, что позволяет одновременно выполнять до 10 задач.
Количество воркеров можно изменить в конфигурационном файле. Пример заполнения представлен ниже:
k8s:
k8s-workers-count: ${K8S_WORKERS_COUNT|10}
k8s-tasks-channel-size: ${K8S_TASKS_CHANNEL_SIZE|100} #
k8s-tasks-timeout-minutes: ${K8S_TASKS_TIMEOUT_MINUTES|60}
k8s-client-outside-mode: ${K8S_OUTSIDE|false}
k8s-namespace: ${K8S_NAMESPACE|default}
- Ресурсные ограничения для задач задаются двумя способами:
- параметрами YAML-шаблона (поля
resources.requestsиresources.limits); - ограничениями на стороне кластера Kubernetes, настроенными администратором.
- параметрами YAML-шаблона (поля
Примеры YAML-шаблонов
В этом разделе представлены примеры YAML-шаблонов, заполняемых пользователем для запуска CLI-инструментов в Kubernetes.
YAML-шаблон для запуска Trivy
apiVersion: v1
kind: Secret # Тип ресурса: секрет Kubernetes для хранения чувствительных данных
metadata:
labels:
app: asoc
name: int-pullsecret # Название секрета — по нему ссылаются другие ресурсы
namespace: {{namespace}} # Название namespace — обязательный параметр
data:
.dockerconfigjson: >-
# Base64-encoded JSON с credentials для реестра repo.kcs.kaspersky.com
cipheredCodejson==
type: kubernetes.io/dockerconfigjson # Специальный тип секрета для Docker-реестров
# Простой Docker-образ
apiVersion: batch/v1
kind: Job # Тип ресурса: одноразовое задание
metadata:
labels:
app: asoc
name: trivy-scan-image # Название задания
namespace: {{namespace}} # Название namespace — обязательный параметр
spec:
ttlSecondsAfterFinished: 3600 # Время в секундах, по истечении которого задание и его поды удаляются
template:
spec:
# imagePullSecrets: # Раскомментировать, если образ берется из приватного реестра
# - name: {{pull_secret_name}}
containers:
- name: trivy
env:
- name: RESULT_PATH
value: "/workspace/report.sarif" # Путь для сохранения SARIF-отчёта
- name: TRIVY_SEVERITY
value: "HIGH,CRITICAL" # Фильтр уязвимостей: только высокий и критический уровни
image: aquasec/trivy:latest # Официальный образ Trivy
command: ["/bin/sh", "-c"]
args:
- |
echo 'Starting Trivy image scan...'
# Сканирование образа и сохранение SARIF-отчета
trivy image \
--severity $TRIVY_SEVERITY \ # Фильтр по переменной TRIVY_SEVERITY
--format sarif \ # Формат отчета
--output $RESULT_PATH \ # Путь из переменной RESULT_PATH
graylog/graylog:6.1 # Целевой образ для сканирования
echo "Scan completed. Report saved to $RESULT_PATH"
echo "Semaphore finished" # Маркер завершения
sleep {{job_timeout}} # Обязательное значение timeout в секундах
volumeMounts:
- name: workspace
mountPath: /workspace # Точка монтирования тома — сюда записывается отчет
resources:
requests:
memory: "128Mi" # Гарантированный минимум памяти
cpu: "100m" # Гарантированный минимум CPU (0.1 ядра)
limits:
memory: "1Gi" # Максимум памяти
cpu: "1" # Максимум CPU (1 ядро)
volumes:
- name: workspace
emptyDir: {} # Временный том: существует только во время выполнения пода, данные не сохраняются после завершения
restartPolicy: Never # Если значение Never, то при ошибке задание не перезапускается
YAML-шаблон для запуска Grype
apiVersion: batch/v1
kind: Job # Тип ресурса: одноразовое задание
metadata:
labels:
app: asoc
name: grype-scan-python # Название задания
namespace: {{namespace}} # Название namespace — обязательный параметр
spec:
ttlSecondsAfterFinished: 3600 # Время в секундах, по истечении которого задание и его поды удаляются
template:
spec:
containers:
- name: grype
image: alpine:latest # Базовый образ — Grype устанавливается внутри
command:
- /bin/sh
- -c
- |
# Загрузка и установка Grype из официального репозитория Anchore
wget -qO- https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh
# Сканирование образа python:3.10.14-alpine3.20
# -o json: формат вывода — JSON
# Результат сохраняется в /workspace/report.json
grype python:3.10.14-alpine3.20 -o json > /workspace/report.json
echo "Scan completed. Report saved to /workspace/report.json"
# Предпросмотр отчета: вывод первых 20 строк в лог пода
echo "First 20 lines of report:"
cat /workspace/report.json | head -20
sleep {{job_timeout}} # Required: specify timeout in seconds
volumeMounts:
- name: workspace
mountPath: /workspace # Точка монтирования тома — сюда записывается отчет
resources:
requests:
memory: "256Mi" # Гарантированный минимум памяти
cpu: "200m" # Гарантированный минимум CPU (0.2 ядра)
limits:
memory: "1Gi" # Максимум памяти
cpu: "1" # Максимум CPU (1 ядро)
volumes:
- name: workspace
emptyDir: {} # Временный том: существует только во время выполнения пода, данные не сохраняются после завершения
restartPolicy: Never # Если значение Never, то при ошибке задание не перезапускается
Плейсхолдеры YAML-шаблонов
Плейсхолдеры предназначены для автоматической подстановки данных из источника сканирования: при формировании проверки система подставляет актуальные значения в соответствующие поля YAML-шаблона. Плейсхолдеры и их обозначение представлены в таблице ниже.
| Плейсхолдер | Обозначение плейсхолдера |
|---|---|
{{type}} | Тип репозитория или реестра |
{{vcs_url}} | URL системы контроля версий репозитория |
{{source_url}} | URL репозитория |
{{file_path}} | Путь к файлу в репозитории |
{{file_path_route}} | Часть пути к файлу в репозитории, оканчивающаяся на '/', без имени файла |
{{source_url_token}} | Токен URL репозитория |
{{auth_method}} | Метод аутентификации репозитория |
{{api_token}} | API-токен репозитория |
{{login}} | Логин репозитория или реестра |
{{password}} | Пароль репозитория или реестра |
{{branch_name}} | Название ветки репозитория |
{{ssh_key}} | SSH-ключ репозитория |
{{ssh_user}} | SSH-пользователь репозитория |
{{ssh_passphrase}} | Парольная фраза (passphrase) SSH-ключа |
{{http_url}} | HTTP(S) URL репозитория |
{{api_url}} | URL API реестра |
{{registry_url}} | URL реестра |
{{image_name}} | Имя образа в реестре |
{{path_method}} | Метод формирования пути в реестре |
{{result_path}} | Путь к файлу результата для парсинга найденных проблем |
{{image}} | Docker-образ инструмента |
{{source_command}} | Команда клонирования исходного кода |
{{tool_command}} | Команда запуска инструмента |