Подтвердить что ты не робот

Docker на Ubuntu не может насытить процессор

У меня есть простое приложение Ruby, в основном оно получает некоторые данные через конечную точку HTTP, немного обрабатывает его, группирует его и отправляет его партиями на удаленную конечную точку HTTP.

Когда я запускаю это на bare-metal - я насыщаю 4 процессора до 100% и опускаюсь 3000reqs/s (согласно ab, приложение немного интенсивно вычисляет);

но когда я запускаю его в Docker, я получаю только 1700reqs/s. Процессоры, похоже, достигают максимума примерно на 55-65%. Это же приложение, те же настройки.

ЦП

Я попытался увеличить ab concurrency. Само приложение размещено в Пассажире, я попытался запустить его в 20 процессах, в 40 процессах (Пассажир запускает приложение). Внутри докера это, похоже, не хочет идти выше.

Я запускаю его через docker-compose, хост Ubuntu 14.04

$ docker -v
Docker version 1.10.0, build 590d5108

$ docker-compose -v
docker-compose version 1.5.2, build 7240ff3

Среднее значение нагрузки в обоих случаях велико (около 20), но оно не связано с диском.

$ vmstat 1
procs -----------memory---------- ---swap-- -----io---- ---system---  ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in      cs  us sy id wa st
22  0      0 8630704  71160 257040    0    0    29     6  177    614   3  1 94  1  0
 7  0      0 8623252  71160 257084    0    0     0    16  9982 83401  46 12 43  0  0
43  0      0 8618844  71160 257088    0    0     0     0  9951 74056  52 10 38  0  0
17  0      0 8612796  71160 257088    0    0     0     0 10143 70098  52 14 34  0  0
17  0      0 8606756  71160 257092    0    0     0     0 11324 70113  48 15 37  0  0
31  0      0 8603748  71168 257104    0    0     0    32  9907 85295  44 12 41  3  0
21  0      0 8598708  71168 257104    0    0     0     0  9895 69090  52 11 36  0  0
22  0      0 8594316  71168 257108    0    0     0     0  9885 68336  53 12 35  0  0
31  0      0 8589564  71168 257124    0    0     0     0 10355 82218  44 13 43  0  0

Он также не связан с сетью. Даже если я отключу отправку данных на удаленный хост, и все коммуникации находятся внутри машины - я все еще вижу 55-65%.

Настройка для docker и compose по умолчанию, ничего не изменено.

Почему я не могу насыщать процессоры, когда он работает внутри Docker? В Докере есть какой-то скрытый предел? Как узнать это ограничение?

EDIT1 CPU set, CPU share

cpuset_cpus:0,1,2,3,4,5,6,7 и/или cpu_shares: 102400 (100 раз по умолчанию), похоже, не изменяет ситуацию.

