『现学现忘』Docker基础 — 36、CMD指令和ENTRYPOINT指令的区别
CMD指令和ENTRYPOINT指令作用都是指定一个容器启动时要运行的命令。
1、CMD指令和ENTRYPOINT指令说明
CMD指令, 支持三种格式:
CMD ["executable","param1","param2"] :使用 exec 执行,推荐方式;
CMD command param1 param2 :在 /bin/sh 中执行,提供给需要交互的应用;
CMD ["param1","param2"] :提供给 ENTRYPOINT 的默认参数;
每个Dockerfile只能生效一条CMD指令。如果指定了多条CMD指令,只有最后一条生效。
如果用户启动容器时候指定了运行的命令,则会覆盖掉CMD指定的命令。
ENTRYPOINT指令,支持两种格式:
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。
# mydockerfile目录中创建Dockerfile_cmd文件
[root@192 mydockerfile]# pwd
/home/mydockerfile
[root@192 mydockerfile]# touch Dockerfile_cmd
编辑Dockerfile_cmd文件,内容如下:
FROM centos # 继承了本地的centos镜像
CMD ["ls","-a"] # 执行ls -a 命令
说明:我们之前CMD执行都是
/bin/bash,这回改成ls -a命令是一样的,就是启动容器后执行ls -a命令。
根据Dockerfile_cmd生成cmd镜像。
[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镜像,查看结果。
# 查看本地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命令,我们再来查看一下结果。
[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这个参数,就必须重新完整的输入整个命令,如下:
[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。
# mydockerfile目录中创建Dockerfile_entrypoint文件
[root@192 mydockerfile]# pwd
/home/mydockerfile
[root@192 mydockerfile]# touch Dockerfile_entrypoint
编辑Dockerfile_entrypoint文件,内容如下:
FROM centos # 继承了本地的centos镜像
ENTRYPOINT ["ls","-a"] # 执行ls -a 命令
根据Dockerfile_entrypoint生成entrypoint镜像。
[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镜像,查看结果。
# 查看本地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命令,我们再来查看一下结果。
[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指令的区别。
『现学现忘』Docker基础 — 36、CMD指令和ENTRYPOINT指令的区别的更多相关文章
- 『现学现忘』Docker基础 — 16、Docker中的基本概念和底层原理
		目录 1.Docker的底层原理 2.Docker中常用的基本概念 3.run命令的运行流程 4.为什么Docker比VM快 Docker架构图: 我们依照Docker架构图进行Docker基础概念的 ... 
- 『现学现忘』Docker基础 — 38、COPY指令和ADD指令
		目录 1.COPY指令 (1)COPY指令说明 (2)COPY指令格式 (3)COPY指令使用 (4)其他 2.ADD指令 (1)ADD指令说明 (2)ADD指令格式 (3)ADD指令使用 (4)不推 ... 
- 『现学现忘』Docker基础 — 9、Docker简介
		目录 1.什么是Docker? 2.Docker的出现解决了什么问题? 3.Docker的特别之处 4.Docker相关网站 1.什么是Docker? 2010年dotCloud公司在旧金山成立,PA ... 
- 『现学现忘』Docker基础 — 25、Docker镜像讲解
		目录 1.镜像是什么 2.Docker镜像获取的方式 3.Docker镜像加载原理 (1)UnionFS(联合文件系统) (2)Docker镜像加载原理 1.镜像是什么 镜像是一种轻量级.可执行的独立 ... 
- 『现学现忘』Docker基础 — 26、Docker镜像分层的理解
		目录 1.分层的镜像 2.加深理解 3.特别说明 1.分层的镜像 我们可以去下载一个镜像,注意观察下载的日志输出,可以看到Docker的镜像是一层一层的在下载. 思考:为什么Docker镜像要采用这种 ... 
- 『现学现忘』Docker基础 — 27、Docker镜像的commit操作
		目录 1.commit命令作用 2.commit命令说明 3.示例演示 1.commit命令作用 在运行的容器中,并在镜像的基础上做了一些修改,我们希望保存起来,封装成一个新的镜像,方便我们以后使用, ... 
- 『现学现忘』Docker基础 — 28、Docker容器数据卷介绍
		目录 1.什么是Docker容器数据卷 2.数据卷的作用 3.数据卷的使用 1.什么是Docker容器数据卷 Docker容器数据卷,即Docker Volume(卷). 当Docker容器运行的时候 ... 
- 『现学现忘』Docker基础 — 32、通过DockerFile的方式挂载数据卷
		目录 1.简单了解一下DockerFile 2.通过DockerFile的方式挂载数据卷 (1)创建DockerFile文件 (2)编辑Dockerfile文件 (3)构建Dokcer镜像 (4)启动 ... 
- 『现学现忘』Docker基础 — 34、DockerFile文件详解
		目录 1.DockerFile文件说明 2.Dockerfile构建过程解析 (1)Docker容器构建三步骤 (2)Dockerfile文件的基本结构 (3)Dockerfile注意事项 (4)Do ... 
随机推荐
- C#早期绑定&后期绑定
			早期绑定(early binding),又可以称为静态绑定(static binding).在使用某个程序集前,已知该程序集里封装的方法.属性等.则创建该类的实例后可以直接调用类中封装的方法. 后期绑 ... 
- Java递归与基础复习
			Day01-基础复习,递归 1.递归 定义:指在当前方法内调用自己,即函数内部调用本函数 分类: 直接递归和间接递归 直接递归成为方法自身调用自己 间接递归可以A方法调用B方法,B方法调用C方法,C方 ... 
- Java 类方法和类变量
			目录 一.类变量 1.如果定义类变量 2.如何访问类变量 3.类变量的使用注意事项和细节 二.类方法 1.类方法的形式 2.类方法的调用 3.类方法经典使用场景 4.类变量和类方法 三.main方法 ... 
- Mattermost Server安装及配置AD/LADP
			一.安装Mattermost Server Mattermost is an open source, self-hosted Slack-alternative. 1.下载mattermost s ... 
- 『德不孤』Pytest框架 — 9、Pytest测试报告
			目录 1.pytest-html插件 2.Allure测试报告 (1)Allure框架说明 (2)Allure框架的使用 1.pytest-html插件 Pytest可以通过命令行方式,生成xml/h ... 
- MariaDB 与Mysql版本对应关系
			特定MariaDB版本的完全兼容性 就InnoDB而言,MariaDB 10.2.MariaDB 10.3和MariaDB 10.4是MySQL 5.7的有限替代.然而,在每一个新的MariaDB版本 ... 
- SQL从零到迅速精通【实用函数(3)】
			1.LOWER()函数 使用LOWER函数将字符串中所有字幕字符转换为小写,输入语句如下. SELECT LOWER('BEAUTIFUL'),LOWER('Well'); 2.UPPER()函数 S ... 
- laravel7 实现阿里云大文件上传
			1:新创一个桶名 2:下载SDK 3: 4: php编辑器 终端运行 5:阿里云复制代码 6:获取秘钥和毽 7: 控制器书写代码:切记引入oss namespac App\Http\Controlle ... 
- Java安装与卸载
			Java安装与卸载 Java优势 面向对象 可移植性,跨平台易用 高性能 为分布式设计 具有动态性 支持多线程 安全性 健壮性,运行前会对内存进行检查 Java三大版本 JavaSE:标准版 Java ... 
- Spring系列26:Spring AOP 通知与顺序详解
			本文内容 如何声明通知 如何传递参数到通知方法中 多种通知多个切面的通知顺序 多个切面通知的顺序源码分析与图解 声明通知 Spring中有5种通知,通过对应的注解来声明: @BeforeBefore ... 
