2015-10-14 64 views
23

我不是在詢問有關碼頭工使用主管,而只是想讓我的理解得到驗證。在碼頭使用主管

我知道docker在運行時運行一個進程。另外,當我們需要在容器中運行多個進程時使用主管。

我已經看到幾個例子,其中一個容器是從基礎鏡像啓動的,並且安裝了幾個服務,並且容器承諾形成一個新的鏡像,全部沒有主管。

所以,我的基本疑問是兩種方法之間有什麼區別。

我的理解是,當docker容器停止時,它向PID 1的進程發送一個kill信號,PID 1管理子進程並停止所有的子進程,而這正是supervisor完成的任務,而我們可以安裝多進程沒有管理員只有一個進程可以運行,當碼頭運行發出,當容器停止時,只有PID 1將被髮送信號,其他運行進程將不會正常停止。

請確認我對使用supervisord的理解是否正確。

感謝

+0

更新2016年9月:參見[我的新答案](http://stackoverflow.com/a/39593409/6309):docker守護進程可以在Docker 1.12中爲你處理這些殭屍進程。 – VonC

回答

38

,而我們可以在沒有監督員安裝多個過程中,當搬運工運行時發出,當容器只能停在PID 1將發送信號和其他正在運行的進程只有一個進程可以運行不會優雅地停下來。

是的,雖然它取決於你的主進程如何運行(前臺或後臺)以及它如何收集子進程。

即什麼是「Trapping signals in Docker containers

docker stop詳述通過發送SIGTERM信號停止運行的容器,讓主工藝處理並使用SIGKILL在寬限期後終止應用程序。

發送到容器的信號由正在運行的主進程(PID 1)處理。

如果應用程序在前臺,意味着應用程序是容器中的主進程(PID1),它可以直接處理信號。

但是:

以信號可能是一個背景,你不能直接發送任何信號的過程。在這種情況下,一種解決方案是設置一個shell腳本作爲入口點並編排該腳本中的所有信號處理。

的問題是「Docker and the PID 1 zombie reaping problem

的Unix的設計是這樣一種方式,父進程必須明確地「等待」子進程終止,以收集其退出狀態進一步詳述。殭屍進程一直存在,直到父進程執行此操作,並使用系統調用系列調用的waitpid()系列調用。

爲了消除其殭屍而在子進程上調用waitpid()的操作稱爲「收割」。

init進程 - PID 1 - 有一個特殊的任務。其任務是「採用」孤兒過程。

https://blog.phusion.nl/wp-content/uploads/2015/01/adoption.png

操作系統預計init進程謀取收養的孩子了。

問題與碼頭工人:

我們看到,很多人只能運行一個進程在它們的容器,他們認爲,當他們運行此單過程中,他們就完成了。
但最有可能的是,這個過程沒有被寫成像一個正確的init過程那樣工作。
也就是說,它可能期望另一個init流程來完成這項工作,而不是正確收穫採用的流程,並且是正確的。

使用像phusion/baseimage-docker這樣的圖像幫助管理一個(或多個)進程,同時保持主進程符合init。

它使用runit instead of supervisord,多進程管理:

Runit是不是有解決收割問題。相反,它支持多個進程。鼓勵多個流程的安全性(通過流程和用戶隔離)。
Runit使用的內存少於Supervisord,因爲Runit是用Python編寫的C和Supervisord。
並且在一些使用情況下,容器中的進程重新啓動優於整個容器重新啓動。

該圖片包括一個my_init script,它負責照顧「收穫」問題。

在baseimage-docker中,我們鼓勵在單個容器中運行多個進程。雖然不一定是多個服務。
邏輯服務可以由多個操作系統進程組成,我們提供的設施可以輕鬆實現。

+0

感謝您的精心解答。我正在嘗試phusion映像,據我所知每當容器啓動時它會運行/etc/init.d中的任何內容。但是,我在init.d中有一個不在容器啓動時啓動的服務。你能幫忙嗎? – user3275095

+0

當然:你可以問一個新的問題,你的新安裝的細節?這樣,我(和其他人)可以看看。 – VonC

+0

噢..我的錯誤是/etc/my_init.d – user3275095

10

更新2016年9月的泊塢窗1.12(Q4 2016/Q1 2017)

Arnaud Porterie只是twitted

[]剛剛合併:與docker run --initRick Grimes將採取所有的殭屍照顧。

commit eabae09

PR 26061: 「添加init進程的殭屍戰鬥和信號處理」(和PR 26736

這增加了打擊殭屍小C的二進制文件。它安裝在 /dev/init下,並且被用戶指定的參數前置。您通過守護進程標記dockerd --init啓用它,因爲它被 禁用,因爲它是向後兼容的默認值。

您也可以覆蓋守護進程選項,或者在容器基礎上用docker run --init=true|false指定此選項。

你可以通過運行一個像這樣的進程來測試這個過程,作爲 容器中的pid 1,並看到容器中出現的額外的殭屍,因爲它運行的是 。

int main(int argc, char ** argv) { 
    pid_t pid = fork(); 
    if (pid == 0) { 
     pid = fork(); 
     if (pid == 0) { 
      exit(0); 
     } 
     sleep(3); 
     exit(0); 
    } 
    printf("got pid %d and exited\n", pid); 
    sleep(20); 
} 

docker daemon現在有選項

--init 

運行容器內的初始化轉發信號和收穫過程

+0

感謝您的更新。 – user3275095