Gitlib Gitlib
首页
  • 分类
  • 标签
  • 归档
  • Golang开发实践万字总结
  • MySQL核心知识汇总
  • Redis实践总结
  • MQ实践万字总结
  • Docker数据持久化总结
  • Docker网络模式深度解读
  • 常用游戏反外挂技术总结
  • 读书笔记
  • 心情杂货
  • 行业杂谈
  • 友情链接
关于我
GitHub (opens new window)

Ravior

以梦为马,莫负韶华
首页
  • 分类
  • 标签
  • 归档
  • Golang开发实践万字总结
  • MySQL核心知识汇总
  • Redis实践总结
  • MQ实践万字总结
  • Docker数据持久化总结
  • Docker网络模式深度解读
  • 常用游戏反外挂技术总结
  • 读书笔记
  • 心情杂货
  • 行业杂谈
  • 友情链接
关于我
GitHub (opens new window)
  • 基础架构

  • MQ

  • 微服务

  • 分布式

  • 高并发

  • 大数据

  • 容器化

    • Docker

      • Docker入门总结
      • Docker快速入门
      • Docker镜像优化
      • Docker数据持久化总结
      • Docker网络模式深度解读
      • Dockerfile入门
      • Dockerfile设置默认时区
      • Dockerfile中CMD与ENTERPOINT差异比较
        • exec 模式
        • shell 模式
        • CMD与ENTRYPOINT差异
      • Docker Compose使用总结
  • 架构设计
  • 容器化
  • Docker
Ravior
2018-02-05
目录

Dockerfile中CMD与ENTERPOINT差异比较

在我们编写Dockerfile时,CMD 和 ENTRYPOINT 指令都可以用来指定容器启动时运行的命令,从程序设计角度来说,Docker不可能提供两种一样的指令,它们之间究竟有什么差异和关联呢?

在了解两者差异之前,我们先了解一下Dockerfile中两种启动命令编写模式:

  • exec模式:CMD ["a", "b", "c"], 容器启动后会执行命令:a b c
  • Shell:CMD "a" , 容器启动后会执行命令:/bin/sh a

可以看出,exec模式采用数组的形式,容器启动时会把数组中的值依次转化组合成shell命令,而shell模式则是采用字符串的形式,字符串会作为/bin/sh -c的参数。

下面通过 CMD 指令来验证 exec 模式和 shell 模式。

# exec 模式

FROM ubuntu
CMD ["top"]
1
2

将上面代码保存到Dockerfile中,然后构建镜像并启动一个容器。

# 构建镜像
docker build -t ubuntu/test:1 .
# 启动容器
docker run -itd --name ubuntu-test-1 ubuntu/test:1
1
2
3
4

检查一下容器是否在运行:docker ps -a

docker

可以看出容器在后台正常运行,查看一下容器的进程:

docker exec ubuntu-test-1 ps aux
1

docker

可以看到top命令正在运行,pid为1。

# shell 模式

FROM ubuntu

CMD "top"
1
2
3

将上面代码保存到Dockerfile中,同样构建镜像并启动一个容器。

# 构建镜像
docker build -t ubuntu/test:2 .
# 启动容器
docker run -itd --name ubuntu-test-2 ubuntu/test:2
1
2
3
4

查看当前所有容器:docker ps -a

docker

可以看到当前容器运行的命令是:/bin/sh -c \"top\", 而之前容器运行的命令是:"top", 验证了exec模式和shell模式的差异。

查看一下当前容器的进程:

docker exec ubuntu-test-2 ps aux
1

docker

1号进程是/bin/sh -c "top",top命令pid是6。

# CMD与ENTRYPOINT差异

关于CMD与ENTRYPOINT有几条铁律:

  • 在Dockerfile中,只能有一个ENTRYPOINT指令,如果有多个ENTRYPOINT指令则以最后一个为准;
  • 在Dockerfile中,只能有一个CMD指令,如果有多个CMD指令则以最后一个为准;
  • 执行docker run如果带有其他命令参数,将会覆盖CMD指令;

同时Docker官方文档中,给出了CMD指令的用法:

  • CMD ["executable","param1","param2"] (exec form, this is the preferred form)
  • CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
  • CMD command param1 param2 (shell form)

结合以上几点,我们可以知道,当同时存在CMD指令和ENTRYPOINT指令时,只会执行ENTRYPOINT指令,至于如何处理CMD指令,就要分很多种情况,可见官方说明:

docker

在日常开发中,ENTRYPOINT指令,往往用于设置容器启动后的第一个命令,CMD指令,往往用于设置容器启动的第一个命令的默认参数,这对一个容器来说可以是变化的。

#Docker
上次更新: 2022/12/01, 11:09:34
Dockerfile设置默认时区
Docker Compose使用总结

← Dockerfile设置默认时区 Docker Compose使用总结→

最近更新
01
常用游戏反外挂技术总结
11-27
02
Golang开发实践万字总结
11-11
03
Redis万字总结
10-30
更多文章>
Theme by Vdoing | Copyright © 2011-2022 Ravior | 粤ICP备17060229号-3 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式