2016-04-21 73 views
2

我有一個docker容器,它運行用python Flask編寫的REST服務。我在OSx上使用VirtualBox運行容器。爲什麼docker在高內存使用率時崩潰?

這是在OSX上的內存統計信息在容器啓動時:

enter image description here

所以,我有3GB〜可用內存。所以,我跑我的容器2 GB

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

的內存限制,現在我送〜100個REST請求到容器上運行,而在同一時間運行docker stats服務。

最終,碼頭容器崩潰。

在容器崩潰之前,我正在粘貼來自docker stats以下的數據。

崩潰1:當運行100個不同的請求(容器崩潰幾乎瞬間

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 

崩潰2:大約30之後當運行1個請求100倍(容器崩潰)

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在碰撞後顯示以下內容

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

運行的dmesg顯示了幾個內存不足的錯誤:

➜ ~ 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 

問題

  1. 我怎樣才能避免這樣的事故?

  2. 這只是在我的本地機器上,但最終我打算將此容器部署到生產中。我應該遵循什麼方法來防止崩潰?我應該將這個容器的多個克隆放在Nginx負載均衡器後面嗎?

  3. 在生產中,我計劃在單個服務器上運行單個容器。如果我在服務器上運行單個容器,並且不在該服務器上運行其他任何內容,容器是否能夠使用所有可用的計算資源?

+0

如果內核內存不足,Linux內核就有殺死進程的習慣。找出它的原因。 –

+0

如果您在單個服務器上運行單個容器,爲什麼使用contsiner? – dirn

回答

2

歡迎資源:)

的容器上放置一個極限的精彩世界並沒有讓你留下的限制下,它只是告訴內核何時開始擠壓你的時候殺您。你必須保持低於你的極限。在很多情況下,這意味着當你無法在預算範圍內滿足他們的需求時,觀察你的內存佔用情況,排隊或放棄請求。 AKA減載。

不過,好處是當你需要更多的容器副本時,你現在有一個非常明確的信號。

+0

「在很多情況下,這意味着當你無法在預算範圍內滿足他們的需求時,觀察你的內存佔用和排隊或者丟棄請求」我想這樣的事情是在應用程序/代碼級完成的?另外,是否有東西會監視內存佔用情況,並在容器崩潰之前創建副本?我從生產角度考慮這個問題 – Anthony

+0

一些解決方案內部包括用於自我監控和卸載的庫,擁有響應負載增長容器的控制系統,響應負載添加複製品的控制系統,以及「機會主義」內存借用等待控制系統。 –

+0

哎呀,按回車。簡而言之,在OSS的土地上,並非所有這些東西都可以提供給你。 Kubernetes內置支持自動縮放副本以響應加載,但只能水平。 Kubernetes也有能力描述借用記憶的容器,但我認爲這並不像我們想要的那樣健壯。您確實需要比普通Docker更全面的東西來使這種情況變得易於管理,這就是Kubernetes存在的原因(僅作爲示例)。 –

相關問題