【Docker 那些事儿】如何安全地停止、删除容器

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

在这里插入图片描述

文章目录


在这里插入图片描述

🌟 前言

上一篇文章讲了容器的运行启动【Docker 那些事儿】如何安全地进入到容器内部
 
本篇文章将继续承接上一篇讲讲如何 停止、删除容器对容器进行资源限制
在这里插入图片描述

1. 停止和删除容器

🍑 停止容器

在工作中有时会需要将容器暂停例如要为容器文件系统做一个快照时。使用 docker pausedocker unpause 命令可以对容器进行暂停与激活操作并且暂停状态的容器不会占用宿主机 CPU 资源。

当不再需要业务运行时就要将容器关闭这时可以使用 docker stop 命令。当遇到特殊情况而无法关闭容器时还可以使用 docker kill 命令强制终止容器示例代码如下
在这里插入图片描述
以上示例使用 docker kill 命令强制终止了容器。

企业中通常有大量的容器需要操作一个一个操作会浪费大量的人力及时间成本。在这种情况下可以将 Docker 命令与正则表达式结合起来实现对容器的批量操作。

首先查看运行状态容器的 ID 号示例代码如下
在这里插入图片描述
接着使用 正则表达式 根据运行状态容器的 ID 号关闭正在运行的容器示例代码如下
在这里插入图片描述
以上示例运用 docker stop 命令与正则表达式批量终止了运行中的容器该命令还有另一种编写方式示例代码如下
在这里插入图片描述
另外使用类似方法还可以对容器进行批量删除、启动等操作。

docker stop 与 docker kill 的区别如下👇

  • docker stop 执行时首先给容器发送一个TERM信号让容器做一些退出前必须做的保护性、安全性操作然后让容器自动停止运行如果在一段时间内容器没有停止运行再执行 kill -9 指令强制终止容器。
  • docker kill 执行时不论容器是什么状态在运行什么程序直接执行 kill -9 指令强制终止容器。

🍑 删除容器

容器以其轻量级的特点受人欢迎通常一些容器使用不久就会闲置长期积累会导致不必要的资源浪费所以要及时清理无用的容器。
 
docker rmi 命令不同docker rm 命令用于删除容器下面将介绍删除容器的几种方法。

🍇 删除容器方法一

首先查看所有容器及其状态示例代码如下
在这里插入图片描述
从以上示例中可以看到目前宿主机中有三个处于终止状态的容器以及一个处于运行状态的容器。

然后结合正则与 docker rm 命令列出处于终止状态的容器并进行删除示例代码如下
在这里插入图片描述
以上示例使用 docker rm 命令结合正则表达式实现了批量删除容器并回显删除的容器 ID

最后查看并确认容器已删除示例代码如下
在这里插入图片描述
从示例中可以看到处于终止状态的容器已经被删除运行状态的容器并没有被删除。

🍇 删除容器方法二

首先查看所有容器及其状态示例代码如下
在这里插入图片描述
从以上示例中可以看到宿主机中有三个处于终止状态的容器以及一个处于运行状态的容器。

接着使用 docker rm 命令结合正则表达式列出所有容器 ID 号并删除容器示例代码如下
在这里插入图片描述
从以上示例中可以看到命令的执行时发生了报错提示无法删除一个正在运行的容器可以使用 -f 参数强制执行。

然后查看当前容器状态示例代码如下
在这里插入图片描述
上述示例中可以看到docker rm 命令结合正则表达式删除了三个终止状态的容器运行中的容器没有被删除。
最后根据报错提示在命令中添加一个 -f 参数表示强制删除示例代码如下
在这里插入图片描述
从以上示例中可以看到处于运行状态中的容器已经被删除。

🍇 删除容器方法三

首先查看当前容器及其状态示例代码如下
在这里插入图片描述
接着使用 docker rm 命令结合 docker ps -q -f status=exited 命名筛选出处于终止状态的容器 ID 号并删除容器示例代码如下
在这里插入图片描述
上述示例中命令已经执行成功。

最后查看容器是否被删除示例代码如下。
在这里插入图片描述
上述示例中可以看到处于终止状态的容器都已经被删除。

🍇 删除容器方法四

Docker1.13 版本开始用户可以使用 docker container prune 命令删除处于终止状态的容器。

