Мы используем Jenkins и Docker в комбинации ... мы настроили Jenkins как модель master / slave, и контейнеры запускаются в подчиненных агентах. Иногда из-за ошибки в плагине jenkins docker или по неизвестным причинам контейнеры остаются болтающимися.

Чтобы убить их всех, нужно время, около 5 секунд на процесс контейнера, а у нас их около 15000. Завершение работы по очистке займет ~ 24 часа. Как я могу удалить сразу несколько контейнеров? или эффективно, чтобы на это ушло меньше времени?

  1. Удалит ли докер-клиент контейнеры?
  2. Есть ли том, где хранятся эти контейнеры, можно ли удалить (плохая идея)
  3. Есть ли потоки / параллелизм, чтобы удалить их быстрее? Я собираюсь запускать задание cron еженедельно, чтобы исправлять эти ошибки, но сейчас у меня нет целого дня, чтобы их удалить.
2
Krish 6 Сен 2016 в 18:37

3 ответа

Лучший ответ

Попробуй это:

  1. Удалить docker-engine
  2. Перезагрузить хост
  3. rm /var/lib/docker

Перезагрузка эффективно останавливает все контейнеры, а удаление докера не позволяет им вернуться после перезагрузки. (если у них установлено restart=always)

3
Michael 6 Сен 2016 в 16:44

Так,

docker kill $(docker ps -a -q)

Не то, что тебе нужно?

РЕДАКТИРОВАТЬ: очевидно, что это не так. Мой следующий дубль:

А) как-то создать список всех контейнеров, которые вы хотите остановить.

Б) Разделите этот список (возможно, просто нарезав его на n частей).

C) Выполнение n заданий параллельно, каждое из которых работает с одним из этих списков-срезов.

Г) Надеюсь, что «докер» достаточно надежен для обработки n процессов, отправляющих n запросов на уничтожение последовательно, параллельно.

E) Если это действительно работает: возможно, начните экспериментировать, чтобы определить оптимальную настройку для n .

1
GhostCat 6 Сен 2016 в 15:58

Если вас интересует только уничтожение процессов, поскольку они не завершаются должным образом (моя оценка того, что вы имеете в виду - поправьте меня, если я ошибаюсь), есть способ пройтись по запущенным процессам контейнера и убить их, используя Pid информацию из метаданных контейнера. Похоже, что на этом этапе вам не обязательно заботиться о завершении чистого процесса (вот почему docker kill занимает так много времени на каждый контейнер - контейнер может не реагировать на правильные сигналы, и поэтому движок терпеливо ждет, и затем убивает процесс), то kill -9 - гораздо более быстрый и радикальный способ завершить эти контейнеры и очистить их.

Быстрый тест с использованием последней версии докера показывает, что я могу убить ~ 100 контейнеров за 11,5 секунд на относительно современном ноутбуке:

$ time docker ps --no-trunc --format '{{.ID}}' | xargs -n 1 docker inspect --format '{{.State.Pid}}' $1 | xargs -n 1 sudo kill -9

real    0m11.584s
user    0m2.844s
sys     0m0.436s

Четкое объяснение происходящего:

  1. Я прошу движок докера предоставить список всех запущенных контейнеров "только полный идентификатор контейнера" ​​(docker ps)
  2. Я прохожу это через docker inspect один за другим, прошу вывести только идентификатор процесса (.State.Pid), который
  3. Затем я перехожу к kill -9, чтобы система напрямую уничтожила контейнерный процесс; намного быстрее, чем ждать, пока двигатель сделает это.

Опять же, это не рекомендуется для общего использования, поскольку оно не позволяет выполнять стандартную (чистую) обработку выхода для контейнерного процесса, но в вашем случае это звучит так, как будто это не важный критерий.

Если есть оставшиеся метаданные контейнера для этих закрытых контейнеров, вы можете очистить их, используя:

docker rm $(docker ps -q -a --filter status=exited)

Это удалит все завершенные контейнеры из хранилища метаданных движка (содержимое /var/lib/docker) и должно быть относительно быстрым для каждого контейнера.

3
Phil E 6 Сен 2016 в 20:01