共同点和区别
共同:执行命令
这两个关键字,都可以指定镜像启动以后做的一些命令,这点不需要证明了。
共同:唯一性
多个相同关键字会覆盖,只取最后一个执行
mkdir aaa && cd aaa
cat <<EOF > dockerfile01
FROM busybox
CMD echo 1
CMD echo 2
CMD echo 3
EOF
docker build -f dockerfile01 -t a:01 .
docker run --rm a:01 # 输出3
说明只取最后一个 CMD 执行
cat <<EOF > dockerfile02
FROM busybox
ENTRYPOINT ["echo","4"]
ENTRYPOINT ["echo","5"]
ENTRYPOINT ["echo","6"]
EOF
docker build -f dockerfile02 -t a:02 .
docker run --rm a:02 # 输出6
说明也只取最后一个 ENTRYPOINT 执行
操作截图
区别:外部Command处理
先测试CMD
cat <<EOF > dockerfile11
FROM busybox
CMD echo 11111111
EOF
docker build -f dockerfile11 -t a:11 .
docker run --rm a:11 # 输出 11111111
docker run --rm a:11 echo outside-command # 输出 outside-command
可见,外部CMD可以覆盖dockerfile中的CMD
再看看EntryPoint
cat <<EOF > dockerfile12
FROM busybox
ENTRYPOINT ["echo","11112222"]
EOF
docker build -f dockerfile12 -t a:12 .
docker run --rm a:12 # 输出 11112222
docker run --rm a:12 echo outside-command # 输出 outside-command
可见,外部command不能覆盖entrypoint,只能作为参数。
能够输入外部参数,也是Entrypoint比CMD好用的主要原因。
扫描二维码关注公众号,回复:
11753935 查看本文章
同时,entrypoint也可以被外部command覆盖,通过docker run --entrypoint 覆盖。
比如:docker run --rm --entrypoint ping a:12 127.0.0.1
操作截图
区别:执行顺序
Entrypoint先执行
# 生成dockerfile
cat <<EOF > dockerfile21
FROM busybox
CMD echo CMD-21
ENTRYPOINT ["echo","ENTRYPOINT-21"]
EOF
cat <<EOF > dockerfile22
FROM busybox
ENTRYPOINT ["echo","ENTRYPOINT-22"]
CMD echo CMD-22
EOF
# 编译镜像
docker build -f dockerfile21 -t a:21 .
docker build -f dockerfile22 -t a:22 .
# 执行,无外部参数
docker run --rm a:21 #输出:ENTRYPOINT-21 /bin/sh -c echo CMD-21
docker run --rm a:22 #输出:ENTRYPOINT-21 /bin/sh -c echo CMD-21
## 可见都是,先执行Entrypoint,CMD只能作为EntryPoint参数
# 执行,带外部参数
docker run --rm a:21 echo aaaaaa #输出:ENTRYPOINT-21 echo aaaaaa
docker run --rm a:22 echo bbbbbb #输出:ENTRYPOINT-22 echo bbbbbb
## 可见,先执行Entrypoint,CMD被外部参数覆盖,仍是作为EntryPoint的参数
操作截图
应用
首先,Entrypoint是首选,不管啥镜像,用他就对了。
CMD最大的问题是无法接受参数!!!
- entrypoint可以封装命令。只需传参数,不关心核心命令是什么。比如
docker run write:1.0 "this is a book"
- entrypoint可以封死了镜像。除非Dockerfile重写entrypoint,否则都是执行基础镜像的entrypoint,保证可用性。