Магазин контейнеров Marathon: полное руководство по управлению хранилищем ядер | AdminWiki

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

30 июля 2026 10 мин. чтения
Содержание статьи

Что такое магазин контейнеров Marathon и зачем им управлять

Магазин контейнеров Marathon - это централизованное хранилище метаданных и образов ядер, которое обслуживает все приложения, развернутые через этот оркестратор. Каждый запущенный инстанс, каждая группа и каждое обновление конфигурации оставляют след именно здесь. Прямой доступ к этому хранилищу дает вам полную инвентаризацию кластера, поиск устаревших образов и проверку целостности конфигураций - задачи, которые стандартный UI Marathon не закрывает.

В отличие от поверхностного просмотра через веб-интерфейс, работа с хранилищем через API позволяет выполнять массовые операции: от аудита всех версий образов до автоматизированной замены устаревших компонентов. Это критически важно, когда в кластере крутятся десятки и сотни приложений, а ручной контроль становится узким местом.

Для специалистов, которые уже работают с Docker в production-окружении и настраивают мониторинг через Prometheus, эта статья даст готовые инструменты для глубокого контроля над Marathon. Если вы еще не знакомы с практиками безопасного деплоя, рекомендую изучить руководство по Docker в production, где разобраны health checks, canary-деплой и управление секретами.

Архитектура хранилища: где живут ваши контейнеры

Хранилище Marathon построено по документо-ориентированной модели и хранит данные в формате JSON. Каждая сущность - приложение, группа, задача - представлена как документ с уникальным идентификатором и набором полей. Физически данные размещаются в state-хранилище Mesos, с которым Marathon синхронизируется через REST API.

Ключевые эндпоинты для доступа:

  • /v2/apps - список всех приложений с их конфигурациями и статусами
  • /v2/groups - иерархическая структура групп приложений
  • /v2/tasks - информация о запущенных и завершенных задачах
  • /v2/deployments - активные и завершенные деплои

Состояние Mesos выступает единственным источником правды. Marathon кэширует данные для ускорения ответов, но при каждом запросе может обращаться к Mesos для актуализации. Это объясняет задержки при первом обращении к эндпоинту после длительного простоя.

Для сложных сценариев диагностики, когда нужно сопоставить данные из Marathon с метриками кластера, пригодятся навыки работы с Kubernetes troubleshooting через метрики - принципы корреляции логов и метрик универсальны для любых оркестраторов.

Ключевые сущности: приложения, группы, образы и версии

Четкое понимание терминологии избавит от путаницы при работе с API и скриптами:

  • Application (приложение) - базовая единица деплоя. Содержит определение контейнера: образ, ресурсы CPU/памяти, переменные окружения, health checks, количество экземпляров.
  • Group (группа) - логическое объединение приложений с общей конфигурацией. Группы могут быть вложенными, образуя иерархию. Путь к группе формирует часть идентификатора приложения: /production/backend/api-service.
  • Container Image (образ контейнера) - ссылка на Docker-образ, который используется для запуска. Может включать тег версии или digest. Именно по этому полю выполняется фильтрация устаревших образов.
  • Version ID (идентификатор версии) - временная метка или UUID, присваиваемый каждой конфигурации приложения при деплое. Хранилище сохраняет историю версий, что позволяет выполнять откат.

Связь между сущностями прямая: группа содержит приложения, каждое приложение ссылается на образ и имеет историю версий. При запросе через API вы получаете полное дерево этих зависимостей в одном JSON-ответе.

Полный перебор записей: стратегии и практические примеры

Стандартный UI Marathon показывает приложения списком с базовой фильтрацией, но не позволяет получить полный дамп всех записей хранилища. Для аудита и инвентаризации нужен прямой доступ через REST API с правильной обработкой пагинации.

Главный инструмент здесь - эндпоинт /v2/apps с параметрами, управляющими объемом возвращаемых данных. Без параметров Marathon возвращает только первые 100 записей, что неприемлемо для крупных кластеров.

Использование REST API для инвентаризации

Базовый запрос для получения всех приложений с полными конфигурациями:

curl -s "http://marathon-host:8080/v2/apps?embed=apps.tasks&embed=apps.lastTaskFailure" | jq .

Параметр embed включает в ответ вложенные объекты: задачи и информацию о последних сбоях. Это экономит отдельные запросы за каждой задачей.

Для обработки больших кластеров управляйте пагинацией через offset и limit:

# Первая страница: приложения с 1 по 200
curl -s "http://marathon-host:8080/v2/apps?offset=0&limit=200"

# Вторая страница: приложения с 201 по 400
curl -s "http://marathon-host:8080/v2/apps?offset=200&limit=200"

