Docker学习笔记四:进入容器&删除容器

使容器在后台运行

有些时候,需要让容器在后台运行而不是直接把“启动命令”的结果输出在当前宿主机下。此时,可以通过添加-d参数来实现。

举个例子,假如不使用-d参数执行下面这条命令:

docker run ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"

那么会一直在控制台输出hello world,如下所示:

docker run ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"
hello world
hello world
hello world
...

但是如果使用了-d参数,此时容器会在后台运行并且不会将输出结果输出到控制台。如下所示:

docker run -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"
ccd644424bffed71747e2a36977d70745cc211e7dac71006437ca52914c1b743

进入一个docker容器的几种方法

  1. 使用ssh登陆进容器;
  2. 使用nsenter、nsinit等第三方工具;
  3. 使用docker本身提供的工具。

为什么不使用SSH进入Docker
oschina文章
使用nsenter进入Docker容器
关于什么是nsenter请参考如下文章:
Github–nsenter介绍

在了解了什么是nsenter之后,系统默认将我们需要的nsenter安装到主机中

如果没有安装的话,按下面步骤安装即可(注意是主机而非容器或镜像)

具体的安装命令如下:

$ wget https://www.kernel.org/pub/linux/utils/util-linux/v2.24/util-linux-2.24.tar.gz  
$ tar -xzvf util-linux-2.24.tar.gz  
$ cd util-linux-2.24/  
$ ./configure --without-ncurses  
$ make nsenter  
$ sudo cp nsenter /usr/local/bin

nsenter可以访问另一个进程的名称空间。所以为了连接到某个容器我们还需要获取该容器的第一个进程的PID。可以使用docker inspect命令来拿到该PID。
docker inspect命令使用如下:

$ sudo docker inspect --help   

inspect命令可以分层级显示一个镜像或容器的信息。比如我们当前有一个正在运行的容器

如果要显示该容器第一个进行的PID可以使用如下方式

$ sudo docker inspect -f {{.State.Pid}} 44fc0f0582d9 

在拿到该进程PID之后我们就可以使用nsenter命令访问该容器了。

$ sudo nsenter --target 3326 --mount --uts --ipc --net --pid  

其中的3326即刚才拿到的进程的PID

Docker目前主要提供了docker exec和docker attach两个命令。

docker attach进入一个容器内部

docker attach containerId|containerName

如下所示,首先使用docker run创建了一个容器,为其分配了伪终端,打开了它的标准输入流,并且让它在后台执行。

然后使用docker attach进入了该容器内部,实际上就是进入容器“启动命令”的终端。(containerId可以不用输全,只要能代表容器即可。例如下面的0539就是代表容器ID以0539开头的容器,一般情况下,前4位就能唯一标识一个容器了)

[root@localhost Desktop]# docker run -itd ubuntu /bin/bash
0539852938cdb9538f67750d07ed8c7fa072de742d5c0c02128576f2d227ec46
[root@localhost Desktop]# docker attach 0539
root@0539852938cd:/# 
root@0539852938cd:/# ls
bin   dev  home  lib64  mnt  proc  run   srv  tmp  var
boot  etc  lib   media  opt  root  sbin  sys  usr
root@0539852938cd:/# exit
exit
[root@localhost Desktop]#

docker exec进入一个容器内部

 docker exec [options] containerName|containerId command [arg]

如下所示,首先使用docker run创建了一个容器,并使它在后台运行。

docker exec命令可以在一个运行的容器内部执行一条命令,例如下图中执行docker exec aec0 mkdir dir1后,就在容器中创建了一个dir1的文件夹。除此以外,还可以在容器中启动一个新的bash,例如下图执行了docker exec -it aec0 /bin/bash,在容器内部启动了一个新的bash终端,并使用-it为其分配一个伪终端绑定到标准输出上。

[root@localhost Desktop]# docker run -itd ubuntu /bin/bash
aec040300549f95a8c4b37fecd3059122f08cb5422673640bd0bd9e641d0644c
[root@localhost Desktop]# docker exec aec0 mkdir dir1
[root@localhost Desktop]# docker exec -it aec0 /bin/bash
root@aec040300549:/# ls
bin   dev   etc   lib    media  opt   root  sbin  sys  usr
boot  dir1  home  lib64  mnt    proc  run   srv   tmp  var
root@aec040300549:/# exit
exit
[root@localhost Desktop]# 

