05. 容器资源管理

2023-09-07 12:59:53 浏览数 (2)

1、前言

通常情况下,我们一台宿主机上会同时启动多个Docker容器,而在默认情况下,Docker是没有限制其运行的容器所使用的硬件资源,比如CPU,内存,IO等。而在实际环境中,往往一个容器的负载过高,会占用宿主机的大部分资源,会导致其他容器的访问资源被抢占,而出现响应超时或无法响应等情况。

因此,我们往往会对同时启动的Docker容器做资源的分配和管理。这就是我们今天要说的容器资源管理。

2、CGroup

熟悉Linux的应该知道,Linux内核提供了一组为cgroup(Controller Group)的进程,通过这些进程可以限制应用对资源的使用,如CPU,内存等。通过cgroup可以对系统资源做精细化控制,例如实现对每个容器使用的CPU比率进行限制。

Linux CGroup主要提供了几种功能:

  • Resource Limitation:限制资源的使用,如CPU,内存的上限。
  • Prioritization:应用的优先级控制,如控制任务的调度。
  • Accounting:应用的审计和统计,例如实现应用的计费。
  • Control:实现对应用的控制,例如应用的挂起,恢复和执行等。

2.1、是否开启CGroup

代码语言:javascript复制
cat /boot/config-3.10.0-1160.el7.x86_64 |grep CGROUP

如果相关参数是y,表示已经启动了Linux CGroup,默认是开启的。

2.2、Linux CGroup限制资源能使用

2.2.1、创建一个demo

创建一个high_cpu.java文件。

代码语言:javascript复制
touch high_cpu.java

编写一段死循环代码。

代码语言:javascript复制
class HighCpu {
    public static void main(String args[]) {
        int i=0;
        while(true){
            i  ;
        }
    }
}

再编译执行他。

代码语言:javascript复制
javac high_cpu  
nohup java HighCpu &

执行完观察cpu占用情况。

代码语言:javascript复制
htop

我这里启了两个,所以两个进程。但是不影响我们观测,可以看到进程3999的CPU使用率已经接近100%。

安装htop步骤:

yum -y install epel-release.noarch

yum -y install htop

2.2.2、CGroup限制CPU使用

1)首先进入系统cgroup目录下。

代码语言:javascript复制
cd /sys/fs/cgroup/ 
ls

可以看到里面有很多熟悉的资源相关文件,如cpu,memory,blkio等。

没错,我们要限制cpu使用,当然是进入到cpu/目录。

代码语言:javascript复制
cd spu/
# 创建我们自己的资源隔离脚本,
mkdir mycpu
cd mycpu
ls

可以看到在里面默认生成很多cpu相关的脚本文件。

我们着重看cpu.cfs_quota_us。

代码语言:javascript复制
cat cpu.cfs_quota_us

里面的值为-1,则表示不限制cpu使用。

我们修改他的值为2000,也就是限制20%阈值。

代码语言:javascript复制
echo 20000 > cpu.cfs_quota_us

#同时把我们上面的进程号(3999)写进tasks文件
echo 3999 > tasks

我们再htop观察下cpu占用,可以看到CPU使用已经成功降到了20%的上限。

2.3、Linux CGroup限制内存使用

同上面的CPU限制,内存限制也类似。

代码语言:javascript复制
cd /sys/fs/cgroup/memory
mkdir mymem
cd mymem
more memory.limit_in_bytes 

可以看到这个值很大,表示对内存没有进行限制。

同样我们可以通过配置进行调整。

代码语言:javascript复制
echo 10m > memory.limit_in_bytes

#同时把我们上面的进程号(3999)写进tasks文件
echo 3999 > tasks

这样,内存使用就限制了10m可用。

2.4、Linux CGroup限制IO

代码语言:javascript复制
cd /sys/fs/cgroup/blkio
mkdir myio
cd myio
echo '8:0 1048576' > blkio.throttle.read_bps_device

#同时把我们上面的进程号(3999)写进tasks文件
echo 3999 > tasks

