У меня есть простое приложение 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 - я могу насытить все ядра.
Но я все еще не понимаю ограничения.
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)
Это начинает становиться действительно странным.
Чтобы дать 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.