网易蜂巢(现更名为网易云计算基础服务)最近上线了容器自定义入口的功能, 还没有试用的同学可以先从本文开始~
CMD和ENTRYPOINT都是为镜像指定容器启动命令的常用Dockerfile指令, 本文将通过实验的方法详解这俩个命令的使用方法和用法差异.
序号 | 格式 | 使用说明 |
---|---|---|
1 | CMD ["executable","param1","param2"] | 使用 exec 执行,推荐方式 |
2 | CMD command param1 param2 | shell form,是以”/bin/sh -c”的方法执行的命 |
3 | CMD ["param1","param2"] | 为ENTRYPOINT指定参数 |
PRE:
准备了两个小脚本分别ADD到所有的测试镜像中, 最后由/root/test打印内容确定所执行的脚本
cmd.sh
#!/bin/bash
while [ "1" = "1" ]
do
for args in $@
do
echo "Printed by cmd.sh" $args >> /root/test
done
sleep 2
done
entrypoint.sh
#!/bin/bash
while [ "1" = "1" ]
do
for args in $@
do
echo "Printed by entrypoint.sh" $args >> /root/test
done
sleep 2
done
FROM hub.c.163.com/ncetest001/debian:ssh
ADD cmd.sh /root/
ADD entrypoint.sh /root/
RUN chmod +x /root/cmd.sh
RUN chmod +x /root/entrypoint.sh
CMD ["/root/cmd.sh","arg1"]
#ENTRYPOINT ["/root/entrypoint.sh","ARG1"]
docker build -t hub.c.163.com/***/debian:cmd1 -f /home/yuz/docker/df-cmd1 .
这里使用了蜂巢的镜像仓库, *为注册用户的nickname;在本地docker login蜂巢账户, 就可以向自己的仓库推送镜像, 这里我的仓库名是debian.
root@yuz-server:/home/yuz/docker# docker run -d hub.c.163.com/***/debian:cmd1
6f4545989696a7790b16233737fc3a187d782abdeb8ad604b2f106707809b409
root@yuz-server:/home/yuz/docker# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6f4545989696 hub.c.163.com/***/debian:cmd1 "/root/cmd.sh arg1" About a minute ago Up About a minute hungry_pike
root@yuz-server:/home/yuz/docker# docker exec -it 6f4545989696 /bin/bash
root@6f4545989696:/# cd
root@6f4545989696:~# tailf test
Printed by cmd.sh arg1
Printed by cmd.sh arg1
Printed by cmd.sh arg1
Printed by cmd.sh arg1
ADD cmd.sh /root/
ADD entrypoint.sh /root/
RUN chmod +x /root/cmd.sh
RUN chmod +x /root/entrypoint.sh
CMD /root/cmd.sh arg2
#ENTRYPOINT ["/root/entrypoint.sh","ARG1"]
直接查看测试结果:执行了CMD命令
root@5c78b3d7e304:~# tailf test
Printed by cmd.sh arg2
Printed by cmd.sh arg2
Printed by cmd.sh arg2
Printed by cmd.sh arg2
Add cmd.sh /root/
Add entrypoint.sh /root/
Run chmod +x /root/cmd.sh
Run chmod +x /root/entrypoint.sh
CMD ["arg3.1","arg3.2"]
Entrypoint ["/root/entrypoint.sh","ARG1"]
直接查看测试结果:CMD作为Entrpoint的参数打印
root@e600c62f8a5c:~# tailf test
Printed by entrypoint.sh arg3.2
Printed by entrypoint.sh ARG1
Printed by entrypoint.sh arg3.1
Printed by entrypoint.sh arg3.2
Printed by entrypoint.sh ARG1
Printed by entrypoint.sh arg3.1
可以看到docker ps 的结果中第二种用法以shell运行方式执行的命令是 /bin/sh -c
root@yuz-server:/home/yuz/docker# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e600c62f8a5c 2e9769872b5c "/root/entrypoint.sh " 5 minutes ago Up 5 minutes focused_wing
5c78b3d7e304 400b9c8b703a "/bin/sh -c '/root/cm" 5 minutes ago Up 5 minutes amazing_bardeen
6f4545989696 hub.c.163.com/***/debian:cmd1 "/root/cmd.sh arg1" 9 minutes ago Up 9 minutes hungry_pike
序号 | 格式 | 使用说明 |
---|---|---|
1 | ENTRYPOINT ["executable", "param1", "param2"] | 使用 exec 执行,推荐方式 |
2 | ENTRYPOINT command param1 param2 | shell form |
同CMD用法, 这里就不对Entrypoint的具体用法举例说明.
在对比区别之前再总结下共同点:
那么区别是什么?
CMD: 启动容器时候指定了运行的命令,则会覆盖掉镜像中 CMD 指定的命令
ENTRYPOINT: 启动容器时候指定了运行的命令,并不会覆盖掉镜像中Entrypoint的命令
通过实验验证下:
回忆下, cmd1镜像中使用CMD命令
root@yuz-server:/home/yuz/docker# docker run -d hub.c.163.com/***/debian:cmd1 /root/cmd.sh 替换
d81d02b0003d1e195a1e9016f5c6d3724cb38e4f16dd98295a69faccaa71587e
root@yuz-server:/home/yuz/docker# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d81d02b0003d hub.c.163.com/***/debian:cmd1 "/root/cmd.sh 替换" 5 minutes ago Up 5 minutes sleepy_euclid
root@yuz-server:/home/yuz/docker# docker exec -it d81d02b0003d /bin/bash
root@d81d02b0003d:/# cd
root@d81d02b0003d:~# tailf test
Printed by cmd.sh 替换
Printed by cmd.sh 替换
Printed by cmd.sh 替换
Printed by cmd.sh 替换
结果: 启动容器的入口命令覆盖了CMD命令
cmd2镜像中使用ENTRYPOINT命令
root@yuz-server:/home/yuz/docker# docker run -d hub.c.163.com/***/debian:cmd3 /root/cmd.sh 替换
d81d02b0003d1e195a1e9016f5c6d3724cb38e4f16dd98295a69faccaa71587e
root@yuz-server:/home/yuz/docker# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bf2ab7c4131f hub.c.163.com/***/debian:cmd3 "/root/entrypoint.sh " 4 minutes ago Up 4 minutes serene_pike
root@yuz-server:/home/yuz/docker# docker exec -it bf2ab7c4131f /bin/bash
root@bf2ab7c4131f:/# cd
root@bf2ab7c4131f:~# tailf test
Printed by entrypoint.sh 替换
Printed by entrypoint.sh ARG1
Printed by entrypoint.sh /root/cmd.sh
Printed by entrypoint.sh 替换
Printed by entrypoint.sh ARG1
Printed by entrypoint.sh /root/cmd.sh
Printed by entrypoint.sh 替换
Printed by entrypoint.sh ARG1
Printed by entrypoint.sh /root/cmd.sh
结果: 启动容器的入口命令并没有覆盖ENTRYPOINT命令, 而是作为dockerfile中ENTRYPOINT的参数执行
其实, 通过上面的两次docker ps 命令也可以看出启动命令的不同.
蜂巢上目前也加入了容器的自定义入口选项, 当容器的启动遇到问题如: Dockerfile中没有指定运行进程; 或者想要覆盖原有镜像中的CMD命令, 都可以通过下图指定地方进行添加, 欢迎适用:)
本文来自网易实践者社区,经作者张雨授权发布。