前面有说到这两个指令的区别:
CMD:
DockerFile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换
ENTRYPOINT:ENTRYPOINT的目的和CMD一样,都是在指定容器启动程序及参数,但是不会被覆盖,而是被追加
以下案例作为验证如上区别:
分别制作CMD的查询ip容器和ENTRYPOINT的查询ip容器。
CMD案例
FROM centos:7RUN yum install -y curlCMD curl -s https://www.ip.cn/
[linguo@VM-4-6-centos dockerFile]$ docker build -f dockerfile_ip1 -t cmdip [linguo@VM-4-6-centos dockerFile]$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE cmdip latest c4b147baa8fb 6 seconds ago 370MB [linguo@VM-4-6-centos dockerFile]$ docker run cmdip <!DOCTYPE html> <html lang="en" xmlns:v-touch="http://www.w3.org/1999/xhtml"> ... </html> [linguo@VM-4-6-centos dockerFile]$ docker run cmdip -i docker: Error response from daemon: failed to create shim: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "-i": executable file not found in $PATH: unknown. ERRO[0000] error waiting for container: context canceled在这个例子中如果想在”curl -s https://www.ip.cn/“追加参数-i打印请求报文是无法实现的,因为CMD命令会被docker run 后面的命令给覆盖,如果需要CMD则指令必须完整。”docker run cmdip curl -s -i https://www.ip.cn/“
ENTRYPOINT案例
FROM centos:7 RUN yum install -y curl ENTRYPOINT ["curl","-s","https://www.ip.cn/"]```shell [linguo@VM-4-6-centos dockerFile]$ docker build -f dockerfile_ip2 -t entrypointip . [linguo@VM-4-6-centos dockerFile]$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE entrypointip latest 90ce4dda7639 6 seconds ago 370MB cmdip latest c4b147baa8fb 10 minutes ago 370MB [linguo@VM-4-6-centos dockerFile]$ docker run entrypointip <!DOCTYPE html> … [linguo@VM-4-6-centos dockerFile]$ docker run entrypointip -i HTTP/1.1 200 OK Date: Sun, 17 Apr 2022 13:57:53 GMT Content-Type: text/html;charset=UTF-8 Transfer-Encoding: chunked Connection: keep-alive Content-Language: en-US Cache-Control: max-age=1800 CF-Cache-Status: HIT Age: 3075 Last-Modified: Sun, 17 Apr 2022 13:06:38 GMT Expect-CT: max-age=604800, report-uri=”https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct“ Report-To: {“endpoints”:[{“url”:”https:\/\/a.nel.cloudflare.com\/report\/v3?s=4gM8xOkdO%2F%2BZu%2BJ5aXTPDej2MDyAg34lVgQ5d9M4DzDfYtDds9ZXATPbbDW5qwp1MkMpZ1RWwndgEZOgQsxjIwDygDKjSkRhZv9rmHzs6yer38IejDjl67Np6H0%3D”}],”group”:”cf-nel”,”max_age”:604800} NEL: {“success_fraction”:0,”report_to”:”cf-nel”,”max_age”:604800} Server: cloudflare CF-RAY: 6fd5ac2359db7e4c-LAX alt-svc: h3=”:443”; ma=86400, h3-29=”:443”; ma=86400
<!DOCTYPE html>
…看到-i是直接被追加到ENTRYPOINT指令的参数中的,没有像之前使用CMD那样报错,并成功打印了请求的报文。
3. CMD和ENTRYPOINT结合使用
```shell
FROM centos:7
RUN yum install -y curl
ENTRYPOINT ["curl","-s","https://www.ip.cn/"]
CMD ["-i"]
使用CMD将-i参数传递这样也是可以的
针对以上的区别作如下补充:
- 如果 ENTRYPOINT 使用了 shell 模式,CMD 指令会被忽略。
- 如果 ENTRYPOINT 使用了 exec 模式,CMD 指定的内容被追加为 ENTRYPOINT 指定命令的参数。
- 如果 ENTRYPOINT 使用了 exec 模式,CMD 也应该使用 exec 模式。
所以上面说ENTRYPOINT指令被追加这句话也不是一定的,要看编写DockerFile时使用的写法。
另外,ENTRYPOINT也是可以覆盖的,使用”—entrypoint” 显式指定,且定义了多个ENTRYPOINT时也是只有最后一个生效
[linguo@VM-4-6-centos dockerFile]$ docker run --entrypoint date entrypointip
Sun Apr 17 14:31:51 UTC 2022