attach与exec的比较

使用docker run -d ubuntu "while true ; do sleep 1 ; echo hello; done"创建并在后台启动容器,每隔一秒打印一个hello。

[root@localhost Desktop]# docker run -d ubuntu /bin/sh -c "while true ; do sleep 1 ; echo hello; done"
a695e721e324f11cc958867d13c9c6707018e359c747ba103554d4d8e9e7750f

使用docker attach 5719进入容器内部后,会在控制台每隔一秒打印了一个hello。

[root@localhost Desktop]# docker attach a695
hello
hello
...

但是使用docker exec –it 5719 /bin/bash进入容器后,并没有打印“hello”,因为docker exec执行后,在容器中打开一个新的终端,该终端与“启动命令”的终端不是同一个。

[root@localhost Desktop]# docker exec -it a695 /bin/bash
root@a695e721e324:/#

attach与exec的主要区别

  1. attach直接进入容器“启动命令”的终端,不会启动新的进程;
  2. exec则是在容器中打开新的终端,并且可以启动新的进程;
  3. 如果想直接在终端中查看容器“启动命令”的输出,用attach;其他情况使用exec。

删除容器

删除一个处于终止状态的容器

我们使用docker rm containName|containId来删除一个处于终止状态的容器。 请留意,在不加任何参数的情况下,docker rm只能删除处于终止状态的容器。
docker rm实例
执行docker ps –a查看所有的容器,如下图所示,其中容器名为dist\fracted_wright的容器STATUS对应为Exited,也就意味着它处于终止状态。

[root@localhost Desktop]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS                     PORTS               NAMES
21d9ad4beeec        busybox             "echo hello"        6 seconds ago        Exited (0) 5 seconds ago                       dist\fracted_wright
70b35ab2219f        ubuntu              "/bin/bash"         28 seconds ago       Up 20 seconds                                  container1
e70fa4917b69        ubuntu              "/bin/bash"     

执行docker rm 21d9,我们可以将该容器删除,再次执行docker ps –a,如下图所以,从图中可以看出,该容器已经被不存在了,说明删除成功了。

[root@localhost Desktop]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS               NAMES
70b35ab2219f        ubuntu              "/bin/bash"         About a minute ago   Up About a minute                       container1
e70fa4917b69        ubuntu              "/bin/bash"         2 minutes ago        Up 2 minutes                            admiring_heise

使用docker rm 删除一个正在运行的容器,失败了
从上图我们可以看到containId=70b35ab2219f 的容器正在运行状态,当我执行docker rm 70b3,如下图所示,提示不能删除一个正在运行的容器。从下图可以看出该容器并没有被删除。

[root@localhost Desktop]# docker rm 70b3
Error response from daemon: You cannot remove a running container 70b35ab2219f9c610053ffc65b0a961bd2bc87b6a849fe52253da5dffdc80508. Stop the container before attempting removal or use -f

删除一个正在运行的容器

删除一个正在运行的容器,有两种方式:

  • 第一种,先执行docker stop停止该容器,然后使用docker rm删除掉;
  • 第二种,执行docker rm –f命令,强制删除。
[root@localhost Desktop]# docker stop 70b3
70b3
[root@localhost Desktop]# docker rm 70b3
70b3
[root@localhost Desktop]# docker rm -f e70f
e70f
[root@localhost Desktop]# docker ps -a
CONTAINER ID        IMAGE               COMMAND     

删除所有处于终止状态的容器

可以执行docker rm $(docker ps -a -q),用来删除所有处于终止状态的容器。

我们知道docker ps –a命令可以查看所有容器的信息。而docker ps –a –q只查看所有容器的containerId。在Linux中,将命令放在$()中,会执行命令并返回命令的执行结果。因此$( docker ps -a -q)会返回所有容器的container id,而docker rm只能干掉终止的容器,而如果用docker rm删除正在运行的容器时,将不能删除掉。所以可以使用docker rm $(docker ps -a -q)来删除所有处于终止状态的容器。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值