Перейти к основному содержимому
Версия: 1.5.1

Запуск CLI-инструментов в Kubernetes

TRON ASOC позволяет запускать CLI-инструменты безопасности в виде временных подов Kubernetes. Под разворачивается на время сканирования, получает данные из репозитория, формирует отчет и передаёт его в ASOC как нативная интеграция. После завершения сканирования под останавливается автоматически.

На текущий момент поддерживается запуск следующих инструментов:

  • Semgrep;
  • PVS;
  • Trivy;
  • Grype;
  • KICS;
  • Manual — сторонний инструмент, из которого можно загрузить результаты сканирований в систему, которые будут учитываться при дальнейшей обработке данных. Результаты загружаются в формате JSON с теми же требованиями, которые представлены в разделе выше Загрузка внешнего отчета.
warning

Очень важно запускать CLI-инструменты в том же пространстве (namespace), в котором запущен и TRON ASOC. Любые попытки запуска инструментов в другом пространстве будут неуспешными.

Для создания и запуска инструмента необходимо выполнить следующие шаги:

  1. Перейти в раздел Интеграции → Инструменты безопасности.
  2. Нажать кнопку Добавить инструмент безопасности.
  3. Выбрать инструмент, поддерживающий запуск в Kubernetes (см. список выше).
  4. В открывшемся окне заполнить информацию об инструменте безопасности.
  5. Активировать переключатель Выполнять в Kubernetes

Добавление нового инструмента безопасности

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

YAML-шаблон инструмента безопасности

к сведению

YAML-шаблон должен содержать следующие обязательные элементы:

  • переменную RESULT_PATH — путь внутри контейнера, по которому инструмент сохраняет отчет о сканировании и который передается в систему. Значение переменной заполняется в рамках плейсхолдера {{result_path}};
  • маркер завершения — строка, выводимая в лог контейнера строка, которая передает в TRON ASOC уведомление о состоянии задания.

Маркеры завершения представлены ниже:

  • Semaphore finished — этот маркер означает, что сканирование завершено успешно и отчет доступен по пути, указанном в переменной RESULT_PATH;
  • Semaphore error: — этот маркер означает, что сканирование завершено с ошибкой.
  1. После заполнения нажать кнопку Создать.

Далее необходимо создать проверку и запустить сканирование.

к сведению

Примеры YAML-шаблонов представлены в разделе ниже.

Особенности запуска CLI-инструментов

При создании и запуске необходимо учитывать следующие особенности:

  1. Задачи отправляются в кластер 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}
  1. Ресурсные ограничения для задач задаются двумя способами:
    • параметрами YAML-шаблона (поля resources.requests и resources.limits);
    • ограничениями на стороне кластера Kubernetes, настроенными администратором.

Примеры 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}}Команда запуска инструмента