Поиск контейнеров в Marathon начинается с прямого API-запроса к эндпоинту /v2/apps. Если вам нужен конкретный контейнер по ID или имени приложения, используйте GET /v2/apps/{appId}. AppId чувствителен к регистру и всегда начинается с прямого слэша. Базовый запрос с авторизацией через заголовок выглядит так:
curl -s -H "Authorization: token=$MARATHON_AUTH_TOKEN" \
-H "Content-Type: application/json" \
"https://marathon.example.com/v2/apps//production/backend-service"
В ответе вы получите JSON с полным определением приложения. Ключевые поля для быстрой оценки состояния: tasksRunning (сколько задач сейчас работает), tasksHealthy (сколько прошли health check), tasksUnhealthy (сколько не прошли проверку здоровья) и tasksStaged (ожидают запуска). Если tasksUnhealthy больше нуля - приложение требует немедленного внимания.
Практика показывает, что администраторы тратят до 40% времени инцидента на поиск нужного контейнера среди сотен запущенных. Правильно построенный фильтр сокращает этот этап до одной команды. В этом руководстве собраны готовые шаблоны запросов для всех типовых сценариев: от поиска по меткам до массовых операций перезапуска.
Для сложных случаев, когда стандартных фильтров недостаточно, используется утилита jq - она обрабатывает JSON-вывод Marathon и даёт гранулярный контроль над выборкой. Все примеры ниже протестированы на Marathon 1.11+ и предполагают наличие jq в системе.
Как быстро найти контейнер по ID или имени через Marathon API
Эндпоинт /v2/apps без параметров возвращает список всех приложений. Добавление appId сужает выборку до одного. AppId формируется по иерархическому принципу: группы разделяются слэшами, например /team-alpha/staging/payment-worker.
Частая ошибка - пропуск начального слэша или несовпадение регистра. Marathon считает /MyApp и /myapp разными приложениями. Проверьте точное написание через список всех приложений:
curl -s -H "Authorization: token=$TOKEN" \
"https://marathon.example.com/v2/apps" | jq '.apps[].id'
Вывод покажет полные идентификаторы. Скопируйте нужный и подставьте в запрос. Поле health в ответе содержит массив результатов проверок: alive означает успех, unreachable - контейнер не отвечает на health check. Для приложений без health check поле будет пустым.
Если приложение не найдено, Marathon возвращает HTTP 404. Причина может быть в удалении приложения или опечатке в appId. В таких случаях поможет диагностика проблем поиска контейнеров - проверьте права доступа к ZooKeeper и актуальность кэша.
Фильтрация контейнеров по меткам: синтаксис и готовые примеры
Метки - основной механизм организации приложений в Marathon. Они задаются при создании приложения в секции labels и позволяют группировать контейнеры по средам, командам, сервисам или любым другим признакам. Фильтрация по меткам выполняется параметром label в query string.
Синтаксис: ?label=KEY==VALUE для точного совпадения и ?label=KEY!=VALUE для исключения. Оператор == чувствителен к регистру. Если значение содержит спецсимволы - пробелы, слэши, двоеточия - его нужно URL-кодировать. Пример поиска всех приложений staging-среды:
curl -s -H "Authorization: token=$TOKEN" \
"https://marathon.example.com/v2/apps?label=environment==staging" \
| jq '.apps[] | {id: .id, env: .labels.environment}'
Для поиска по команде используйте метку team:
curl -s -H "Authorization: token=$TOKEN" \
"https://marathon.example.com/v2/apps?label=team==backend" \
| jq '.apps | length'
Последняя команда выводит количество приложений backend-команды - удобно для быстрой инвентаризации.
Поиск по нескольким меткам одновременно
Marathon объединяет несколько параметров label через логическое AND. Запрос с двумя метками вернёт только приложения, у которых совпали обе. Это позволяет сужать выборку до конкретного сервиса в конкретной среде:
curl -s -H "Authorization: token=$TOKEN" \
"https://marathon.example.com/v2/apps?label=environment==staging&label=role==worker" \
| jq '[.apps[] | {id: .id, env: .labels.environment, role: .labels.role}]'
OR-логика нативно не поддерживается. Если нужно найти приложения с меткой team==backend ИЛИ team==frontend, придётся сделать два запроса и объединить результаты через jq:
{
curl -s -H "Authorization: token=$TOKEN" \
"https://marathon.example.com/v2/apps?label=team==backend";
curl -s -H "Authorization: token=$TOKEN" \
"https://marathon.example.com/v2/apps?label=team==frontend";
} | jq -s '.[0].apps + .[1].apps | unique_by(.id)'
Этот подход работает для любых несовместимых условий. При большом количестве меток лучше написать скрипт с циклом.
Отбор контейнеров по состоянию: как найти все проблемные инстансы
Marathon не предоставляет прямого фильтра по статусу задачи в query string эндпоинта /v2/apps. Но состояние приложения отражается в полях tasksRunning, tasksHealthy, tasksUnhealthy и tasksStaged. Комбинация /v2/apps и jq решает задачу фильтрации по этим полям.
Поиск всех приложений с проблемами - те, у которых есть нездоровые или застревающие в staged задачи:
curl -s -H "Authorization: token=$TOKEN" \
"https://marathon.example.com/v2/apps" \
| jq '[.apps[] | select(.tasksUnhealthy > 0 or .tasksStaged > 0) | {
id: .id,
running: .tasksRunning,
unhealthy: .tasksUnhealthy,
staged: .tasksStaged
}]'
Этот запрос - первая команда при инциденте. За 2 секунды вы получаете список всех проблемных приложений кластера. Для production-сред с сотнями контейнеров это экономит 10-15 минут ручного обхода.
Приложения без health check не будут иметь заполненных полей tasksHealthy и tasksUnhealthy. Для них ориентируйтесь на tasksRunning относительно желаемого количества instances. Расхождение означает, что часть задач не смогла запуститься.
Фильтрация задач по статусу (TASK_RUNNING, TASK_FAILED и др.)
Детальный статус каждой задачи доступен через эндпоинт /v2/tasks. Он возвращает плоский список всех задач кластера с их состояниями. Фильтрация через jq по полю state даёт гранулярный контроль:
curl -s -H "Authorization: token=$TOKEN" \
"https://marathon.example.com/v2/tasks" \
| jq '[.tasks[] | select(.state == "TASK_FAILED") | {
appId: .appId,
taskId: .id,
state: .state,
message: .message
}]'
Основные статусы задач:
- TASK_RUNNING - задача работает
- TASK_FAILED - задача завершилась с ошибкой
- TASK_FINISHED - задача успешно завершилась
- TASK_STAGING - задача ожидает ресурсов
- TASK_STARTING - задача запускается
- TASK_KILLING - задача в процессе остановки
- TASK_KILLED - задача принудительно остановлена
Поле message в ответе содержит причину сбоя - нехватка памяти, ошибка образа, таймаут health check. Это ключевая информация для диагностики. При большом кластере /v2/tasks возвращает значительный объём данных. Используйте пагинацию через заголовки ответа или фильтруйте по appId на стороне клиента.
Поиск контейнеров по потреблению ресурсов: CPU и память
Marathon хранит запрошенные ресурсы в определении приложения: cpus (дробное число ядер) и mem (мегабайты). Эти значения - лимиты, которые контейнер запросил у Mesos. Реальное потребление может отличаться, для него нужны метрики Mesos или системы мониторинга.
Сортировка приложений по убыванию CPU - быстрый способ найти самых тяжёлых потребителей:
curl -s -H "Authorization: token=$TOKEN" \
"https://marathon.example.com/v2/apps" \
| jq '[.apps[] | {id: .id, cpus: .cpus, mem: .mem}] | sort_by(-.cpus)'
Поиск приложений с памятью больше 1024 МБ:
curl -s -H "Authorization: token=$TOKEN" \
"https://marathon.example.com/v2/apps" \
| jq '[.apps[] | select(.mem > 1024) | {id: .id, mem: .mem}]'
Эти запросы помогают при планировании ресурсов кластера и поиске приложений с завышенными лимитами. Приложение, запросившее 8 CPU, но использующее 0.1 - кандидат на оптимизацию. Для мониторинга реального потребления настройте связку Prometheus и Grafana, как описано в руководстве по мониторингу контейнеров.
Массовые операции: перезапуск и масштабирование отфильтрованных контейнеров
Результаты фильтрации можно направить на вход циклу, выполняющему действия над группой приложений. Типовой сценарий: перезапустить все контейнеры с определённой меткой после изменения конфигурации или для применения нового образа.
Базовый шаблон: получить список appId через фильтр, затем в цикле отправить PUT-запрос на эндпоинт /v2/apps/{appId}/restart. Для масштабирования используется PUT на /v2/apps/{appId} с телом {"instances": N}.
Меры предосторожности при массовых операциях:
- Добавьте подтверждение перед выполнением - выведите список затрагиваемых приложений и запросите ввод
- Ограничьте количество одновременных операций - Marathon может отклонить запросы при превышении лимита
- Проверяйте HTTP-код ответа каждого запроса - одиночный сбой не должен останавливать всю операцию
Пример скрипта для перезапуска всех приложений с определенной меткой
Скрипт получает список appId приложений с меткой environment==staging, выводит их для подтверждения и выполняет перезапуск каждого с задержкой 2 секунды между запросами:
#!/bin/bash
MARATHON_URL="https://marathon.example.com"
AUTH_TOKEN="$MARATHON_AUTH_TOKEN"
LABEL_FILTER="environment==staging"
echo "Получение списка приложений с меткой $LABEL_FILTER..."
APP_IDS=$(curl -s -H "Authorization: token=$AUTH_TOKEN" \
"$MARATHON_URL/v2/apps?label=$LABEL_FILTER" \
| jq -r '.apps[].id')
if [ -z "$APP_IDS" ]; then
echo "Приложения не найдены. Выход."
exit 0
fi
echo "Будут перезапущены следующие приложения:"
echo "$APP_IDS"
echo ""
read -p "Подтвердите операцию (yes/no): " CONFIRM
if [ "$CONFIRM" != "yes" ]; then
echo "Операция отменена."
exit 0
fi
for APP_ID in $APP_IDS; do
echo "Перезапуск $APP_ID..."
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
-X PUT -H "Authorization: token=$AUTH_TOKEN" \
-H "Content-Type: application/json" \
"$MARATHON_URL/v2/apps${APP_ID}/restart")
if [ "$HTTP_CODE" -eq 200 ]; then
echo " Успешно (HTTP $HTTP_CODE)"
else
echo " Ошибка (HTTP $HTTP_CODE)"
fi
sleep 2
done
echo "Операция завершена."
Скрипт требует установленного jq. Переменная MARATHON_AUTH_TOKEN должна быть задана в окружении. Задержка в 2 секунды предотвращает перегрузку Marathon API - при сотнях приложений увеличьте её до 5 секунд.
Экспорт данных о контейнерах для отчетности и аудита
Регулярный сбор информации о контейнерах нужен для инвентаризации, аудита безопасности и планирования ресурсов. Marathon API возвращает JSON, который легко преобразуется в CSV для дальнейшего анализа в таблицах или системах отчётности.
Пример jq-фильтра для выборки ключевых полей и экспорта в CSV с заголовками:
curl -s -H "Authorization: token=$TOKEN" \
"https://marathon.example.com/v2/apps" \
| jq -r '["id","cpus","mem","instances","labels"],
(.apps[] | [
.id,
.cpus,
.mem,
.instances,
(.labels | to_entries | map("\(.key)=\(.value)") | join(";"))
]) | @csv' > marathon_inventory.csv
Этот однострочник создаёт CSV-файл с идентификатором приложения, запрошенными CPU, памятью, количеством экземпляров и всеми метками, склеенными через точку с запятой. Файл открывается в Excel, Google Sheets или загружается в системы аналитики.
Для регулярного сбора настройте cron-задачу, выполняющую скрипт раз в сутки. Результаты можно складывать в директорию с датой в имени файла - получится история изменений кластера за любой период. При аудите безопасности такой архив незаменим: вы всегда знаете, какие контейнеры работали в конкретный день и с какими метками.
Если кластер управляется через Kubernetes, аналогичный подход к сбору метрик описан в руководстве по диагностике подов и узлов - принципы фильтрации и экспорта данных схожи.
Поиск контейнеров по версии образа (image)
Информация об образе контейнера хранится в секции container.docker.image определения приложения. Поиск по этому полю выявляет приложения с устаревшими версиями или использующие тег :latest, что создаёт риски неконтролируемых обновлений.
Поиск всех приложений, использующих тег :latest:
curl -s -H "Authorization: token=$TOKEN" \
"https://marathon.example.com/v2/apps" \
| jq '[.apps[] | select(.container.docker.image | endswith(":latest")) | {
id: .id,
image: .container.docker.image
}]'
Поиск приложений с конкретным тегом, например :v1.0:
curl -s -H "Authorization: token=$TOKEN" \
"https://marathon.example.com/v2/apps" \
| jq '[.apps[] | select(.container.docker.image | contains(":v1.0")) | {
id: .id,
image: .container.docker.image
}]'
Использование :latest в production-окружении опасно: перезапуск контейнера может подтянуть новую версию образа, не протестированную в вашем окружении. Результат - внезапная деградация сервиса. Найдите такие приложения первым запросом и замените тег на фиксированную версию.
Поиск приложений вообще без тега (используется образ по умолчанию :latest неявно):
curl -s -H "Authorization: token=$TOKEN" \
"https://marathon.example.com/v2/apps" \
| jq '[.apps[] | select(.container.docker.image | test(":[^/]+$") | not) | {
id: .id,
image: .container.docker.image
}]'
Этот запрос находит образы без двоеточия и тега - они так же опасны, как явный :latest. После выявления проблемных приложений обновите определения, указав конкретную версию образа, и выполните плановый перезапуск.
Для отладки проблем с контейнерами после смены образа используйте шпаргалку команд Docker - там собраны проверенные практики диагностики падающих контейнеров и анализа логов.