Ответ приходит в формате JSON с полем apps, содержащим массив объектов приложений. Каждый объект включает идентификатор, образ, ресурсы, статус и историю версий.

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

curl -s "http://marathon-host:8080/v2/apps" | jq -r '.apps[].container.docker.image' | sort -u

Эта команда извлекает поле image из каждого приложения, сортирует и удаляет дубликаты. Результат - полный перечень образов, которые использует кластер.

Автоматизация сбора данных: скрипт для рекурсивного обхода

Ручные запросы неудобны для регулярного аудита. Bash-скрипт с jq автоматизирует сбор данных по всем группам и приложениям:

#!/bin/bash
MARATHON="http://marathon-host:8080"
OUTPUT="marathon_inventory_$(date +%Y%m%d).json"

# Получаем все приложения с задачами и группами
curl -s "${MARATHON}/v2/apps?embed=apps.tasks&embed=apps.counts" | jq '{
  timestamp: now,
  apps: [.apps[] | {
    id: .id,
    image: .container.docker.image,
    instances: .instances,
    cpus: .cpus,
    mem: .mem,
    version: .version,
    tasks_running: .tasksRunning,
    tasks_healthy: .tasksHealthy
  }]
}' > "$OUTPUT"

echo "Inventory saved to $OUTPUT"

Скрипт собирает ключевые поля: идентификатор, образ, количество экземпляров, ресурсы CPU/памяти, версию конфигурации и статусы задач. Запуск через cron раз в сутки создает историю изменений кластера.

Для кластеров с глубокой вложенностью групп добавьте рекурсивный обход через /v2/groups с параметром embed=groups.apps. Это вернет полное дерево групп со всеми приложениями в одном ответе.

Продвинутая сортировка и фильтрация результатов

Получение полного списка - только первый шаг. Реальная ценность хранилища раскрывается через целенаправленные запросы, которые извлекают только нужные данные. Marathon API поддерживает фильтрацию на стороне сервера, а утилита jq дает неограниченные возможности постобработки на клиенте.

Фильтрация через API: параметры и операторы

Marathon поддерживает query-параметр filter с синтаксисом поле:оператор:значение. Доступные операторы: eq (равно), neq (не равно), contains (содержит), like (регулярное выражение).

Примеры фильтрации:

# Все приложения с образом nginx
curl -s "http://marathon-host:8080/v2/apps?filter=container.docker.image:contains:nginx"

# Приложения с более чем 2 экземплярами
curl -s "http://marathon-host:8080/v2/apps?filter=instances:gt:2"

# Комбинированный фильтр: nginx в production-группе
curl -s "http://marathon-host:8080/v2/apps?filter=id:like:%2Fproduction%2F.*&filter=container.docker.image:contains:nginx"

Параметр order сортирует результаты по указанному полю:

# Сортировка по использованию CPU (по убыванию)
curl -s "http://marathon-host:8080/v2/apps?order=-cpus"

# Сортировка по дате последнего обновления
curl -s "http://marathon-host:8080/v2/apps?order=version"

Ограничение API: фильтрация работает только по полям верхнего уровня объекта приложения. Для сложных условий, например поиска по меткам или переменным окружения, нужна постобработка через jq.

Магия jq: сортировка и анализ на стороне клиента

jq превращает JSON-ответы Marathon в структурированные отчеты. Вот несколько боевых примеров:

Топ-10 приложений по потреблению CPU:

curl -s "http://marathon-host:8080/v2/apps" | jq -r '
  [.apps[] | {id: .id, cpus: .cpus}] 
  | sort_by(.cpus) 
  | reverse 
  | .[0:10] 
  | ["ID","CPUs"], (.[] | [.id, .cpus]) 
  | @tsv'

Подсчет приложений на каждый образ:

curl -s "http://marathon-host:8080/v2/apps" | jq -r '
  [.apps[] | .container.docker.image] 
  | group_by(.) 
  | map({image: .[0], count: length}) 
  | sort_by(.count) 
  | reverse'

Поиск приложений с устаревшим образом:

curl -s "http://marathon-host:8080/v2/apps" | jq -r '
  .apps[] 
  | select(.container.docker.image | test("myapp:v1\\.0\\.\\d+")) 
  | "\(.id) -> \(.container.docker.image)"'

Этот запрос находит все приложения, использующие образы семейства v1.0.x, и выводит их идентификаторы с полным именем образа. Результат - готовая карта для планирования обновления.

