詳文:理解Docker容器的進程管理:https://yq.aliyun.com/articles/5545
在Docker中,每個Container都是Docker Daemon的子進程。
docker exec
命令可以進入指定的容器內部執行命令。由它啟動的進程屬於容器的namespace和相應的cgroup。但是這些進程的父進程是Docker Daemon而非容器的PID1進程。
如果我們在宿主機操作系統中手動殺掉容器的啟動進程,容器會自動結束,而容器名空間中所有進程也會退出。
Docker提供了兩個命令docker stop
和docker kill
來向容器中的PID1進程發送信號。
當執行docker stop
命令時,docker會首先向容器的PID1進程發送一個SIGTERM信號,用於容器內程序的退出。如果容器在收到SIGTERM后沒有結束, 那么Docker Daemon會在等待一段時間(默認是10s)后,再向容器發送SIGKILL信號,將容器殺死變為退出狀態。這種方式給Docker應用提供了一個優雅的退出(graceful stop)機制,允許應用在收到stop命令時清理和釋放使用中的資源。而docker kill
可以向容器內PID1進程發送任何信號,缺省是發送SIGKILL信號來強制退出應用。
- 容器的PID1進程需要能夠正確的處理SIGTERM信號來支持優雅退出。
- 如果容器中包含多個進程,需要PID1進程能夠正確的傳播SIGTERM信號來結束所有的子進程之后再退出。
- 確保PID1進程是期望的進程。缺省sh/bash進程沒有提供SIGTERM的處理,需要通過shell腳本來設置正確的PID1進程,或捕獲SIGTERM信號。
在docker容器中,PID1同樣會接管孤兒進程。
如果在容器中運行多個進程,PID1進程需要有能力接管“孤兒”進程並回收“僵屍”進程。
利用Supervisor等工具作為PID1進程是在容器中支持多進程管理的主要實現方式;和簡單利用shell腳本fork子進程相比,采用Supervisor等工具有很多好處:
- 一些傳統的服務不能以PID1進程的方式執行,利用Supervisor可以方便的適配
- Supervisor這些監控工具大多提供了對SIGTERM的信號傳播支持,可以支持子進程優雅的退出