Существует также ничего интересного об ограничениях в /var/log/*

Сеть моста/хоста EDIT2

Это также не сеть docker bridge. Эффект тот же, когда я использую net: host в Docker Compose

Шкала EDIT3

Если я запускаю второй контейнер с тем же кодом с открытым портом, я могу получить загрузку процессора до 77%, но все же не на 100%, как на голом. Обратите внимание, что каждый из этих контейнеров управляет 20-40 процессами с балансировкой нагрузки внутри пассажира.

Проблема EDIT4 Ubuntu?

Хорошо, похоже, это что-то связано с Ubuntu. Тот же контейнер работал на CoreOS - я могу насытить все ядра.

htop core os

Но я все еще не понимаю ограничения.

EDIT5 Тестирование DigitalOcean

Чтобы быть полностью справедливым, я взял 2 идентичных 16GB 8CPU экземпляра на DigitalOcean, как во Франкфурте, так и в центре данных. Я установил приложение на самый последний Ubuntu и самую последнюю версию CoreOS.

CoreOS 949.0.0: Docker version 1.10.0, build e21da33
Ubuntu 14.04.3: Docker version 1.10.0, build 590d5108

Я не уверен, как получить точно такие же сборки - кажется, что у CoreOS есть встроенный и только для чтения Docker FS и с Ubuntu - я понятия не имею, как правильно построить e21da33. Но общая версия такая же 1.10.0

Я запускаю ab с внешней машины на DigitalOcean также во Франкфурте, чтобы гарантировать, что ab не является изменением. Я ударил внешний IP-адрес в обоих случаях. Параметры для ab одинаковы (ab -n 40000 -c 1000 -k), код тот же.

Результаты:

 Ubuntu:   58-60% CPU    1162.22 [#/sec] (mean)
 CoreOS:     100% CPU    4440.45 [#/sec] (mean)

Это начинает становиться действительно странным. сравнение htop

Чтобы дать Ubuntu шанс, я также попытался добавить:

  security_opt:
     - apparmor:unconfined

Но это не сильно изменилось.

EDIT6 Протестированный контейнер в некоторых других ОС:

Ubuntu 14.04.3   NOT OK (50-60% CPU)
Ubuntu 15.10     NOT OK (50-60% CPU)
Debian 8.3       NOT OK (50-60% CPU)
CentOS 7.2.1511      OK   (100% CPU)
CoreOS 949.0.0       OK   (100% CPU)

По-прежнему не знаю, каково ограничение. Кажется, это связано с Debian.

4b9b3361

Ответ 1

Пожалуйста, не волнуйтесь (или пламените меня) - это не ответ - мне просто нужно больше места, чем позволит комментарий! Я не эксперт по Linux или Docker, но мне очень нравится эта проблема, и я провел некоторое исследование в течение выходных, и у меня есть несколько возможностей для изучения, которые могут помочь. У меня нет испытательной установки, поэтому вышли в тупик.

Теории до сих пор "Для Debian и Ubuntu...":

  • Докер ставит контейнер и подпроцессы в группу, которая что-то дросселируется.

  • Планировщик для ОС и планировщик в Докере контейнер (systemd?) в какой-то мере "сражаются" за процессор и постоянно вытесняя друг друга.

  • Планировщик ОС обрабатывает (a) Контейнер Докеров и (b) приложения в виде отдельных конкурирующих запросов ресурсов и, следовательно, давая каждому около 50%

  • Мне кажется, что ароматы RedHat от linux каким-то образом "интегрированный" докер (читайте "посмотрел, что он делает, и изменил их Настройка ОС или настройка Docker для совместимости "). Что они изменили сделать это? - это может быть то, что делает разницу.

  • Существует сильный толчок для того, чтобы не использовать Docker под RHEL 6, но вместо этого использовать RHEL 7+ - Что они изменили в RH между этими версиями WRT. планирование процессора, что делает их настолько увлеченными использованием 7 +?

Что я буду смотреть дальше:

  • настройка cgroup во время работы.
  • Содержимое любых файлов limits.conf
  • Различия в файлах конфигурации Docker между версией на RH и Ubuntu.
  • (Если бы у меня было время) посмотреть, есть ли у Докера на RHEL 6 (как RHEL 7 нет)

Исследование: https://goldmann.pl/blog/2014/09/11/resource-management-in-docker/
http://www.janoszen.com/2013/02/06/limiting-linux-processes-cgroups-explained/
https://github.com/docker/docker/issues/6791
https://github.com/ibuildthecloud/systemd-docker/issues/15
https://unix.stackexchange.com/questions/151883/limiting-processes-to-not-exceed-more-than-10-of-cpu-usage
http://linux.die.net/man/5/limits.conf
https://marketplace.automic.com/details/centos-official-docker-image
https://www.datadoghq.com/blog/how-to-monitor-docker-resource-metrics/
https://libraries.io/go/github.com%2Fintelsdi-x%2Fsnap-plugin-collector-docker%2Fdocker
https://serverfault.com/questions/356962/where-are-the-default-ulimit-values-set-linux-centos
https://www.centos.org/forums/viewtopic.php?t=8956
https://docs.mongodb.org/manual/reference/ulimit/
http://www.unixarena.com/2013/12/how-to-increase-ulimit-values-in-redhat.html

Если ни одно из этого не помогает, я приношу свои извинения!

Ответ 2

Запуск Docker с systemd исправил эту проблему для меня (Unbuntu 16.04). Все мои 12 потоков используются при 100% в одном контейнере при бенчмаркинге.

Служба Stop Docker:

sudo service docker stop

И запустите его с помощью systemctl:

sudo systemctl start docker

Чтобы запустить Docker при загрузке:

sudo systemctl enable docker

Ответ 3

У нас была та же проблема, мы начали погружаться и обнаружили это: https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt

Вы можете указать --cpu-quota для Docker, и вы хотите, чтобы он соответствовал количеству процессоров, которые вы хотите использовать.

Например, если вы хотите, чтобы контейнер мог использовать 4 ЦП, вы должны установить его в 400000; если вы хотите, чтобы он полностью не ограничивался, укажите -1.

Работал на нас.