记得第一次接触 docker 的时候,教程中写着 docker run -it 之类的命令,当时对这个 -it 选项是一知半解,本文就来分析一下这三个选项,尽量做到通俗易懂,这也是我写博客的目的。

一、选项说明

官方文档:https://docs.docker.com/engine/reference/commandline/run/

选项选项简写说明
–detach-d在后台运行容器,并且打印容器id。
–interactive-i即使没有连接,也要保持标准输入保持打开状态,一般与 -t 连用。
–tty-t分配一个伪tty,一般与 -i 连用。

“-”与“–”的区别请参考:Linux编程:命令行选项单横线“-”与双横线“–”的区别

二、-it 选项

使用 ubuntu:19.10 镜像创建并运行一个名称为 ubuntu1910 的容器,-i 选项指示 docker 要在容器上打开一个标准的输入接口,-t 指示 docker 要创建一个伪 tty 终端,连接容器的标准输入接口,之后用户就可以通过终端进行输入。由于 docker run [OPTIONS] IMAGE [COMMAND] [ARG...] 命令的默认 COMMAND/bin/bash,因此用户的输入是基于 bash shell 执行的。

示例中,在终端上输入了 exit 13 ,回车执行该命令,退出终端。该命令被传递到 docker run 的调用方,并且被记录到容器的 metadata 中。

[root@iZ2ze6ogddtzz4dzyy00xwZ ~]# docker run --name ubuntu1910 -it ubuntu:19.10
root@cd83bc3b0d3b:/# exit 13
exit

通过 docker ps -a 命令查看容器,Exited (13) 35 seconds ago 就是被回写的内容。

[root@iZ2ze6ogddtzz4dzyy00xwZ ~]# docker ps -a | grep ubuntu1910
cd83bc3b0d3b        ubuntu:19.10                                             "/bin/bash"              46 seconds ago      Exited (13) 35 seconds ago                                       ubuntu1910
[root@iZ2ze6ogddtzz4dzyy00xwZ ~]# 

容器的 metadata 在 /var/lib/docker/containers/containerId/ 目录下,其中 containerId-json.log 文件中记录了回写的内容。

[root@iZ2ze6ogddtzz4dzyy00xwZ cd83bc3b0d3bb76fc9fc5df326235b3554c15455891d3b3aa0921fb16796322d]# cat cd83bc3b0d3bb76fc9fc5df326235b3554c15455891d3b3aa0921fb16796322d-json.log 
{"log":"\u001b]0;root@cd83bc3b0d3b: /\u0007root@cd83bc3b0d3b:/# exit 13\r\n","stream":"stdout","time":"2020-02-08T14:35:22.509224333Z"}
{"log":"exit\r\n","stream":"stdout","time":"2020-02-08T14:35:22.509286061Z"}
[root@iZ2ze6ogddtzz4dzyy00xwZ cd83bc3b0d3bb76fc9fc5df326235b3554c15455891d3b3aa0921fb16796322d]# 

三、-d 选项

使用 docker run -d 在后台创建并启动名称为 ubuntu1 的容器,通过 docker ps 命令没有查找到处于运行状态的容器,通过 docker ps -a 命令查找到已经停止运行的 ubuntu1 容器。

[root@iZ2ze6ogddtzz4dzyy00xwZ ~]# docker run -d --name ubuntu1 ubuntu:19.10
315cc38afc2f06abb5a2fbb075ebca16455367b2de685cf0c5ba828ab62dd5a1
[root@iZ2ze6ogddtzz4dzyy00xwZ ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
c04afe750081        mysql:5.7           "docker-entrypoint.s…"   26 hours ago        Up 26 hours         0.0.0.0:3306->3306/tcp, 33060/tcp   mysql5.7
[root@iZ2ze6ogddtzz4dzyy00xwZ ~]# docker ps -a | grep ubuntu1
315cc38afc2f        ubuntu:19.10                                             "/bin/bash"              35 seconds ago      Exited (0) 34 seconds ago                                        ubuntu1
cd83bc3b0d3b        ubuntu:19.10                                             "/bin/bash"              18 minutes ago      Exited (13) 18 minutes ago                                       ubuntu1910
[root@iZ2ze6ogddtzz4dzyy00xwZ ~]# 

于是疑惑产生了, -d 是保证容器在后台运行,为什么我的容器停止运行了呢?

前面提到过, docker run [OPTIONS] IMAGE [COMMAND] [ARG...] 中有一个 COMMAND 参数,容器启动后会执行 COMMAND命令,它的默认值为 /bin/bash。也就是说容器在后台启动成功后,执行了 COMMAND 命令后直接关闭了。

docker命令请参考:https://blog.csdn.net/claram/article/details/103301942

了解到该原理后,我们可以通过在 docker run -d 后增加一个驻留在进程中长期运行的命令就可以保证容器不关闭了。

[root@iZ2ze6ogddtzz4dzyy00xwZ ~]# docker run -d --name ubuntu2 ubuntu:19.10 tail -f /dev/null 
a0d3c58fc68b139f63355594dd91c2d047b84a3d56880418eedcd8fedb6307b6
[root@iZ2ze6ogddtzz4dzyy00xwZ ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
a0d3c58fc68b        ubuntu:19.10        "tail -f /dev/null"      5 seconds ago       Up 4 seconds                                            ubuntu2
c04afe750081        mysql:5.7           "docker-entrypoint.s…"   26 hours ago        Up 26 hours         0.0.0.0:3306->3306/tcp, 33060/tcp   mysql5.7
[root@iZ2ze6ogddtzz4dzyy00xwZ ~]# 

文章内容仅代表个人观点,如有不正之处,欢迎批评指正,谢谢大家。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