2016-04-21 2 views
2

J'ai un conteneur docker qui exécute mon service REST écrit en python Flask. Je cours le conteneur using VirtualBox sur OSx.Pourquoi le docker plante-t-il en cas d'utilisation intensive de la mémoire?

Ce sont les statistiques de la mémoire sur OSx au moment où le conteneur est lancé:

enter image description here

Donc, j'ai ~ 3 Go de mémoire libre. Alors je lance mon conteneur avec limite de mémoire de 2 Go

docker run -d -m 2g --name mycontainer -p 5000:5000 foobar 

J'envoie ~ 100 demandes REST au service en cours d'exécution sur le conteneur en même temps d'exécution docker stats.

Éventuellement, le conteneur docker se bloque.

Je colle sous les données de docker stats juste avant le plantage du conteneur.

crash 1: Lors de l'exécution de 100 demandes différentes (Container tombe en panne presque instantanément

CONTAINER   CPU %    MEM USAGE/LIMIT  MEM %    NET I/O    BLOCK I/O 
27ee4ed4f98a  99.27%    256.9 MB/2.147 GB 11.96%    163.2 kB/7.958 kB 107.4 MB/0 B 
CONTAINER   CPU %    MEM USAGE/LIMIT MEM %    NET I/O    BLOCK I/O 
27ee4ed4f98a  99.77%    324 MB/2.147 GB 15.09%    163.2 kB/7.958 kB 107.4 MB/0 B 
CONTAINER   CPU %    MEM USAGE/LIMIT MEM %    NET I/O    BLOCK I/O 
CONTAINER   CPU %    MEM USAGE/LIMIT MEM %    NET I/O    BLOCK I/O 
CONTAINER   CPU %    MEM USAGE/LIMIT MEM %    NET I/O    BLOCK I/O 

Accident 2. Lors de l'exécution 1 demande 100 fois (accidents de conteneurs après environ 30)

CONTAINER   CPU %    MEM USAGE/LIMIT  MEM %    NET I/O    BLOCK I/O 
41fc484677fb  79.00%    891.5 MB/2.147 GB 41.52%    12.13 MB/429.8 kB 2.379 GB/61.85 MB 
CONTAINER   CPU %    MEM USAGE/LIMIT MEM %    NET I/O    BLOCK I/O 
41fc484677fb  85.83%    892 MB/2.147 GB 41.54%    12.13 MB/429.8 kB 3.071 GB/61.85 MB 
CONTAINER   CPU %    MEM USAGE/LIMIT MEM %    NET I/O    BLOCK I/O 
41fc484677fb  85.83%    892 MB/2.147 GB 41.54%    12.13 MB/429.8 kB 3.071 GB/61.85 MB 
CONTAINER   CPU %    MEM USAGE/LIMIT MEM %    NET I/O    BLOCK I/O 
41fc484677fb  86.01%    892 MB/2.147 GB 41.54%    12.13 MB/429.8 kB 3.81 GB/61.85 MB 
CONTAINER   CPU %    MEM USAGE/LIMIT MEM %    NET I/O    BLOCK I/O 
41fc484677fb  86.01%    892 MB/2.147 GB 41.54%    12.13 MB/429.8 kB 3.81 GB/61.85 MB 
CONTAINER   CPU %    MEM USAGE/LIMIT  MEM %    NET I/O    BLOCK I/O 
41fc484677fb  86.28%    892.2 MB/2.147 GB 41.55%    12.13 MB/429.8 kB 4.508 GB/61.85 MB 
CONTAINER   CPU %    MEM USAGE/LIMIT  MEM %    NET I/O    BLOCK I/O 
41fc484677fb  86.28%    892.2 MB/2.147 GB 41.55%    12.13 MB/429.8 kB 4.508 GB/61.85 MB 
CONTAINER   CPU %    MEM USAGE/LIMIT MEM %    NET I/O    BLOCK I/O 
CONTAINER   CPU %    MEM USAGE/LIMIT MEM %    NET I/O    BLOCK I/O 
CONTAINER   CPU %    MEM USAGE/LIMIT MEM %    NET I/O    BLOCK I/O 

