017、RUN、CMD、ENTRYPOINT (2019-01-08 周二)

 
RUN CMD ENTRYPOINT 这三个Dockerfile指令看上去很类似,很容易混淆。
 
简单的说:
 
    RUN 执行命令并创建新的镜像层,经常用于安装软件
    CMD 设置容器启动后默认执行的命令机器参数,但CMD能够被 docker run 后面跟的命令行参数替换
    ENTRYPOINT 配置容器启动时运行的命令
 
shell 和exex 格式
 
有shell和exec两种方式可以指定 RUN CMD ENTRYPOINT 要运行的命令,两者在使用上有细微的区别
 
shell 格式:
<instruction> <command>
 
例如:
 
RUN apt-get install -y python3
CMD echo "Hello world"
ENTRYPOINT echo "Hello world"
 
当指令执行时,shell格式底层会调用 /bin/sh -c <command>
 
root@docker-lab:~/017# cat Dockerfile
FROM busybox
ENV name www1707
ENTRYPOINT echo "Hello $name"
root@docker-lab:~/017# docker build -t test017 .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM busybox
---> 3a093384ac30
Step 2/3 : ENV name www1707
---> Running in e43df73f1151
Removing intermediate container e43df73f1151
---> 973f9b8b29b7
Step 3/3 : ENTRYPOINT echo "Hello $name"
---> Running in 5efc3b5b3053
Removing intermediate container 5efc3b5b3053
---> c9321b834dbb
Successfully built c9321b834dbb
Successfully tagged test017:latest
root@docker-lab:~/017# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
test017             latest              c9321b834dbb        6 seconds ago       1.2MB
myimage             latest              c67728621bdd        33 hours ago        1.2MB
busybox             latest              3a093384ac30        7 days ago          1.2MB
root@docker-lab:~/017# docker run test017
Hello www1707
 
exec格式:
<instruction> ["executable","param1","param2",...]
 
例如:
 
RUN ["apt-get","install","python3"]
CMD ["/bin/echo","Hello world"]
ENTRYPOINT ["/bin/echo","Hello world"]
 
当指令执行时,会直接调用command,不会被shell解析
 
root@docker-lab:~/017# cat Dockerfile
FROM busybox
ENV name www1707
ENTRYPOINT ["/bin/echo","Hello,$name"]
root@docker-lab:~/017# docker build -t test-017 .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM busybox
---> 3a093384ac30
Step 2/3 : ENV name www1707
---> Running in 6a2a8dcbd2ab
Removing intermediate container 6a2a8dcbd2ab
---> 026f3f3c154e
Step 3/3 : ENTRYPOINT ["/bin/echo","Hello,$name"]
---> Running in 92c90db5bbc3
Removing intermediate container 92c90db5bbc3
---> 1f01346313b5
Successfully built 1f01346313b5
Successfully tagged test-017:latest
root@docker-lab:~/017# docker run test-017
Hello,$name
 
 
root@docker-lab:~/017# cat Dockerfile
FROM busybox
ENV name www1707
ENTRYPOINT ["/bin/sh","-c","echo Hello,$name"]
root@docker-lab:~/017# docker build -t test-017 .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM busybox
---> 3a093384ac30
Step 2/3 : ENV name www1707
---> Using cache
---> 026f3f3c154e
Step 3/3 : ENTRYPOINT ["/bin/sh","-c","echo Hello,$name"]
---> Running in 459792a5b117
Removing intermediate container 459792a5b117
---> d163360f72c5
Successfully built d163360f72c5
Successfully tagged test-017:latest
root@docker-lab:~/017# docker run test-017
Hello,www1707
 
 
CMD 和 ENTYRPOINT 推荐使用exec格式,因为指令的可读性更强,更容易理解。
 
RUN
 
    RUN 使用两种格式都可以,但是RUN一般用来安装应用和软件包,推荐shell格式
    RUN apt-get update && apt-get install -y vim wget 
    先执行update 保证后面安装的软件版本是最新的,要不然会可能会安装一个早期的版本或者直接安装失败
 
