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.
Ответы
Ответ 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
.
Работал на нас.