「这是我参与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 exec 和 docker attach 都可以进入容器,那么他两有什么区别呢?
attach 是将终端的标准输入附加到容器的终端中去,容器中的标准输出会同时打印到终端,如果退出当前终端,容器也会退出。
exec 是在一个运行态的容器中执行命令,退出当前终端,容器不会退出,所以我们推荐使用 exec。