Dockerfile中CMD主要目的是爲容器提供默認啓動命令
CMD命令格式:
1、CMD ["executable","param1","param2"]
exec形式,推薦使用 exec表單被解析爲JSON數組,必須使用雙引號
2、CMD ["param1","param2"]
作爲entrypoint參數使用 應使用JSON數組格式
3、CMD command param1 param2
shell形式
以nginx鏡像爲例
shell形式:CMD nginx "-g daemon off;"
exec形式:CMD ["nginx","-g","daemon off;"]
可以看出兩種形式容器啓動命令是不同的
查看容器進程,shell形式下nginx進程並不是PID爲1的進程
使用shell形式命令將被解析爲/bin/sh -c <command>,這將導致<command>不能作爲容器PID爲1的進程運行,不利於docker stop時容器的優雅退出
PID1進程對於操作系統而言具有特殊意義。操作系統的PID1進程是init進程,以守護進程方式運行,是所有其他進程的祖先,具有完整的進程生命週期管理能力。在Docker容器中,PID1進程是啓動進程,它也會負責容器內部進程管理的工作。而這也將導致進程管理在Docker容器內部和完整操作系統上的不同。
當執行docker stop命令時,docker會首先向容器的PID1進程發送一個SIGTERM信號,用於容器內程序的退出。如果容器在收到SIGTERM後沒有結束, 那麼Docker Daemon會在等待一段時間(默認是10s)後,再向容器發送SIGKILL信號,將容器殺死變爲退出狀態。這種方式給Docker應用提供了一個優雅的退出(graceful stop)機制,允許應用在收到stop命令時清理和釋放使用中的資源。而docker kill可以向容器內PID1進程發送任何信號,缺省是發送SIGKILL信號來強制退出應用。
執行docker stop來看一下二者的區別,可以很明顯看出shell形式是被強制殺死
ENTRYPOINT有兩種形式:
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2
ENTRYPOINT也分爲shell形式跟exec形式,效果跟CMD相同,此處不做過多介紹
參考:
https://www.cnblogs.com/ilinuxer/p/6188303.html
https://docs.docker.com/engine/reference/builder/#cmd
https://docs.docker.com/engine/reference/builder/#entrypoint