【问题标题】:Docker -it command is related to a Docker image or Docker containerDocker -it 命令与 Docker 镜像或 Docker 容器相关
【发布时间】:2020-10-04 17:34:05
【问题描述】:

我是 Docker 新手,正在尝试使用 101-tutorial docker image(https://github.com/dockersamples/101-tutorial) 了解 Docker

在本课中,他们试图解释当 2 个容器实例从同一个镜像运行时,第一个容器创建的数据默认在第二个容器中不可用(除非我们使用容器卷和挂载,等)。

第 1 点和第 2 点表明 ubuntu 容器正在运行,并且有一个名为 data.txt 的文件。

据我了解,docker -it 用于访问 docker 容器内的终端。 https://docs.docker.com/engine/reference/run/

但我不明白第三点中使用的命令。为什么docker run -it ubuntu ls / 命令在 Ubuntu 映像上运行,而不是在使用 Container ID 的容器上运行?该命令是否仅用于显示图像内的内容,而不是使用 ls / 显示 docker 容器内的内容?

我预计第 3 点应该创建另一个容器实例,然后运行 ​​ls /,但按照 docker ps,我看到我的机器中只有一个 ubuntu 容器运行。

【问题讨论】:

  • IIUC,它确实启动了一个容器并在其中运行ls,但该容器立即再次关闭。
  • 因此使用命令中传递的镜像名称创建了一个 docker 容器,并在该容器上运行ls /,然后立即关闭该 docker 容器?
  • 尝试docker ps -a 列出所有容器。现在你只得到“正在运行”的。 @daniu 是正确的,因为只要 PID=1 的进程正在运行,容器就会启动并运行。 ls 运行然后退出,这使容器进入“退出”状态。更多信息:stackoverflow.com/questions/32427684/…
  • @tgogos:谢谢。很清楚
  • 另外,docker run 命令总是关于 ImageID 而不是 containerID,这意味着它总是会启动一个新容器。 stackoverflow.com/a/46138763/6700081

标签: docker docker-container


【解决方案1】:

正如documentation for docker run 中所说:

Docker 在隔离的容器中运行进程。容器是在主机上运行的进程。主机可以是本地的或远程的。当操作员执行 docker run 时,运行的容器进程是隔离的,因为它有自己的文件系统,自己的网络,以及与主机分离的自己的隔离进程树。

该过程完成后,容器将被关闭。

至于您的问题是“指的是图像还是容器”-您将图像作为参数提供给创建容器,然后在创建的容器中运行该过程。

一个 Docker 容器的生命周期是:

  • docker run imagename -> 从镜像imagename 创建容器x
  • docker exec x ls -> 在 running 容器中执行命令 ls x
  • docker stop x -> 停止容器(但在 docker container ls -a 中仍然可见)
  • docker start x -> 重启容器x
  • docker stop x -> 停止容器xagain
  • docker rm x -> 删除容器x(现在ls -a 也不会显示)

【讨论】:

  • 因此,当我们使用长时间运行的命令(例如启动 springboot 应用程序等)执行 docker run 时,除非我们手动停止它们,否则这些命令不会完成,因此 docker 容器会一直运行,除非容器是手动的停了下来。但是对于带有类似ls / 的短命令的docker run,因为返回结果并且命令完成,所以在命令运行后docker 容器退出/停止/关闭。对吗?
  • @firstpostcommenter 是的(虽然你不需要手动停止容器但也可以终止进程)。我编辑了我的帖子以获得常见生命周期命令的列表。
【解决方案2】:

Docker 容器彼此完全隔离。当您使用镜像创建容器时,系统中的一小部分资源会在命名空间和 cgroup 的帮助下被隔离,然后将镜像中的文件复制到这个隔离环境的资源中。

当您执行命令docker run -it ubuntu ls / 时,它会创建一个新容器,运行指定的命令ls / 并使用-i 和-t 标志为您提供到docker 容器的交互式tty。

运行此过程并显示输出后,容器立即退出,因此docker ps 的输出中没有显示任何内容。为了检查创建的容器,运行docker ps --all 命令。

【讨论】:

    【解决方案3】:

    我看到问题是关于docker run imagename 命令。

    TLDR:- 您看不到 docker 容器,因为 docker 容器已创建并启动,然后立即退出。为什么?因为这一切都归结为Dockerfile 中给出的CMD 命令,该命令用于构建您尝试运行的docker 映像(在本例中为ubuntu docker 映像)。


    关于 Docker 和docker run 命令的一些背景知识:-

    在您的情况下,当您运行 docker run ubuntu 命令时,会创建并启动 docker 容器,然后立即退出,因此您不会在 docker ps 容器列表中看到它,但您可以在 docker ps -a 命令结果中看到它exited 状态。

    这是因为容器旨在运行特定的任务或进程,例如托管 Web 服务器或应用程序服务器或数据库的实例,或者只是执行某种计算或分析。

    一旦任务完成,容器就会退出。容器只有在它里面的进程还活着的时候才会存在。如果容器内的 WebService 停止或崩溃,则容器退出。

    那么谁来定义容器内运行的进程呢?

    如果我们查看流行的 docker 镜像(如 nginx)的 dockerfile,我们会看到一条名为 CMD 的指令,它代表定义将在容器启动时在容器中运行的程序的命令。

    对于 nginx 镜像是 nginx 命令,对于 mysql 镜像是 mysqld 命令。

    您之前尝试做的是使用 Ubuntu 映像运行容器,如果我们看到该映像的 dockerfile (Ubuntu Docker image's dockerfile),我们将看到它使用 bash 作为 CMD 中的默认命令线。现在bash 并不是真正的进程,如网络服务器或数据库服务器。它是一个外壳,用于侦听来自终端的输入,如果找不到终端,它就会退出。因此,当您之前运行映像时,Docker 从该映像创建了一个容器并启动了 bash 程序。默认情况下,docker 在运行时不会将终端附加到容器,因此 bash 程序找不到终端并退出。由于创建容器时启动的进程完成了,所以容器也退出了。

    那么我们如何指定不同的命令来启动容器呢?

    一种选择是将命令附加到 docker run 命令,这样它就会覆盖映像中指定的默认命令。例如docker run ubuntu sleep 5 使用 sleep 5 命令作为添加的选项。这样,当容器启动时,它会运行 sleep 程序,等待 5 秒钟然后退出。但是我们如何使这种变化永久化。假设我们希望图像在启动时始终运行 sleep 命令。然后我们应该从基础 ubuntu 镜像创建我们自己的镜像并指定一个新命令。

    Dockerfile,

    使用CMD指令,

    FROM Ubuntu
    CMD sleep 5
    

    或者同时使用Entrypoint和CMD指令哪个更好,

    FROM Ubuntu
    ENTRYPOINT ["sleep"]
    CMD ["5"]
    

    所以我们现在可以使用docker build 命令构建新镜像并将其命名为 ubuntu-sleeper 或类似名称。我们现在可以简单地运行docker run ubuntu-sleeper 命令并获得相同的结果,它总是休眠 5 秒并退出

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-20
      • 2014-05-07
      • 2016-08-06
      相关资源
      最近更新 更多