docker基础
01、Docker简介
02、Docker的安装(通过yum安装)
03、Docker安装的问题补充
04、Docker的安装(通过RPM软件包)
05、Docker的安装(通过脚本安装)
06、Docker的卸载
07、Docker配置阿里云镜像加速器
08、Docker中的基本概念和底层原理
09、Docker常用命令(帮助命令)
10、Docker常用命令(镜像命令)
11、Docker常用命令(容器命令01)
12、Docker常用命令(容器命令02)
13、Docker常用命令(容器命令03)
14、Docker安装Nginx
15、Docker图形化管理工具Portainer
16、Docker镜像讲解
17、Docker镜像分层的理解
18、Docker镜像的commit操作
19、Docker容器数据卷介绍
20、Docker容器数据卷的应用
21、Docker中数据卷相关命令
22、Docker数据卷实现MySQL数据持久化
23、DockerFile的方式挂载数据卷
24、Docker数据卷容器的说明与共享数据原理
25、DockerFile文件详解
26、Docker实战:自定义CentOS镜像
27、CMD指令和ENTRYPOINT指令的区别
28、ONBUILD指令介绍
29、COPY指令和ADD指令
30、自定义Tomcat9镜像
31、发布镜像到DockerHub
32、将本地镜像推送到阿里云
33、补充:save和load命令说明
34、Jenkins + Docker + Github 自动部署
本文档使用 MrDoc 发布
-
+
首页
27、CMD指令和ENTRYPOINT指令的区别
### **1、CMD指令和ENTRYPOINT指令说明** **CMD指令, 支持三种格式:** ```python CMD ["executable","param1","param2"] :使用 exec 执行,推荐方式; CMD command param1 param2 :在 /bin/sh 中执行,提供给需要交互的应用; CMD ["param1","param2"] :提供给 ENTRYPOINT 的默认参数; ``` 每个Dockerfile只能生效一条CMD指令。如果指定了多条CMD指令,只有最后一条生效。 如果用户启动容器时候指定了运行的命令,则会覆盖掉CMD指定的命令。 **ENTRYPOINT指令,支持两种格式:** ```python ENTRYPOINT ["executable", "param1", "param2"] ENTRYPOINT command param1 param2 :shell中执行 ``` 每个Dockerfile中只能生效一个ENTRYPOINT指令,当有多个ENTRYPOINT指令时,只有最后一个起效。 如果用户启动容器时候指定了运行的命令,不会被`docker run`执行的命令参数覆盖。(追加效果:`docker run`命令之后的参数,会被当做参数传递给`ENTRYPOINT`,之后形成新的命令组合) ### **2、CMD指令只有最后一条生效的原因** CMD指令是一个容器中默认的可执行命令。也就是容器启动以后,默认执行的命令。(默认是重点) 换句话说,给出了CMD指令的一个角色定位,它主要作用是**定义默认的容器启动后执行的命令。** **提示:** **这也就是网上所说,只有最后一条CMD指令会生效,之前的都会被覆盖掉。** **就是因为CMD指令的角色定位就是默认,如果你不进行额外指定,那么就执行CMD指令。否则,你要自己指定了命令,那么就不会执行CMD指令,这也就是相当于CMD指令会被覆盖。** 而`ENTRYPOINT`指令,才是正统地用于定义容器启动以后的执行体,从名字上我们也可以看出,entrypoint 入口点的意思,一个容器的“入口”。 ### **3、CMD指令演示** 我们以ContOS镜像为基础,对该镜像进行修改。 **(1)准备测试环境** 进入宿主机`/home/mydockerfile`目录中,创建Dockerfil文件`Dockerfile_cmd`。 ```python # mydockerfile目录中创建Dockerfile_cmd文件 [root@192 mydockerfile]# pwd /home/mydockerfile [root@192 mydockerfile]# touch Dockerfile_cmd ``` 编辑`Dockerfile_cmd`文件,内容如下: ```python FROM centos # 继承了本地的centos镜像 CMD ["ls","-a"] # 执行ls -a 命令 ``` **说明:我们之前CMD执行都是`/bin/bash`,这回改成`ls -a`命令是一样的,就是启动容器后执行`ls -a`命令。** 根据`Dockerfile_cmd`生成`cmd`镜像。 ```python [root@192 mydockerfile]# docker build -f /home/mydockerfile/Dockerfile_cmd -t wukong/cmd:1.0 . Sending build context to Docker daemon 3.072kB Step 1/2 : FROM centos ---> 300e315adb2f Step 2/2 : CMD ["ls","-a"] ---> Running in e34a0fc14329 Removing intermediate container e34a0fc14329 ---> de211d4ca7f3 Successfully built de211d4ca7f3 Successfully tagged wukong/cmd:1.0 ``` **(2)进行验证** 运行`wukong/cmd`镜像,查看结果。 ```python # 查看本地Docker镜像 [root@192 mydockerfile]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE wukong/cmd 1.0 de211d4ca7f3 2 minutes ago 209MB wokong_centos 1.6 6441f63090d4 3 hours ago 291MB centos latest 300e315adb2f 3 months ago 209MB # 直接运行该容器,查看结果,输出了默认工作目录中的内容。 [root@192 mydockerfile]# docker run wukong/cmd:1.0 . .. .dockerenv bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var # 容器启动,执行完ls -a 命令后,就会停止。 [root@192 mydockerfile]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ``` 接下来,我们在`docker run`命令后,加入`-l`参数,我们再来查看一下结果。 ```python [root@192 mydockerfile]# docker run wukong/cmd:1.0 -l docker: Error response from daemon: OCI runtime create failed: container_linux.go:367: starting container process caused: exec: "-l": executable file not found in $PATH: unknown. ``` **说明:** **我的意思是想追加一个`-l`参数,让容器启动后,执行`ls -al`命令。结果我们看到是,可执行文件找不到的报错,`exec: "-l":executable file not found`。** **这就是我们之前说过的,跟在镜像名后面的是`command`(命令),运行时会替换CMD的默认值。也就是`-l`参数替换了Dockerfile文件中的`CMD ["ls","-a"]`命令,而不是添加在原来的命令里。** **而单独的`-l`参数不是Linux命令,不能单独的命令,自然找不到,所以就报错了。** **所以综上所述,CMD指令会被`docker run`之后的参数替换。** 那么如果我们希望加入`-l`这个参数,就必须重新完整的输入整个命令,如下: ```python [root@192 mydockerfile]# docker run wukong/cmd:1.0 ls -al total 0 drwxr-xr-x. 1 root root 6 Mar 20 11:13 . drwxr-xr-x. 1 root root 6 Mar 20 11:13 .. -rwxr-xr-x. 1 root root 0 Mar 20 11:13 .dockerenv lrwxrwxrwx. 1 root root 7 Nov 3 15:22 bin -> usr/bin drwxr-xr-x. 5 root root 340 Mar 20 11:13 dev drwxr-xr-x. 1 root root 66 Mar 20 11:13 etc drwxr-xr-x. 2 root root 6 Nov 3 15:22 home lrwxrwxrwx. 1 root root 7 Nov 3 15:22 lib -> usr/lib lrwxrwxrwx. 1 root root 9 Nov 3 15:22 lib64 -> usr/lib64 drwx------. 2 root root 6 Dec 4 17:37 lost+found drwxr-xr-x. 2 root root 6 Nov 3 15:22 media drwxr-xr-x. 2 root root 6 Nov 3 15:22 mnt drwxr-xr-x. 2 root root 6 Nov 3 15:22 opt dr-xr-xr-x. 122 root root 0 Mar 20 11:13 proc dr-xr-x---. 2 root root 162 Dec 4 17:37 root drwxr-xr-x. 11 root root 163 Dec 4 17:37 run lrwxrwxrwx. 1 root root 8 Nov 3 15:22 sbin -> usr/sbin drwxr-xr-x. 2 root root 6 Nov 3 15:22 srv dr-xr-xr-x. 13 root root 0 Mar 20 06:42 sys drwxrwxrwt. 7 root root 145 Dec 4 17:37 tmp drwxr-xr-x. 12 root root 144 Dec 4 17:37 usr drwxr-xr-x. 20 root root 262 Dec 4 17:37 var ``` ### **4、ENTRYPOINT指令演示** 和上面CMD指令演示相似。 我们以ContOS镜像为基础,对该镜像进行修改。 **(1)准备测试环境** 进入宿主机`/home/mydockerfile`目录中,创建Dockerfil文件`Dockerfile_entrypoint`。 ```python # mydockerfile目录中创建Dockerfile_entrypoint文件 [root@192 mydockerfile]# pwd /home/mydockerfile [root@192 mydockerfile]# touch Dockerfile_entrypoint ``` 编辑`Dockerfile_entrypoint`文件,内容如下: ```python FROM centos # 继承了本地的centos镜像 ENTRYPOINT ["ls","-a"] # 执行ls -a 命令 ``` 根据`Dockerfile_entrypoint`生成`entrypoint`镜像。 ```python [root@192 mydockerfile]# docker build -f /home/mydockerfile/Dockerfile_entrypoint -t wukong/entrypoint:1.0 . Sending build context to Docker daemon 4.096kB Step 1/2 : FROM centos ---> 300e315adb2f Step 2/2 : ENTRYPOINT ["ls","-a"] ---> Running in ecd4a636d8be Removing intermediate container ecd4a636d8be ---> e641401b4ea5 Successfully built e641401b4ea5 Successfully tagged wukong/entrypoint:1.0 ``` **(2)进行验证** 运行`wukong/entrypoint`镜像,查看结果。 ```python # 查看本地Docker镜像 [root@192 mydockerfile]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE wukong/entrypoint 1.0 e641401b4ea5 2 minutes ago 209MB wukong/cmd 1.0 adda4543a402 3 minutes ago 209MB wokong_centos 1.6 6441f63090d4 4 hours ago 291MB centos latest 300e315adb2f 3 months ago 209MB # 直接运行该容器,查看结果,输出了默认工作目录中的内容。 [root@192 mydockerfile]# docker run wukong/entrypoint:1.0 . .. .dockerenv bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var ``` 接下来,我们在`docker run`命令后,加入`-l`参数,我们再来查看一下结果。 ```python [root@192 mydockerfile]# docker run wukong/entrypoint:1.0 -l total 0 drwxr-xr-x. 1 root root 6 Mar 20 12:03 . drwxr-xr-x. 1 root root 6 Mar 20 12:03 .. -rwxr-xr-x. 1 root root 0 Mar 20 12:03 .dockerenv lrwxrwxrwx. 1 root root 7 Nov 3 15:22 bin -> usr/bin drwxr-xr-x. 5 root root 340 Mar 20 12:03 dev drwxr-xr-x. 1 root root 66 Mar 20 12:03 etc drwxr-xr-x. 2 root root 6 Nov 3 15:22 home lrwxrwxrwx. 1 root root 7 Nov 3 15:22 lib -> usr/lib lrwxrwxrwx. 1 root root 9 Nov 3 15:22 lib64 -> usr/lib64 drwx------. 2 root root 6 Dec 4 17:37 lost+found drwxr-xr-x. 2 root root 6 Nov 3 15:22 media drwxr-xr-x. 2 root root 6 Nov 3 15:22 mnt drwxr-xr-x. 2 root root 6 Nov 3 15:22 opt dr-xr-xr-x. 124 root root 0 Mar 20 12:03 proc dr-xr-x---. 2 root root 162 Dec 4 17:37 root drwxr-xr-x. 11 root root 163 Dec 4 17:37 run lrwxrwxrwx. 1 root root 8 Nov 3 15:22 sbin -> usr/sbin drwxr-xr-x. 2 root root 6 Nov 3 15:22 srv dr-xr-xr-x. 13 root root 0 Mar 20 06:42 sys drwxrwxrwt. 7 root root 145 Dec 4 17:37 tmp drwxr-xr-x. 12 root root 144 Dec 4 17:37 usr drwxr-xr-x. 20 root root 262 Dec 4 17:37 var ``` **说明:想给`Dockerfile`文件中的`ENTRYPOINT ["ls","-a"]`命令追加一个`-l`参数,让容器启动后执行`ls -al`命令,结果顺利执行。** **结论:这就说明了,`ENTRYPOINT`指令是可以在容器启动的时候追加命令。** ### **5、总结** - CMD:CMD设置容器启动后默认执行的命令及其参数。但CMD设置的指令,能够被docker run命令后面的命令行参数替换(也就是可被重写覆盖)。 - ENTRYPOINT,表示镜像在初始化时需要执行的命令。不会被忽略,一定会被执行,即使运行docker run命令时指定了其他命令(也就是可被重写覆盖)。 - CMD和ENTRYPOINT都只能在文件中存在一次。如果多个存在,只有最后一个生效,其它无效! - 对于 CMD 和 ENTRYPOINT 的设计而言,多数情况下它们应该是单独使用的。当然,有一个例外是 CMD 为 ENTRYPOINT 提供默认的可选参数。 **说明:** **对于 `Dockerfile` 来说,`CMD `和 `ENTRYPOINT` 是非常重要的指令。它们不是在构建镜像的过程中执行,而是在启动容器时执行,所以主要用来指定容器默认执行的命令。** **Dockerfile中很多命令的功能都十分的相似,我们需要了解它们的区别,我们最好的学习就是对比他们,然后测试效果。** **以上就是`CMD`指令和`ENTRYPOINT`指令的区别。**
李智
2025年3月17日 13:22
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
分享
链接
类型
密码
更新密码