上面的"8:0"是当前需要限制的设备号。如要查看/dev/sda磁盘的设备号,可以使用ls -l /dev/sda。

3、Docker对资源的管理

为什么前面说了那么多Linux CGroup对资源的管理?因为Docker是构建在Linux基础上的,因此Docker就是利用Linux CGroup来实现对资源的控制。那么有了前面CGroup的认识,我们接下来学习Docker资源管理就容易很多。

3.1、Docker对CPU的限制

Docker引擎可以通过-c或--cpu-shares来为每个容器分配一个“CPU使用的权重”。该权重与实际的处理速度无关,每个容器默认有1024个CPU配额权重。

如果启动了两个容器,并且两个都使用默认的权重值 1024,则 Docker 引擎将把 CPU使用率平均分配给这两个容器,即这两个容器各自占用 50%的 CPU使用率。

但是,如果给容器 A分配的是 1024 权重,而给容器 B分配的是 512 权重,则会发现容器A使用CPU的比例比容器B使用 CPU的比例多一倍。

3.1.1、构建一个镜像

创建一个Dockerfile文件,这里直接使用我们前面用过的例子:

代码语言:javascript复制
# 指定基础镜像作为该容器的基础环境,如springboot应用最起码得有jdk环境
FROM openjdk:8

# 执行维护者的信息
MAINTAINER shamee csdn peng793049488

# 创建一个存放该工程的目录
RUN mkdir -p /data/project
ADD target/dockerfile-springboot-1.0-SNAPSHOT.jar /data/project/dockerfile-springboot-1.0-SNAPSHOT.jar

# 对外暴露一个8899端口
EXPOSE 8899

# 执行启动
ENTRYPOINT ["/bin/sh", "-c", "java -jar /data/project/dockerfile-springboot-1.0-SNAPSHOT.jar"]

使用docker build构建镜像:

代码语言:javascript复制
docker build -t docker_cgroup .   

构建完,便可以看到我们的镜像docker_cgroup。

3.1.2、构建两个容器

代码语言:javascript复制
# 第一个容器, CPU默认(1024)
docker run -d docker_cgroup --cpu 4 --name=cpu_1024

# 第二个容器, CPU配额权重512
docker run -d  -c 512 docker_cgroup --cpu 4  --name=cpu_512

3.1.3、查看CPU使用率

通过命令:

代码语言:javascript复制
docker stats

可以看到CPU的占用情况,设置1024权重的CPU占用率比512的高将近一倍。

docker stats 命令可以查看容器的CPU,内存,IO等分配,使用情况。下面的内存验证和IO验证均可以使用该命令查看。

除此以外,还可以设置以下参数,直接绑定CPU核心数:

代码语言:javascript复制
# 表示使用CPU0,1,2核 
--cpuset-cpus=0,1,2

3.2、Docker对内存的限制

同上面CPU的管理,Docker引擎支持通过-m参数来设定容器所使用的内存。

如:

代码语言:javascript复制
docker run -it xxx -m 256m

-m 256m表示限制容器使用的内存大小为256m。验证方式可以类似上面CPU管理方式,可以直接使用docker stats来查看。这里就不赘述。

3.3、Docker对IO的限制

对I/O的限制,可以使用参数:

代码语言:javascript复制
# 这里是限制容器写入速度为1MB/s 
docker run -it xxx --device-write-bps /dev/sda:1mb

其他参数:

参数名称

说明

--blkio-weight

可以通过--blkio-weight 修改容器 blkio 的权重,权重值为 10~1000

--blkio-weight-device weighted-device

指定某个设备的权重

--device-read-bps throttled-device

按每秒读取块设备的数据量设定上限

--device-read-iops throttled-device

按照每秒读操作的次数设定上限

--device-write-bps throttled-device

按每秒写入块设备的数据量设定上限

--device-write-iops throttled-device

按照每秒写操作的次数设定上限

3.4、查看Docker的资源配置

可以使用:

代码语言:javascript复制
docker inspect <容器ID或名称>

来查看容器的具体配置情况信息。

0 人点赞