05.command vs entrypoint
容器和虚拟机
容器不仅旨在承载操作系统,而是专注于执行一个过程,或者只是分析计算。
当容器内的进程运行完毕时,容器也随之退出,容器和容器内的进程的生命周期是相同的,如果容器内部的应用程序停止或者崩溃,则容器也会退出。
所以,谁来定义容器内运行的应用程序?
在一般的 Dockerfile 中,最后一般会有一个 CMD 指令,如 CMD ["nginx"] ,该命令将定义在容器内运行的进程。
CMD 指令
CMD 指令中的每个参数需要单独分隔:
✔ CMD ["sleep", "5"]
❌ CMD ["sleep 5"]
在启动容器时,显式指定参数将覆盖掉 CMD 中指定的参数。
ENTRYPOINYT 指令
和 CMD 指令不同, ENTRYPOINT 指令将指定一个运行的程序,而可以不指定参数,如 ENTRYPOINT ["sleep"] ,当运行容器时,在运行指令后加上参数,即可表示在 ENTRYPOINT 指令后附加的参数。
如 Dockerfile 中指定了 ENTRYPOINT ["sleep"] ,在启动容器时,使用指令 docker run ubuntu-sleeper 10 ,则相当于在 Dockerfile 中指定了 CMD ["sleep", "10"] 。
如果在运行容器时不指定附加参数,将会出现参数缺失的错误,因此,要指定默认值,需要 ENTRYPOINT 和 CMD 结合使用:
FROM ubuntu
ENTRYPOINT ["sleep"]
CMD ["5"]这样,当不显式指定附加参数时,将 sleep 5s ,在显式指定参数时,如 docker run ubuntu-sleeper 10 ,则最后的 CMD 参数将被替换,sleep 10s 。
修改 ENTRYPOINT 入口程序
如果在运行容器时还需要修改 ENTRYPOINT 的入口程序,需要参数 --entrypoint ,如 docker run --entrypoint sleep2.0 ubuntu-sleeper 10 ,这将会使用 sleep2.0 作为入口程序。