开发者学堂课程【Docker 快速入门:Docker file 案例-CMD-ENTRYPOINT 命令案例】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/616/detail/9409
Docker file 案例-CMD-ENTRYPOINT 命令案例
内容介绍:
一、CMD 和 ENTRYPOIN 的相同点
二、CMD
三、ENTRYPOINT
一. CMD 和 ENTRYPOIN 的相同点
接下来看第二个案例,通过上一个案例相信以下的:FROM MAINTAINER RUN EXPOSE WORKDIR ENV CMD 这些差不多都了解了。
输入 docker ps 显示以下内容,Command 就是这个意思,如图所示:
那么接下来看看 command 和 ENTRYPOINT 这两个有什么区别?它们都是指定一个容器启动时要运行的命令。
二.CMD
那么先来看 Command。dockerfile 中可以有多个 cmd 指令,但只有最后一个生效,换句话说,只有 cmd/bin/bash 生效,谁在最后谁生效,但是这个 cmd 会被docker run 之后的参数替换。
如下代码所示:
CMD.echo.$MYPATH
CMD.echo ‘’success-------ok’’
CMD/bin/bash
那么接下来用 tomcat 来进行说明和讲解。现在去 DockerHub 官网上搜索tomcat,是没有任何问题的,随便找到一个 tomcat 的 dockerfile,可以看到Run time 执行一个 linux 命令。代码如下所示:
RUN mkdir-p $CATALINA HOME’’
tomcat 之所以启动它默认的,是因为 command 是有这么一行代码:CMD{‘’catalina.sh’’,’’run’’}
,那么这句话是什么意思呢?是在它文件dockerfile 里面是最后,所以一运行 tomcat 时,它就自动的启动起来了。但是怎么运行 tomcat?输入 docker Images tomcat
,显示出来以下内容:
接着在下面输入 docker run -it -p 7777:8080 tomcat
,现在就去运行,后台就显示各种日志。如下图:
然后再去点火狐浏览器就能访问到 tomcat,那么再按 ctrl c 退出。以下为重点,输入 docker images tomcat
,之所以能运行 tomcat 刚才那个命令,这个没有任何问题,换条代码一运行这个命令,它最后一行是执行这个:CMD{‘’catalina.sh’’,’’run’’}
,所以说 tomcat 才能成功的启动。
假设,命令还是个命令什么都没变,而这时比方 ls 一下,在后面加一个 ls-l,完整命令为:docker run-it-p 8888:8080 tomcat ls-l
。那么这个命令是什么意思呢?相当于在 tomcat 后面,比方现在这是默认没有修改的,要是没有加 ls-l,就执行 CMD{‘’catalina.sh’’,’’run’’}
这行,要是加了 ls-l,相当于在后面既可以是 jersen 处理,也可以是 ls-l。那么又执行了 CMD ls-l 这么一行。
根据 cmd 最后一行起效,相当于 CMD ls-l 这一行就会把上面CMD{‘’catalina.sh’’,’’run’’}
这一行覆盖。那么是否依照主人要求,打出 ls-l 呢?那这些内容是什么?就是它默认登录到的 CATALINA_HOME,也就是默认登录到 usr/local/tomcat 下面,相当于这个写的命令:Is-1 usr/local/tomcat
登录了以后,做了这样一件事情。
只有 tomcat 下面才会有这些,比如 webapps bin config 。输入 dockers ps,tomcat 有没有启动起来?根本没有。你要启动起来,先看这个镜像 image 就是mycentos1.3,这是上一个案例做的内容,如果启动以后这里最起码应该看到一个端口映射 7777:8080
所以现在这个 tomcat ls-l 这个命令就把
CMD{‘’catalina.sh’’,’’run’’}
这个命令给覆盖了。
相当于 tomcat 根本就没有启动。那么这个就是所说的 cmd 会被 docker run 之后的参数替换。
三.ENTRYPOINT
那么 entry point 它的功能比 cmd 更厉害一些,它不会被替换,它会被追加,也就是更加的强大。那么这时不妨来看这么一个命令或者说这么一个案例,docker run 之后的参数会被当做参数传递给 entry point,之后形成新的命令组合。
来看第一个,制作 cmd 版可以查询 ip 信息的容器。Curl 这个命令是什么意思呢?直接输入 curl http://www.baidu.com,显示以下内容:
它会返回这个网址的 form 表单,它是一个 http 的下载命令,接着就做一个简单的命令,输入cd mydocker pwd ll
,可以看到现在有两个 docker file,再输入vimdocker file
,那么这个命令就是做一个最简单的 form centos。
假设 centos,可能有些的 centos 是 6.5 6.6 7.8 没有这个 curl 命令,取一个run,cmd,这次就不再是 linux 下脚本的方式,用 Curl-S 打出 Ip.cn。
可能会疑惑,这个网址访问过吗?这是一个查ip的,可以查出你当前 IP 地址,比方现在在网络上电信上的这个 ip 为:124.282.216.138,上网就是用这个 ip 上的,它就是一个查 ip 的。那么待会就要返回到底是联通的电信的还是移动的网络,这个很简单就查这么一个网址,查出这个网址的结果。
下面来输入 WQ,回车,输入 curl ,了解这个之后就不再多说了,如果有兴趣的同学可以看一眼。接下来读一下这一段话。
可以看到执行后,www.baidu.com 的 html就会显示再屏幕上,那么都是 java 程序出生,之所以能看到百度这个页面,是因为它是用 html 编的。如果说在这执行curl http:// www.baidu.com 可以看到地图,更多产品,这个就相当于是百度的,所看到的 html 这个页面。
那么要拿它来干什么呢?现在这个 dockerfile3 是 3,做一个可以查 ip 的功能。这是 dockerfile3:
FROM centos
RUN yum insta11-y curl
CMD{‘’curl’’,-s,http://ip.cn’’}
这个 FROM centos 不再解释,CMD{‘’curl’’,-s,http://ip.cn’’}
就是刚才执行代码,只不过现在换成百度。现在写进 dockerfile 里面的就是http://ip.cn’’,就是怕本机没有这个 curl 这个命令,写一个就安装一个,要是有就使用,没有也是无所谓的,这就是最简单的一个操作。
接着可以看到 docker build -f dockerfile4-t myip 这个内容,那么输入docker build -f/mydocker/dockerfile3-t myip my ip
后就不加标签 1.1了。这是最新版,再按回车。显示以下内容:
内容显示有 from centos,第一步就是 Run yum insta11-y curl,安装 Curl 命令之后,它检测到已经有 already installed 并且已经安装过了,packagecurl-7.29.0-46.el7.x86_64 already installed and latest version
,是有过这个代码,但是如果没有,也可以用 Run yum install-y curl 这个安装,两者不冲突。
那么 ea174000d4a8 已经成功 build 的这行代码了,输入 docker Images myip
,显示的内容中有没有呢?标签版本是最新版本 261.7mb。
如图所示:
接下来第三步,来跑这个容器。输入 docker run -it-myip,再按回车,出现以下内容:
当前 ip 是:218.241.251.153,来自北京鹏博士,这是 Linux 连上的 Ip,这个当然是它反馈什么内容就是什么内容,最重要的不是这个。重要不是来研究查 IP 的,来讲的是 Cmd 和 entry point。
现在 CMD{‘’curl’’,-s,http://ip.cn’’}
这里就有 cmd,那么问题是如果我们希望还要显示 http 头信息,就需要加上一个 -i 参数。如果刚才输入的代码 docker run -it-myip
这里需要加一个参数 i,什么叫加一个参数 i 呢?
输入 curl,假设这个 ip 是http://ip.cn’’,那么出现的是还是刚才的内容:
Curl-s http://ip.cn’’当前 IP:218.241.251.153,来自:北京市 鹏博士
那么假设它是 http 的下载工具,刚才把表单返回过也解释了,如果参数不够,那么再输入curl-s-i http://ip.cn’,而这个 Curl-s http://ip.cn’’当前 IP:218.241.251.153,来自:北京市 鹏博士,是查 ip 的,但是还想看全部内容,要想看全部内容,就要加一个参数i,那么功能就要扩张了。
假设现在功能扩张以后以以下这种方式写:
dockerfile3:
FROM centos
RUN yum insta11-y curl
CMD{‘’curl’’,-s,http://ip.cn’’}
这种方式所写的 dockerfile3 还够用吗?不妨再来看一眼。回到这个页面,-it 因为没有它什么交互的,所以加不加都可以,输入 docker run myip
,可以看到现在直接返回了 ip。但是要再加上返回的这个内容,如下图:
输入 docker run myip-i
返回之后,就不好使用了。
这时出现 system error 报错了,为什么呢?看如下图:
之前介绍过 Run 后面如果只运行 ip,那么相当于就是运行 CMD{‘’curl’’,-s,http://ip.cn’’}
这个命令,但是再加一个 i,那么相当于说在CMD{‘’curl’’,-s,http://ip.cn’’}
这个命令的基础上,又加了一个 -I,如果要用 cmd 编写,那么上面这行命令就被覆盖了。
因为现在是希望这个 i,添加到这里作为一个公用的参数,共同的参数继续增加它的功能,而不是覆盖。
所以现在用 cmd 不好用,除非要用成 docker run myip curl -s http://ip.cn-i 这样,那运行 docker run myip 这个容器,又做 curl -s http://ip.cn-i 这件事情,还写这个 docker file 干什么?所以某种情况下,最后 run 后面避免不了要加一个参数,一加参数就会把原来的功能替换掉。
所以现在制作 entry point 版本的 ip 查询信息的容器。那么这时候干什么呢?现在是 dockerfile3, Copy dockerfile3 变成 dockerfile4,那么再输入vim dockerfile4,可以原来这里是 cmd, 将它变成 entry point。
接着输入 docker build -f /mydocker/ dockerfile4-t myip2,
按回车,显示以下内容:
可以看见此时用的是 entry point,不再是 cmd。 输入 docker run-myip,原来的版本只能查 ip,因为原来的版本 ip 是 cmd 版的,那么如果想查 http 的全部内容,还要让它的功能再进一步变得复杂,如果加上一个参数 i,命令就会报错system error,因为 i 执行这个 file not found,根本就没这个命令。
前面讲过这个 i 放到最后,因为 run 一执行就会在后面加个 cmd-i,那么就把CMD{‘’curl’’,’’-s’’,http://ip.cn’’}
给覆盖,它只剩最后一个所以这个命令报错。
此时如果用的是 docker run Ip2,可能会觉得不对,这还是查出来只有 ip,没有全部内容,要注意的是,Cmd 加 i,i 把它覆盖,但是如果用 entry point 加 i,相当于在CMD{‘’curl’’,’’-s’’,http://ip.cn’’
这个命令这里,加了一个 i,变成CMD{‘’curl’’,’’-s’’ -I {,http://ip.cn’’}
,那么这个功能参数就又变强大了。
如下图可以看到不但没有被覆盖,还被正确的执行。
加了这个 i,相当于原有的没有被破坏,新有的功能怎么加参数都可以。
打出来 http 全部内容,打出当前 ip 的返回地址,那么 entry point 就没有被覆盖,而是参数追加到原有命令后面,进一步做了 i++ 类似于这样的操作,加深并且加复杂了命令行参数内容,它的功能要比 cmd 相对而言强大一些。
这个就是 cmd 和 entry point 的镜像案例。简单来说,相同点都是指定一个容器启动的时候要运行的命令,不同点是 cmd 这会被覆盖,entry point 会被追加组合继续使用。这两个的细节一定要掌握。