Docker-04-容器启停

581 阅读4分钟

「这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战」。

接上节内容,为什么 hello-world 容器在启动之后的状态变成了 Exited 呢?在这里,我们介绍两种启动容器的方式。

交互式

我们知道启动容器使用 docker run 命令,但是 Docker 允许我们在启动容器的时候打开一个伪终端(参数:-t),此时需要让容器的标准输入保持打开,以达到交互的目的(参数:-i)。

启动 ubuntu 容器:

root@phyger-VirtualBox:~# docker run -i -t ubuntu /bin/bash
root@0acc66615217:/# hostname
0acc66615217
root@0acc66615217:/#

退出 ubuntu 容器:

root@0acc66615217:/# exit
exit
root@phyger-VirtualBox:~# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
0acc66615217        ubuntu              "/bin/bash"         2 minutes ago       Exited (0) 5 seconds ago                       tender_archimedes
c3d23ead2fc6        hello-world         "/hello"            23 hours ago        Exited (0) 23 hours ago                        sharp_sinoussi
root@phyger-VirtualBox:~#

退出后,容器状态为 Exited,为什么呢?

因为容器的存活依赖守护进程,即 1 号进程,如果没有 1 号进程,容器在执行完用户指定的指令后就会退出,如果有 1 号守护进程一直存在,则容器会保持 UP

对于交互式启动的容器,我们可以使用 Ctrl+Q+P 的组合进行退出,这样容器会将/bin/bash 作为 1 号进程保留,使容器保持 UP 态。

root@phyger-VirtualBox:~# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
0acc66615217        ubuntu              "/bin/bash"         11 minutes ago      Up 5 minutes                            tender_archimedes

查看容器内进程:

root@phyger-VirtualBox:~# docker attach 0acc
root@0acc66615217:/# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 13:39 pts/0    00:00:00 /bin/bash
root         8     1  0 13:41 pts/0    00:00:00 ps -ef
root@0acc66615217:/#

守护式

如果我们希望容器在启动后可以自动后台运行,我们就需要使用参数:-d

启动 ubuntu 容器:

root@phyger-VirtualBox:~# docker run -d ubuntu /bin/bash -c "while true;do echo hello docker;sleep 1;done"
742eece654dbb6c2797a65e77b012d830c67185a327faa78295fd280967af3ff
root@phyger-VirtualBox:~#

以守护式模式启动完容器后,会回到 host 的终端界面。

后面的 sh 命令是为了构造守护进程,写了一个死循环,这样守护进程一直不会退出,容器可以保持 UP 态。

查看 ubuntu 容器:

root@phyger-VirtualBox:~# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
742eece654db        ubuntu              "/bin/bash -c 'while…"   2 minutes ago       Up About a minute                       nice_khorana
0acc66615217        ubuntu              "/bin/bash"              22 minutes ago      Up 9 minutes                            tender_archimedes
root@phyger-VirtualBox:~#

进入 ubuntu 容器:

root@phyger-VirtualBox:~# docker exec -it 742 /bin/bash
root@742eece654db:/# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 13:47 ?        00:00:00 /bin/bash -c while true;do echo hello docker;sleep 1;done
root       258     0 23 13:51 pts/0    00:00:00 /bin/bash
root       267     1  0 13:51 ?        00:00:00 sleep 1
root       268   258  0 13:51 pts/0    00:00:00 ps -ef
root@742eece654db:/#

退出 ubuntu 容器:

root@742eece654db:/# exit
exit
root@phyger-VirtualBox:~# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
742eece654db        ubuntu              "/bin/bash -c 'while…"   5 minutes ago       Up 5 minutes                            nice_khorana
0acc66615217        ubuntu              "/bin/bash"              25 minutes ago      Up 13 minutes                           tender_archimedes
root@phyger-VirtualBox:~#

停止启动容器

停止:docker stop <containID>

启动:docker start <containID>

启停容器

删除容器

命令:docker rm [-f] <containID>

对于正在运行的容器是不允许直接删除的,需要先 stop,然后才可以删除。如果想强制删除正在运行的容器则可以添加参数 -f 实现。

删除容器

关于 attach 和 exec

我们使用 docker execdocker attach 都可以进入容器,那么他两有什么区别呢?

attach 是将终端的标准输入附加到容器的终端中去,容器中的标准输出会同时打印到终端,如果退出当前终端,容器也会退出。

exec 是在一个运行态的容器中执行命令,退出当前终端,容器不会退出,所以我们推荐使用 exec

attach和exec