docker ps -a indique ce qui suit après l'accident

CONTAINER ID  IMAGE      COMMAND    CREATED    STATUS      PORTS    NAMES 
41fc484677fb  foobar "python service.py" 7 minutes ago  Exited (137) 2 minutes ago      mycontainer 

dmesg en cours d'exécution montre plusieurs des erreurs de mémoire:

➜ ~ docker exec -it mycontainer dmesg | grep "Out of memory" 
Out of memory: Kill process 2006 (python) score 872 or sacrifice child 
Out of memory: Kill process 2496 (python) score 873 or sacrifice child 
Out of memory: Kill process 2807 (python) score 879 or sacrifice child 
Out of memory: Kill process 3101 (python) score 875 or sacrifice child 
Out of memory: Kill process 5393 (python) score 868 or sacrifice child 
Out of memory: Kill process 5647 (python) score 868 or sacrifice child 
Out of memory: Kill process 5926 (python) score 877 or sacrifice child 
Out of memory: Kill process 6328 (python) score 873 or sacrifice child 
Out of memory: Kill process 7923 (python) score 872 or sacrifice child 
Out of memory: Kill process 10183 (python) score 873 or sacrifice child 

Question

  1. Comment puis-je éviter les accidents comme ceux-ci?

  2. Ceci est juste sur ma machine locale mais finalement je prévois de déployer ce conteneur à la production. Quelles approches dois-je suivre pour me protéger contre les accidents? Devrais-je supporter plusieurs clones de ce conteneur derrière un équilibreur de charge Nginx?

  3. En production, je prévois d'exécuter un seul conteneur sur un seul serveur. Si je lance un conteneur unique sur un serveur et que je n'exécute rien d'autre sur ce serveur, le conteneur pourra-t-il utiliser toutes les ressources informatiques disponibles?

+0

Le noyau Linux a l'habitude de tuer des processus s'il manque de mémoire. Cherchez les raisons pour lesquelles elle le fait. –

+0

Si vous utilisez un seul conteneur sur un seul serveur, pourquoi utilisez-vous un contsiner? – dirn

Répondre

2

Bienvenue dans le monde merveilleux des ressources :)

fixant une limite à un conteneur ne vous rend pas rester sous la limite, il indique que le noyau quand commencer à vous presser et quand tuer toi. Vous devez rester en dessous de votre limite. Dans de nombreux cas, cela signifie que vous devez surveiller votre empreinte mémoire et mettre en attente ou supprimer des demandes lorsque vous ne pouvez pas les satisfaire dans les limites de votre budget. AKA délestage. L'avantage, cependant, est que vous avez maintenant un signal assez clair lorsque vous avez besoin de plus de répliques de vos conteneurs.

+0

"Dans de nombreux cas, cela signifie surveiller votre empreinte mémoire et mettre en file d'attente ou abandonner des demandes lorsque vous ne pouvez pas les satisfaire dans les limites de votre budget" Je suppose que quelque chose comme ça est fait au niveau application/code. En outre, y a-t-il quelque chose qui surveille l'empreinte de la mémoire et crée une réplique juste avant que le conteneur ne se bloque? Je pense à cela du point de vue de la production – Anthony

+0

Certaines des solutions comprennent des bibliothèques pour l'autocontrôle et le délestage, des systèmes de contrôle qui font croître les conteneurs en fonction de la charge, des systèmes de contrôle qui ajoutent des répliques en fonction de la charge et emprunt de mémoire en attendant les systèmes de contrôle. –

+0

Oups, appuyez sur Entrée. La nouvelle est que dans les terres OSS, toutes ces choses ne sont pas disponibles pour vous. Kubernetes a intégré la prise en charge des réplicas à mise à l'échelle automatique en réponse à la charge, mais uniquement horizontalement. Kubernetes a également la capacité de décrire des conteneurs qui empruntent de la mémoire, mais je ne pense pas que ce soit aussi robuste que nous le souhaitons. Vous avez vraiment besoin de quelque chose de plus holistique que le simple Docker pour rendre de telles situations gérables, c'est pourquoi Kubernetes existe (juste comme un exemple). –