首先查看当前容器及其状态示例代码如下
在这里插入图片描述
接着使用命令开始删除所有处于终止状态的容器示例代码如下
在这里插入图片描述
从以上示例中可以看到当 docker container prune 命令执行之后系统会向用户发出警告信息并询问是否要继续。

docker container prune 会直接删除所有处于终止状态的容器为了防止用户的误操作将有用的容器删除命令执行时会有警告信息与询问信息。

这时如果确认要删除可输入 “y” 否则输入 “n” 即可阻止命令执行。示例删除了所有处于终止状态的容器命令执行成功之后返回一个释放内存的值。

最后查看当前容器及其状态示例代码如下
在这里插入图片描述
从以上示例中可以看到处于终止状态的容器已经被删除而处于运行状态的容器并没有受到影响。

2. 容器资源限制

在默认情况下Docker 没有对容器进行硬件资源的限制。使用 Dcoker 运行容器时一台主机上可能会运行成百上千个容器这些容器虽然相互隔离但是在底层使用着相同的 CPU内存磁盘 等资源。

如果不对容器使用的资源进行限制那么容器对宿主机资源的消耗可能导致其他容器或进程不能够正常运行严重时可能导致服务完全不可用。

本节将介绍如何对容器配置 CPU内存Block IO 等资源的限制。

🍑 限制容器内存资源

Linux 服务器上如果内核检测到没有足够的内存Memory来执行重要的系统功能内核会提示OOMEOut of Memory Error内存溢出并开始终止进程以释放内存这称为 OOM 操作。
 
任何进程都有可能被终止包括 Docker 和其他重要的应用程序。如果终止了系统关键进程可能导致整个系统瘫痪。
 
设置限制内存上限虽然能保护主机但是也可能会导致容器里的服务运行不畅。如果为服务设置的内存上限太小服务在正常工作时可能出现资源不足
 
如果设置过大则会因为调度器算法浪费内存。因此合理的做法是遵循以下原则。

  1. 为应用做内存压力测试了解正常业务需求下内存的使用情况然后再进入生产环境。
  2. 限制容器的内存使用上限。
  3. 尽量保持主机的资源充足一旦通过监控发现资源不足就进行扩容或者对容器进行迁移。
  4. 内存资源充足的情况下尽量不要使用 Swap交换分区Swap 的使用会导致内存计算变得复杂对调度器造成压力。

下面介绍Docker启动参数中的内存限制参数。

  • -m--memory

设置容器可使用的最大内存最小值是4MB。

  • --memory-swap

设置容器可使用内存+Swap的最大值。

  • --memory-swapiness

默认情况下用户可以设置一个0~100的值代表允许内存与交换分区置换的比例。

--memory-reservation

设置一个内存使用的 soft limit非强制性限制如果 Docker 发现主机内存不足会执行 OOM 操作。这个值必须小于 –memory 设置的值。

  • --kernel-memory

容器能够使用的内核内存的大小最小值为 4MB

  • --oom-kill-disable

设置是否在运行 OOM 时候终止容器进程。
 
宿主机会在内存不足时随机关闭一些进程而该参数会保护容器进程不被关闭。只有通过设置 -memory 限制容器内存才可以使用该参数否则容器会耗尽主机内存而且导致主机应用被终止。

❗注--memory-swap 只有在设置了 -memory 时才有意义。
 
使用 Swap 允许容器在耗尽所有可用的内存时将多余的内存需求写入磁盘。两者的关系如表所示。

在这里插入图片描述
以上两个参数默认值都为 -1即对容器使用 内存Swap 没有限制。

下面使用 progrium/stress 镜像来介绍如何为容器分配内存该容器可以模拟进行压力测试。示例代码如下
在这里插入图片描述
以上示例运行了一个容器分配可用最大内存为 300MB可用 Swap100MB

其中–vm 1 参数表示启动一个内存工作线程
 
–vm-bytes 280M 参数表示每个线程分配 280MB 内存。
 
可以看到系统不断地给容器分配内存、释放内存一直循环。由于使用的内存 380MB在最大使用量400MB之内容器正常运行。

下面测试内存使用超出限额的情况实例代码如下
在这里插入图片描述
从以上示例中可以看到容器使用的内存超过了限额容器里的进程被终止掉了其中signal 9 就是终止进程信号最后容器退出。

如果在创建容器时仅指定 -m 参数不设置 -memory-swap 参数那么 -memory-swap 默认是 -m 的两倍示例代码如下
在这里插入图片描述
在以上示例中容器最多使用 100MB 内存和 100MB Swap

