对于CMD,一个Dockerfile只有最后一个有效,默认情况下在容器运行下是运行CMD指定的程序,如果需要覆盖,则在docker run 后指定需要运行的程序。
若想利用CMD命令做一些参数传递时,CMD命令并不很好用,此时可以利用ENTRYPOIT,ENTRYPOINT后可以跟CMD一样的命令,默认启动容器的情况下,和CMD产生的效果是一样的,但ENTRYPOIT具备参数传递功能
简要例子:
- 建立Dockerfile文件如下
FROM busybox
CMD ["ifconfig"]
- 这是个简单的dockerfile,当生成镜像启动容器时,容器仅显示下其网卡地址
docker build -t t1 .
docker run -it --rm t1
eth0 Link encap:Ethernet HWaddr 02:42:C0:A8:50:02
inet addr:192.168.80.2 Bcast:192.168.80.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:3 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:310 (310.0 B) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
-
如果想容器只查看eth0的信息只能用docker run -it --rm t1 ifconfig eth0命令,即需人为覆盖CMD命令,若使用docker run -it --rm eth0 是不行的
-
如果Dockerfile内不是CMD命令,而是ENTRYPOINT,则可以传递参数,具体如下:
修改Dockerfile:
FROM busybox
ENTRYPOINT ["ifconfig"]
- 重新构建镜像和容器
docker build -t t2 .
docker run --rm t2
eth0 Link encap:Ethernet HWaddr 02:42:C0:A8:50:02
inet addr:192.168.80.2 Bcast:192.168.80.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:2 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:200 (200.0 B) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
- 带参数:
docker run -it --rm t2 eth0
eth0 Link encap:Ethernet HWaddr 02:42:C0:A8:50:02
inet addr:192.168.80.2 Bcast:192.168.80.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:3 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:290 (290.0 B) TX bytes:0 (0.0 B)
由此可知,ENTRYPOINT可以传递参数,其重要特性是CMD命令是可以覆盖的,而ENTRYPOINT是不能覆盖的,在一些场合中,可以把固定的命令或脚本放置ENTRYPOINT内,而默认的参数放置CMD内,在运行容器时,默认启动使用CMD内参数,需改变参数时,只需在运行时重新指定参数覆盖CMD,而不需要重新指定整个命令,这对于一些特别长或者复杂命令脚本中尤为有效。