CMD
 
    CMD支持三种格式
 
    1、exec格式  CMD ["executable","param1","param2"]
        这是CMD推荐的格式
    2、CMD ["param1","param2"] 
        这是为ENTRYPOINT  提供额外参数时的格式,此时 ENTRYPOINT 必须是exec格式
    3、CMD command param1 param2
        这是shell格式
 
    第二种格式 CMD ["param1","param2"] 要与 exec格式的 ENTRYPOINT 指令配合使用,其用户是为ENTRYPOINT设置默认参数。
 
    当docker run 后面有参数时,CMD指令将会被忽略
 
root@docker-lab:~/017# cat Dockerfile
FROM busybox
CMD echo "Hello world"
root@docker-lab:~/017# docker build -t test-017 .
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM busybox
---> 3a093384ac30
Step 2/2 : CMD echo "Hello world"
---> Running in 15bd85e76424
Removing intermediate container 15bd85e76424
---> 13e99c60b00d
Successfully built 13e99c60b00d
Successfully tagged test-017:latest
root@docker-lab:~/017# docker run test-017
Hello world
root@docker-lab:~/017# docker run -it test-017
Hello world
root@docker-lab:~/017# docker run -it test-017 /bin/sh
/ #
/ # exit
root@docker-lab:~/017#
 
 
ENTRYPOINT
 
    该指令可以让容器以应用程序或者服务运行。ENTYRPOINT和CMD看上去很像,他们都可以指定要执行的命令及参数。但是ENTYRPOINT不会被忽略,一定会被执行,即使docker run 后面指定了其他命令。
 
    exec格式--推荐格式
        ENTYRPOINT ["executable","param1","param2"]
 
root@docker-lab:~/017# cat Dockerfile
FROM busybox
ENTRYPOINT ["/bin/echo","Hello"]
CMD ["world"]
root@docker-lab:~/017# docker build -t test-017 .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM busybox
---> 3a093384ac30
Step 2/3 : ENTRYPOINT ["/bin/echo","Hello"]
---> Running in 5fca55e81dd9
Removing intermediate container 5fca55e81dd9
---> 60978b547d5d
Step 3/3 : CMD ["world"]
---> Running in b1f9da2b8ecf
Removing intermediate container b1f9da2b8ecf
---> 1957f19e2cb7
Successfully built 1957f19e2cb7
Successfully tagged test-017:latest
root@docker-lab:~/017# docker run test-017
Hello world
root@docker-lab:~/017# docker run -it test-017 www1707
Hello www1707
 
 
    shell格式--该格式会忽略掉CMD和docker run 后面的参数
        ENTRYPOINT command param1 param2
 
root@docker-lab:~/017# cat Dockerfile
FROM busybox
ENTRYPOINT echo hello
CMD ["world"]
root@docker-lab:~/017# docker build -t test-017 .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM busybox
---> 3a093384ac30
Step 2/3 : ENTRYPOINT echo hello
---> Running in 683c7c95a0bb
Removing intermediate container 683c7c95a0bb
---> 4b76c9e22319
Step 3/3 : CMD ["world"]
---> Running in 3464e96183d6
Removing intermediate container 3464e96183d6
---> d636aed0e6b4
Successfully built d636aed0e6b4
Successfully tagged test-017:latest
root@docker-lab:~/017# docker run test-017
hello
root@docker-lab:~/017# docker run -it test-017 www1707
hello
 
 
 
 
最佳实践
 
1、RUN 指定用来安装应用和软件包
2、ENTRYPOINT用来运行应用或者服务,可以用CMD提供额外的参数,还可以用docker run提供参数或者是替换掉CMD提供的参数
3、CMD可以为容器设置默认的启动命令,也可以用docker run替换掉
 
 
posted @ 2019-01-10 00:19  三角形  阅读(310)  评论(0编辑  收藏  举报