🍑 限制容器CPU资源

主机上的进程会通过时间分片机制使用 CPUCPU 用频率来量化也就是每秒执行的运算次数。为容器限制 CPU 资源并不是改变 CPU 的频率而是改变每个容器能使用的 CPU 时间片。
 
理想状态下CPU 应该一直处于运算状态并且进程的计算量不会超过 CPU 的处理能力。
 
Docker 允许用户为每个容器设置一个数字代表容器的 CPU share共享默认情况下每个容器的 share 值是 1000。这个 share 值是相对的本身并不能代表任何确定的意义。当主机上有多个容器运行时每个容器占用的 CPU 时间比例为它的 share 值在总额中的比例。
 
例如主机上有两个一直使用 CPU 的容器为了方便理解不考虑主机上运行的其他进程其 CPU share 都为 1000那么两个容器 CPU 使用率都是 50%
 
如果把其中一个容器的 share 值设置为 500那么两者 CPU 的使用比为 2:1如果删除 share 值为 1000 的容器剩下来容器的 CPU 使用率将会是 100%

Docker 为容器设置 CPU 资源限制的参数是 -c–cpu-shares其值是一个整数。运行两个容器 test01test02并设置 CPU 权重示例代码如下
在这里插入图片描述
以上示例中分别为 test01test02 设置 CPU share10002000

接着使用 docker stats 查看容器占用 CPU 情况示例代码如下
在这里插入图片描述
从以上示例中可以看到两个容器 CPU 的使用占比约为 2:1与先前设置的 share 值相吻合。

此时将 share 值为 2000test02 容器暂停再来查看 CPU 使用情况示例代码如下
在这里插入图片描述
设置 CPU 资源限制还可以使用 –cpuset-cpus 参数它能够指定容器使用某一颗 CPU。这里使用 CPU 测试镜像 agileek/cpuset-test 进行测试其功能是将 CPU 用满示例代码如下
在这里插入图片描述
使用宿主机 top 命令查看 CPU 使用情况可以看到 CPU1 已经被占满而 CPU0 没有受到影响如图所示
在这里插入图片描述

🍑 限制容器 Block IO

Block IO 表示磁盘的读写Docker 可以用配置 bps每秒读写的数据量和 iops每秒读写的次数的方式限制容器对磁盘读写的带宽。

下面介绍限制 bps 与 iops 的参数。

  • --device-read-bps

限制读某个设备的bps。

  • --device-write-bps

限制写某个设备的bps。

  • --device-read-iops

限制读某个设备的iops。

  • --device-write-iops

限制写某个设备的iops。

默认情况下所有容器对磁盘读写的带宽是相同的通过配置 -blkio-weight 参数的值10-1000可以指定容器 Block IO 的优先级。–blkio-weight-cpu-shares 类似默认值都是 500

下面运行的两个容器 test01test02其中test01 读写磁盘的带宽是 test02 的两倍。
在这里插入图片描述
从以上示例中可以看到容器 test01 的相对权重值是 800test02 的相对权重值是 400test01 读写磁盘的带宽是 test02 的两倍。

下面运行一个容器限制其对 /dev/sda 写入的速率不高于 20MB/s。因为容器文件系统在宿主机的 /dev/sda 上在容器中写文件相当于对宿主机的 /dev/sda 进行写入操作。

示例代码如下
在这里插入图片描述
以上示例运行了一个 CentOS 容器并限制其写 /dev/sda 的速率为 20MB/s

下面通过命令查看该容器的写入速率示例代码如下
在这里插入图片描述
从以上示例中可以看到设置了写入限制的容器写入速率为 19.4MB/s没有超过写入限制的 20MB/s

作为对比下面运行一个不限制写入速率的容器示例代码如下
在这里插入图片描述
以上示例中一个不限制读写速率的容器写入速率是 61.3MB/s

其他参数使用方法与之类似大家可以自己尝试做一下🤗。

3. 总结

这两篇文章首先介绍了如何获取 Docker 帮助手册然后通过大量的实验讲解了操作 Docker 容器的方法包括进入、停止、删除容器等以及容器各种状态之间如何转换
 
最后介绍了 Docker 容器的资源限制包括 限制内存CPUBLOCK IO 三种方法。

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: Docker