J'ai une application Ruby simple, qui reçoit des données via un point d'accès HTTP, les traite un peu, les regroupe et les envoie par lots à un point d'accès HTTP distant.
Lorsque je l'exécute sur une machine nue, je sature 4 CPU à 100% et j'obtiens environ 3000reqs/s
(selon ab
l'application est un peu gourmande en ressources informatiques) ;
mais lorsque je l'exécute dans Docker, j'obtiens seulement 1700reqs/s
- Les processeurs semblent atteindre un pic à environ 55-65%. La même application, les mêmes paramètres.
J'ai essayé d'augmenter la concurrence d'ab. L'application elle-même est hébergée dans Passenger, j'ai essayé de l'exécuter dans 20 processus, dans 40 processus (Passenger exécute l'application). Dans Docker, il ne semble pas vouloir aller plus loin.
Je l'exécute via docker-compose
l'hôte est Ubuntu 14.04
$ docker -v
Docker version 1.10.0, build 590d5108
$ docker-compose -v
docker-compose version 1.5.2, build 7240ff3
La moyenne de charge est élevée dans les deux cas (environ 20), mais elle n'est pas liée au disque.
$ 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
Il n'est pas non plus lié au réseau. Même si je désactive l'envoi de données à l'hôte distant et que toutes les communications se font à l'intérieur de la machine, je vois toujours 55-65%.
La configuration pour docker et compose sont par défaut, rien n'a été modifié.
Pourquoi ne puis-je pas saturer les processeurs lorsqu'il est exécuté dans Docker ? Y a-t-il une limite cachée dans Docker ? Comment puis-je découvrir cette limite ?
EDIT1 CPU set, CPU shares
cpuset_cpus:0,1,2,3,4,5,6,7
et/ou cpu_shares: 102400
(100 fois la valeur par défaut) ne semble pas changer la situation.
Il n'y a rien d'intéressant non plus concernant les limitations dans /var/log/*
EDIT2 pont/réseau hôte
Ce n'est pas non plus le docker bridge
réseau. L'effet est le même lorsque j'utilise net: host
dans Docker Compose
Échelle EDIT3
Si j'exécute un deuxième conteneur avec le même code mais avec un port différent exposé, je peux faire monter la charge du processeur à 77 %, mais pas encore à 100 % comme sur une machine nue. Notez que chacun de ces conteneurs exécute 20-40 processus équilibrés en charge avec Passenger à l'intérieur.
EDIT4 Le problème d'Ubuntu ?
Ok, ça semble avoir quelque chose à voir avec Ubuntu. Le même conteneur a été exécuté sur CoreOS - je suis capable de saturer tous les cœurs.
Mais je ne comprends toujours pas la limitation.
EDIT5 Test de DigitalOcean
Pour être tout à fait juste, j'ai pris 2 instances identiques de 16GB 8CPU sur DigitalOcean, toutes deux dans le centre de données de Francfort. J'ai installé l'application sur la version la plus récente d'Ubuntu et la plus récente de CoreOS alpha.
CoreOS 949.0.0: Docker version 1.10.0, build e21da33
Ubuntu 14.04.3: Docker version 1.10.0, build 590d5108
Je ne suis pas sûr de savoir comment obtenir exactement les mêmes builds - il semble que CoreOS ait Docker intégré et FS en lecture seule et avec Ubuntu - je n'ai aucune idée de comment obtenir exactement le build e21da33. Mais la version générale est la même 1.10.0
Je cours ab
à partir d'une machine externe sur DigitalOcean également dans le centre de données de Francfort pour s'assurer que ab
n'est pas une variation. J'ai touché l'IP externe dans les deux cas. Les paramètres de ab
sont les mêmes ( ab -n 40000 -c 1000 -k
), le code est le même.
Les résultats :
Ubuntu: 58-60% CPU 1162.22 [#/sec] (mean)
CoreOS: 100% CPU 4440.45 [#/sec] (mean)
Ça commence à devenir vraiment bizarre.
Pour donner une chance à Ubuntu, j'ai aussi essayé d'ajouter :
security_opt:
- apparmor:unconfined
Mais cela n'a pas changé grand-chose.
EDIT6 Testé le conteneur sous d'autres OS :
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)
Je n'ai toujours aucune idée de la limitation. Il semble que ce soit lié à Debian.
0 votes
Comme vous avez 4 Cpus, je suppose que vous lancez votre conteneur docker avec
docker run --cpu 4
n'est-ce pas ?0 votes
Je le lance avec
docker-compose up -d
- Je ne suis pas sûr de ce qu'il fait à l'intérieur. Je vais essayer de le vérifier. Merci.0 votes
Il semble qu'il n'y ait pas de telle option dans
docker run
seulement ceux-là :--cpu-shares
,--cpu-period
,--cpu-quota
,--cpuset-cpus
,--cpuset-mems
0 votes
Semble maintenant
--cpuset-cpus="" CPUs in which to allow execution (0-3, 0,1)
la syntaxe est--cpuset-cpus=(0-3)
pour vous (ou--cpuset-cpus=(1-4)
)peut-être0 votes
Alors, j'ai essayé
0,1
comme indiqué dans la documentation - il l'a limité à 2 des 8 threads du CPU. J'ai ensuite essayé0,1,2,3,4,5,6,7
- il utilise les 8 threads du CPU, mais encore une fois seulement 55-65% d'entre eux :) Merci quand même pour votre aide !0 votes
Voir aussi theza.ch/2014/09/17/cpu-resources-in-docker-mesos-et-marathon à propos de docker, cpus et threads
0 votes
Je crois que vous voulez en fait démarrer le conteneur et spécifier l'option --cpu-shares. Voir ce lien docs.docker.com/engine/reference/run/ . il explique l'utilisation du CPU pour les conteneurs et la suppression des quotas de CPU.
0 votes
@GHETTO.CHiLD Comme je l'ai mentionné dans EDIT1 - je l'ai déjà essayé. Malheureusement, cela n'affecte pas la situation.
0 votes
Même version de docker sur core-os et ubuntu ? Frappez-vous l'IP du conteneur ou l'IP de l'hôte et comptez-vous sur le transfert de réseau du démon Docker ?
0 votes
C'est à peu près la même version, il peut y avoir une différence mineure dans la construction (un jour ou deux), mais généralement 1.10.0. J'ai essayé à la fois l'ip du conteneur (172.x.x.x) et l'ip de l'hôte. Cela ne fait aucune différence.
0 votes
Docker est sensible au noyau et aux limites. Avez-vous essayé avec le même noyau que cent os (Debian Jessie ou Sid) ?
0 votes
J'ai trouvé une solution, je suis également confronté à ce problème.