Для продакшен-сред, где важна наблюдаемость всего конвейера, рекомендую настроить централизованный сбор метрик и логов. В статье по маршрутизации логов и метрик разобрана архитектура с Fluentd, Prometheus и Grafana, которая дополнит данные из Marathon Store.

Экспорт данных для аудита и интеграции

Данные из Marathon Store нужны не только для оперативных задач. Регулярный экспорт в машиночитаемые форматы позволяет строить отчеты, передавать информацию в системы мониторинга и хранить историю для аудита.

Из JSON в CSV: готовые команды

CSV - универсальный формат для Excel, Google Sheets и любых систем отчетности. jq конвертирует JSON в CSV одной командой:

curl -s "http://marathon-host:8080/v2/apps" | jq -r '
  ["ID","Image","Instances","CPUs","Memory","Version"] as $header 
  | $header, (
    .apps[] | [
      .id,
      .container.docker.image,
      .instances,
      .cpus,
      .mem,
      .version
    ]
  ) 
  | @csv' > marathon_report.csv

Для выборочного экспорта добавьте фильтр перед конвертацией. Например, только приложения в группе production:

curl -s "http://marathon-host:8080/v2/apps" | jq -r '
  [.apps[] | select(.id | startswith("/production"))] as $prod
  | ["ID","Image","Instances"], ($prod[] | [.id, .container.docker.image, .instances]) 
  | @csv' > production_apps.csv

Автоматизация отчетности: скрипт с расписанием

Регулярный экспорт с отправкой отчета освобождает от ручного контроля. Bash-скрипт для еженедельного отчета:

#!/bin/bash
MARATHON="http://marathon-host:8080"
REPORT="/tmp/marathon_weekly_$(date +%Y%m%d).csv"

# Собираем данные
curl -s "${MARATHON}/v2/apps" | jq -r '
  ["ID","Image","Instances","TasksRunning","TasksHealthy"] as $h
  | $h, (.apps[] | [.id, .container.docker.image, .instances, .tasksRunning, .tasksHealthy])
  | @csv' > "$REPORT"

# Отправляем через email (требуется настроенный msmtp или mailx)
echo "Еженедельный отчет по Marathon Store приложен" | mailx -s "Marathon Weekly Report" -a "$REPORT" admin@example.com

Для интеграции с Prometheus напишите custom exporter, который отдает метрики из Marathon API. Скрипт на Python с библиотекой prometheus_client может экспортировать количество приложений, распределение образов и статусы задач как метрики для алертов.

Практические кейсы: управление конфигурациями и диагностика

Техники перебора и фильтрации - инструменты. Их ценность проявляется в конкретных сценариях, с которыми DevOps-инженеры сталкиваются ежедневно.

Массовое обновление образов: безопасный подход

Задача: заменить устаревший образ myapp:v1.2.3 на myapp:v2.0.0 во всех приложениях кластера. Ручное обновление через UI - риск ошибки и огромные затраты времени.

Алгоритм безопасного массового обновления:

  1. Инвентаризация: получить список всех приложений с целевым образом.
    curl -s "http://marathon-host:8080/v2/apps" | jq -r '
      .apps[] 
      | select(.container.docker.image == "myapp:v1.2.3") 
      | .id' > apps_to_update.txt
  2. Тестовое обновление: выбрать одно некритичное приложение и обновить его через PUT-запрос с новым образом.
  3. Верификация: дождаться успешного health check и стабильной работы в течение 5-10 минут.
  4. Массовый деплой: выполнить обновление остальных приложений с интервалом 30 секунд между запросами для снижения нагрузки на кластер.
  5. Мониторинг: отслеживать статус деплоя через /v2/deployments.

Скрипт для массового обновления с контролем ошибок:

#!/bin/bash
MARATHON="http://marathon-host:8080"
OLD_IMAGE="myapp:v1.2.3"
NEW_IMAGE="myapp:v2.0.0"

for app_id in $(cat apps_to_update.txt); do
  echo "Updating $app_id..."
  # Получаем текущую конфигурацию
  curl -s "${MARATHON}/v2/apps${app_id}" | jq --arg img "$NEW_IMAGE" '
    .app | .container.docker.image = $img
  ' | curl -s -X PUT -H "Content-Type: application/json" "${MARATHON}/v2/apps${app_id}" -d @-
  
  if [ $? -eq 0 ]; then
    echo "  Success"
  else
    echo "  FAILED"
  fi
  sleep 30
done

Диагностика кластера через анализ хранилища

Хранилище Marathon содержит достаточно данных для выявления проблем без дополнительных систем мониторинга.

Поиск приложений в статусе Unknown:

