前面有说到这两个指令的区别:
    CMD:
    DockerFile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换
    ENTRYPOINT:
    ENTRYPOINT的目的和CMD一样,都是在指定容器启动程序及参数,但是不会被覆盖,而是被追加

    以下案例作为验证如上区别:
    分别制作CMD的查询ip容器和ENTRYPOINT的查询ip容器。

    1. CMD案例

      1. FROM centos:7
      2. RUN yum install -y curl
      3. CMD 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/

    2. 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