您的位置 首页 php

Linux云计算教程全套视频合集:CMD指令讲解

Dockerfile 中只能有一条CMD指令。如果列出多个,CMD 则只有最后一个CMD会生效。CMD 主要目的是为运行容器时提供默认值。

Docker 不是 虚拟机 ,容器就是进程,CMD 指令就是用于指定默认的容器主进程的启动命令的。在启动(运行)一个容器时可以指定新的命令来替代镜像设置中的这个默认命令。

可以包含可执行文件,当然也可以省略。CMD 指令的格式和 RUN 相似,也是两种格式:

  • shell 格式:CMD <命令>exec 格式:CMD [“可执行文件”, “参数1”, “参数2″…]参数列表格式:CMD [“参数1”, “参数2″…]。在指定了 ENTRYPOINT 指令后,用 CMD 指定具体的参数。

插个小消息,也方便想学习的同学,在文章下方留言即可试听课程外加领取千锋HTML5、UI交互设计、PHP、Java+云数据、大数据开发、VR/AR/Unity游戏开发、Python人工智能、Linux 云计算 、全栈软件测试、网络安全等全部的视频学习教程。

Docker 不是虚拟机,容器内没有后台服务的概念。不要期望这样启动一个程序到后台:

CMD systemctl start nginx

这行被 Docker 理解为:

CMD [“sh” “-c” “systemctl start nginx”]

对于容器而言,其启动程序就是容器的应用进程,容器就是为了主进程而存在的,主进程退出,容器就失去了存在的意义,从而退出,其它辅助进程不是它需要关心的东西。

就像上面的示例中,主进程是 sh , 那么当 service nginx start 命令结束后,sh 也就结束了,sh 作为主进程退出了,自然就会使容器退出。

正确的做法是直接执行 nginx 这个可执行文件,并且关闭后台守护的方式,使程序在前台运行。

CMD [“nginx”, “-g”, “daemon off;”]

ENTRYPOINT 指令

ENTRYPOINT 的目的和 CMD 一样,都是在指定容器的启动程序及参数。

ENTRYPOINT 在运行时也可以被替代,不过比 CMD 要略显繁琐,需要通过 docker run 的参数 –entrypoint 来指定。

ENTRYPOINT 的格式和 RUN 指令格式一样,也分为 exec 格式和 shell 格式。

当指定了 ENTRYPOINT 后,CMD 的含义就发生了改变,不再是直接的运行其命令,而是将 CMD 的内容作为参数传给 ENTRYPOINT 指令,也就是实际执行时,将变为:

<ENTRYPOINT> “<CMD>”

有了 CMD 后,为什么还要有 ENTRYPOINT 呢?

这种 <ENTRYPOINT> “<CMD>” 给我们带来了什么好处么?

让我们来看几个场景。

  • 场景一:让镜像变成像命令一样使用

CMD 方式

FROM centos

RUN yum update \

&& yum install -y curl

CMD [ “curl”, “-s”, “#34; ]

构建镜像后, 运行容器

# docker run –rm centos-echo-ip-cmd

执行下面命令会报错

# docker run –rm centos-echo-ip-cmd -i

我们可以看到报错,executable file not found。之前我们说过,跟在镜像名后面的是 command,运行时会替换 CMD 的默认值。因此这里的 -i 并不是添加在原来的 curl -s 后面。 而是替换了原来的 CMD,变成了 CMD [“-i”],而 -i 根本不是命令,所以报了可执行文件找不到。

所以应该使用 ENTRYPOINT 方式

FROM centos

RUN yum install -y curl

ENTRYPOINT [“curl”, “-s”, “#34;]

再次构建镜像后, 运行容器

# docker run –rm centos-echo-ip-entrypoint

# docker run –rm centos-echo-ip-entrypoint -i

这样的话, 最终的指令就变成 ENTRYPOINT [“curl”, “-s”, “#34;, “-i”]

  • 场景二:应用运行前的准备工作

启动容器就是启动主进程,但有些时候,启动主进程前,需要一些准备工作。

官方镜像 redis 中的示例:

FROM alpine:3.4

RUN addgroup -S redis && adduser -S -G redis redis

ENTRYPOINT [“docker-entrypoint.sh”]

EXPOSE 6379

CMD [ “redis-server” ]

可以看到其中为 redis 服务创建了 redis 用户,并在最后指定了 ENTRYPOINT 为 docker-entrypoint.sh 脚本。

#!/bin/sh

# allow the container to be started with `–user`

if [ “$1” = ‘redis-server’ -a “$(id -u)” = ‘0’ ]; then

chown -R redis .

exec gosu redis “$0” “$@”

fi

exec “$@”

该脚本的内容就是根据 CMD 的内容来判断,如果是 redis-server 的话,则切换到 redis 用户身份启动服务器,否则依旧使用 root 身份执行。比如:

$ docker run -it redis id

uid=0(root) gid=0(root) groups=0(root)

还有 ENTRYPOINT 指令不会被 RUN 指令覆盖,而 CMD 指令会被 RUN 指令覆盖。

文章来源:智云一二三科技

文章标题:Linux云计算教程全套视频合集:CMD指令讲解

文章地址:https://www.zhihuclub.com/152884.shtml

关于作者: 智云科技

热门文章

网站地图