# 停止与删除容器<a name="ZH-CN_TOPIC_0184808229"></a>

用docker stop停止名为container1的容器：

```
[root@localhost ~]# docker stop container1
```

也可以用docker kill来杀死容器达到停止容器的目的：

```
[root@localhost ~]# docker kill container1
```

当容器停止之后，可以使用docker rm删除容器：

```
[root@localhost ~]# docker rm container1
```

当然，使用docker rm -f 强制删除容器也是可以的：

```
[root@localhost ~]# docker rm -f container1
```

## 注意事项<a name="zh-cn_topic_0182302403_section3379521174917"></a>

-   禁止使用docker rm -f XXX 删除容器。如果使用强制删除，docker rm会忽略过程中的错误，可能导致容器相关元数据残留。如果使用普通删除，如果删除过程出错，则会删除失败，不会导致元数据残留。
-   避免使用docker kill命令。docker kill命令发送相关信号给容器内业务进程，依赖于容器内业务进程对信号的处理策略，可能导致业务进程的信号处理行为与指令的预期不符合的情况。
-   docker stop处于restarting状态的容器可能容器不会马上停止。如果一个容器使用了重启规则，当容器处于restarting状态时，docker stop这个容器时有很低的概率会立即返回，容器仍然会在重启规则的作用下再次启动。
-   不能用docker restart重启加了--rm参数的容器。加了--rm参数的容器在退出时，容器会主动删除，如果重启一个加了--rm的参数的容器， 可能会导致一些异常情况，比如启动容器时，同时加了--rm与-ti参数，对容器执行restart操作，可能会概率性卡住无法退出。

## docker stop/restart 指定t参数且t<0时，请确保自己容器的应用会处理stop信号<a name="zh-cn_topic_0182302403_section108315281496"></a>

Stop的原理：（Restart会调用Stop流程）

1.  Stop会首先给容器发送Stop 信号（15）
2.  然后等待一定的时间（这个时间就是用户输入的 t）
3.  过了一定时间，如果容器还活着，那么就发送kill信号（9）强杀

输入参数t（单位s）的含义：

-   t<0  :  表示死等，不管多久都等待程序优雅退出，既然用户这么输入了，表示对自己的应用比较放心，认为自己的程序有合理的stop信号的处理机制
-   t=0 ： 表示不等，立即发送kill -9 到容器
-   t\>0 ： 表示等一定的时间，如果容器还未退出，就发送kill -9 到容器

所以如果用户使用t<0 \(比如t=-1\)，请确保自己容器的应用会正确处理signal 15，如果容器忽略了该信号，会导致docker stop一直卡住。

## 如果容器处于Dead状态，可能底层文件系统处于busy状态，需要手动删除<a name="zh-cn_topic_0182302403_section550784274912"></a>

Docker在执行容器删除时，先停止容器的相关进程，之后将容器状态更改为Dead，最后执行容器rootfs的删除操作。当文件系统或者device mapper处于忙碌状态时，最后一步rootfs的删除会失败。docker ps -a查看会发现容器处于Dead状态。Dead状态的容器不能再次启动，需要等待文件系统不繁忙时，手动再次执行docker rm进行删除。

## 共享pid namespace容器，子容器处于pause状态会使得父容器stop卡住，并影响docker run命令执行<a name="zh-cn_topic_0182302403_section12464421336"></a>

使用--pid参数创建共享pid  namespace的父子容器，在执行docker stop父容器时，如果子容器中有进程无法退出（比如处于D状态、pause状态），会产生父容器docker stop命令等待的情况，需要手动恢复这些进程，才能正常执行命令。

遇到该问题的时候，请对pause状态的容器使用docker  inspect 命令查询 PidMode对应的父容器是否为需要docker stop的容器。如果是该容器，请使用docker  unpause将子容器解除pause状态，指令即可继续执行。

一般来说，导致该类问题的可能原因是容器对应的pid  namespace由于进程残留导致无法被销毁。如果上述方法无法解决问题，可以通过借助linux工具，获取容器内残留进程，确定pid  namespace中进程无法退出的原因，解决后容器就可以退出：

-   获取容器pid  namespace id

    ```
    docker inspect --format={{.State.Pid}} CONTAINERID | awk '{print  "/proc/"$1"/ns/pid"}' |xargs readlink
    ```

-   获取该namespace下的线程

    ```
     ls -l /proc/*/task/*/ns/pid |grep -F PIDNAMESPACE_ID |awk '{print $9}' |awk -F  \/ '{print $5}'
    ```


