在 Dockerfile 中, CMD 和 ENTRYPOINT 的区别是什么?
Docker 有一个默认的入口(entrypoint), 它是/bin/sh -c
, 但没有默认命令。
当您运行这样的 Docker 时: docker run -i t ubuntu bash
入口是默认/bin/sh -c
, 镜像是 ubuntu, 命令是 bash。
该命令通过入口运行。也就是说, 被执行的实际的事情是/bin/sh -c bash
。这允许 Docker 通过依赖 shell 分析器实现快速RUN。后来, 人们要求能够定制这样的入口于是引入了-entrypoint
。
以上示例中的 ubuntu 后面的所有内容都是命令, 并传递给入口。当使用 CMD 指令时, 它就像是在做 docker run --t ubuntu <cmd>
。<cmd>
将是入口的参数。
如果改为键入此命令docker run -i -t ubuntu
, 则也会得到相同的结果。您仍将在容器中启动 bash shell, 因为 ubuntu Dockerfile 指定了默认 CMD: CMD ["bash"]
当一切都传递给入口, 便对镜像来说产生一个很好的特性。可以将镜像用作 "二进制"的执行文件。当使用 ["/bin/cat"]
作为入口, 然后运行 docker run img /etc/passwd
, 这里,/etc/passwd
是命令, 并传递到入口,所以最终结果执行便是/bin/cat /etc/passwd
。
另一个例子是将任何命令行指令(cli)作为入口。例如, 如果您有一个 redis 镜像, 你可以简单地通过设置ENTRYPOINT ["redis", "-H", "something", "-u", "toto"]
,然后运行docker run redisimg get key
得到键值, 而不是通过运行 docker run redisimg redis -H something -u toto get key
,来得到相同的结果。
ENTRYPOINT 指定在容器启动时将始终执行的命令。
CMD 指定将被送入 ENTRYPOINT 的参数。
如果要使镜像专用于特定命令, 您将使用入口 ENTRYPOINT ["/path/dedicated_command"]
否则, 如果要为一般目的制作镜像, 则可以保留未指定的 ENTRYPOINT 并使用 CMD ["/path/dedicated_command"]
, 因为你可以通过向docker run
提供参数来覆盖该设置。
例如, 如果您的 Dockerfile 是:
FROM debian:wheezy ENTRYPOINT ["/bin/ping"] CMD ["localhost"]
运行不带参数的镜像会 ping localhost
:
$ docker run -it test PING localhost (127.0.0.1): 48 data bytes 56 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.096 ms 56 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.088 ms 56 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.088 ms ^C--- localhost ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max/stddev = 0.088/0.091/0.096/0.000 ms
现在带参数运行镜像则会ping 参数指定的主机:
$ docker run -it test google.com PING google.com (173.194.45.70): 48 data bytes 56 bytes from 173.194.45.70: icmp_seq=0 ttl=55 time=32.583 ms 56 bytes from 173.194.45.70: icmp_seq=2 ttl=55 time=30.327 ms 56 bytes from 173.194.45.70: icmp_seq=4 ttl=55 time=46.379 ms ^C--- google.com ping statistics --- 5 packets transmitted, 3 packets received, 40% packet loss round-trip min/avg/max/stddev = 30.327/36.430/46.379/7.095 ms
做为比较,假设你有一个 Dockerfile 如下:
FROM debian:wheezy CMD ["/bin/ping", "localhost"]
运行不带参数的镜像会 ping localhost
:
$ docker run -it test PING localhost (127.0.0.1): 48 data bytes 56 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.076 ms 56 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.087 ms 56 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.090 ms ^C--- localhost ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max/stddev = 0.076/0.084/0.090/0.000 ms
现在带参数运行镜像则会运行参数指令:
docker run -it test bash root@e8bb7249b843:/#
可以看看Brian DeHamer这篇文章: https://www.ctl.io/developers...
运行Docker镜像微型指南
下载一个ubuntu镜像
sudo docker pull ubuntu
使用ubuntu运行一个交互性的shell
sudo docker run -i -t ubuntu /bin/bash
docker ps命令
sudo docker ps #列出当前所有正在运行的container
sudo docker ps -l #列出最近一次启动的,且正在运行的container
sudo docker ps -a #列出所有的container
port命令
docker run -p 80:8080 <image> <cmd> #映射容器的8080端口到宿主机的80端口
删除容器命令
sudo docker rm sudo docker ps -a -q
#删除所有容器
sudo docker rm $CONTAINER_ID#删除容器id为CONTAINER_ID的容器
其他命令快速参考:
sudo docker images #查看本地镜像
sudo docker attach $CONTAINER_ID #启动一个已存在的docker实例
sudo docker stop $CONTAINER_ID #停止docker实例
sudo docker logs $CONTAINER_ID #查看docker实例运行日志,确保正常运行
sudo docker inspect $CONTAINER_ID #查看container的实例属性,比如ip等等