curl -s "http://marathon-host:8080/v2/apps" | jq -r '
  .apps[] 
  | select(.tasksHealthy == null and .tasksRunning == 0) 
  | "\(.id) - no healthy tasks, \(.tasksUnhealthy) unhealthy"'

Выявление приложений с частыми перезапусками:

curl -s "http://marathon-host:8080/v2/apps?embed=apps.lastTaskFailure" | jq -r '
  .apps[] 
  | select(.lastTaskFailure != null) 
  | "\(.id) last failure: \(.lastTaskFailure.message[0:100])"'

Поиск аномального потребления ресурсов: сравните запрошенные ресурсы с фактическим использованием через Mesos API. Расхождение более 30% указывает на неправильно настроенные лимиты или утечку памяти в контейнере.

Для сложных случаев диагностики, когда проблема не ограничивается Marathon, а затрагивает весь контейнерный стек, обратитесь к шпаргалке по управлению контейнерами Docker. Там собраны проверенные практики отладки падающих контейнеров и безопасной очистки диска.

Ограничения, ошибки и лучшие практики

Работа с Marathon Store через API имеет подводные камни, которые приводят к неполным данным или ложным выводам.

Типичные ошибки:

  • Игнорирование пагинации. Запрос без параметров возвращает только первые 100 записей. Если в кластере 500 приложений, вы получите неполную картину. Всегда проверяйте заголовок X-Marathon-Count в ответе и сравнивайте с количеством полученных объектов.
  • Неверная интерпретация версий. Поле version в объекте приложения - это версия конфигурации, а не версия образа. Обновление образа создает новую версию конфигурации, но старая сохраняется в истории. Для определения реально работающего образа смотрите container.docker.image.
  • Превышение лимита запросов. Marathon имеет встроенный rate limiting. При интенсивном опросе API возвращает 429 Too Many Requests. Решение: кэширование данных на стороне клиента и использование event stream для отслеживания изменений вместо периодического опроса.

Ограничения API:

  • Максимальный размер ответа - 32 МБ. Для очень крупных кластеров с детальным embed это может быть недостаточно. Разбивайте запросы по группам.
  • Фильтрация на стороне сервера ограничена простыми условиями. Сложная логика требует постобработки через jq.
  • Event stream (/v2/events) доставляет события в формате Server-Sent Events и требует постоянного подключения. Обрыв соединения приводит к потере событий.

Лучшие практики:

  • Кэшируйте результаты полного перебора в локальный файл и обновляйте его инкрементально через event stream.
  • Создавайте резервные копии конфигураций через ежедневный дамп /v2/apps с полным embed. Храните историю минимум 30 дней.
  • Для продакшен-сред используйте выделенного пользователя с правами только на чтение Marathon API.
  • Все скрипты автоматизации тестируйте на staging-кластере перед запуском в production.

Сравнение с аналогами: Marathon Store vs etcd vs Docker Registry

Marathon Store решает специфическую задачу: хранение конфигураций приложений и метаданных деплоя в экосистеме Mesos. Для понимания его места полезно сравнение с инструментами из других оркестраторов.

ХарактеристикаMarathon Storeetcd (Kubernetes)Docker Registry
Модель данныхДокументо-ориентированная (JSON)Ключ-значениеСлои образов + манифесты
ПроизводительностьСредняя, зависит от Mesos stateВысокая, оптимизирован для распределенного консенсусаВысокая для операций push/pull
МасштабируемостьОграничена одним экземпляром MarathonГоризонтальная через RAFT-кластерГоризонтальная через репликацию
Инструменты доступаREST API, ограниченная фильтрацияgRPC API, богатая экосистема (etcdctl)Docker CLI, HTTP API
Основное назначениеМетаданные оркестрацииРаспределенная конфигурация и service discoveryХранение и дистрибуция образов

Marathon Store удобен, когда вы работаете в экосистеме Mesos и вам нужен прямой доступ к конфигурациям приложений без дополнительных абстракций. Он хранит ровно то, что нужно для оркестрации: определения приложений, групп, статусы задач и историю версий.

Если вы планируете миграцию с Mesos/Marathon на Kubernetes, стоит заранее изучить альтернативы. Для простых сценариев оркестрации без сложной экосистемы Kubernetes рекомендую рассмотреть Docker Swarm как стабильную альтернативу - развертывание кластера занимает минуты, а встроенные механизмы rolling updates и секретов покрывают большинство потребностей.

Docker Registry решает другую задачу - хранение самих образов контейнеров, а не метаданных об их использовании. В production-окружении эти инструменты работают вместе: Registry хранит образы, Marathon Store отслеживает, какие версии образов где развернуты.

Поделиться:
Сохранить гайд? В закладки браузера