Docker限制容器的Block IO
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Docker限制容器的Block IO相关的知识,希望对你有一定的参考价值。
参考技术A Block IO指的是磁盘的读写,docker可以通过设置权重以及限制bps和iops的方式控制容器读写磁盘的带宽。通过命令
docker help run | grep -E ‘bps|IO’
可以查询block IO的选项参数。
主要参数有:
–blkio-weight:容器默认磁盘IO的加权值,有效值范围为10-1000。
–blkio-weight-device: 针对特定设备的IO加权控制。其格式为DEVICE_NAME:WEIGHT
–device-read-bps:限制此设备上的读速度(bytes per second),单位可以是KB、MB或者GB。
–device-read-iops:通过每秒读IO次数来限制指定设备的读速度。
–device-write-bps :限制此设备上的写速度(bytes per second),单位可以是KB、MB或者GB。
–device-write-iops:通过每秒写IO次数来限制指定设备的写速度。
接下来将介绍每一个命令的具体使用方法。
1、–blkio-weight、–blkio-weight-device
使用以下命令创建容器
docker run -it --rm --blkio-weight 100 centos /bin/bash
采用docker inspect 命令查看生成的容器的元数据。
2、–device-write-bps、–device-read-bps
2.1 --device-write-bps
使用以下命令创建容器,并限制容器的写入速度是上限30MB/s
docker run -it --rm --device-write-bps /dev/sda:30MB centos
采用docker inspect命令对容器数据进行查看,发现设置成功。
在容器内采用dd命令对容器的写入速度进行测试,验证其读写速度在30M左右,其中oflag=direct 指定用 direct IO 方式写文件,这样 --device-write-bps 才能生效。
如果不采用oflag=direct方式,进行测试,发现速度为2.0GB/s,也间接说明成功限制容器写入速度。
2.2 --device-read-bps
使用以下命令创建容器,并限制容器的读出数据速度是上限30MB/s
docker run -it --rm --device-read-bps /dev/sda:30MB centos
同样,采用docker inspect命令对容器数据进行查看,发现设置成功。
在容器内采用dd命令对容器的写入速度进行测试,验证其读写速度在30M左右。首先需要生成读取数据文件test.out。
time dd if=/dev/zero of=test.out bs=1M count=256
然后再运行dd命令,对容器读取数据速度进行测试,和–device-write-bps类似,iflag=direct是对–device-read-bps的读取速度进行限制。
time dd if=test.out of=/dev/zero bs=1M iflag=direct
在不加iflag=direct的情况下进行测试,发现速度为7.9GB/s,远远大于30MB/s,从而可以看出成功限制容器读取数据的速度。
3、–device-write-iops,–device-read-iops
–device-write-iops,–device-read-iops是通过限制容器每秒读取IO的次数来限制容器的读写速度。
3.1 --device-write-iops
使用以下命令创建容器,并限制容器的每秒写入数据次数不超过30次。
docker run -it --rm --device-write-iops /dev/sda:30 centos
同样,采用docker inspect命令对容器数据进行查看,发现设置成功。
在容器内采用dd命令对容器的写入速度进行测试,写入速度限制到了15.8MB/s。
time dd if=/dev/zero of=test.out bs=1M count=256 oflag=direct
在不加oflag-direct的时候进行测试,速度为2.4GB/s,说明限制容器写入次数成功。
3.2 --device-read-iops
使用以下命令创建容器,并限制容器的每秒读取数据次数不超过30次。
docker run -it --rm --device-read-iops /dev/sda:30 centos
同样,采用docker inspect命令对容器数据进行查看,发现设置成功。
然后在运行dd命令对容器每秒读取io次数进行查看,命令格式通–device-read-bps,接下来将不再进行赘述,直接上图,读取速度为15.8MB/s。
在不加iflag=direct的情况下进行测试,发现读取速度为9.0GB/s远大于15.8MB/s,说明限制容器读取次数成功。
————————————————
原文链接: https://blog.csdn.net/weixin_44713619/article/details/105728147
Docker-安全CPU限额内存限制IO限制安全加固
目录
一、Docker安全介绍
Docker容器的安全性,很大程度上依赖于Linux系统自身,评估Docker的安全性时,主要考虑以下几个方面
Linux内核的命名空间机制提供的容器隔离安全
Linux控制组机制对容器资源的控制能力安全。
Linux内核的能力机制所带来的操作权限安全
Docker程序(特别是服务端)本身的抗攻击性。
其他安全增强机制对容器安全性的影响。
1.命名空间隔离的安全
就是当docker run启动一个容器时,Docker将在后台为容器创建一个独立的命名空间。命名空间提供了最基础也最直接的隔离。
与虚拟机方式相比,通过Linux namespace来实现的隔离不是那么彻底。
[root@server1 ~]# docker run -d --name demo nginx
[root@server1 ~]# docker inspect demo | grep Pid
我们在系统进程里进入pid里查看一下信息!
cd /proc/8980/
cd ns/
ls
2.控制组资源控制的安全
当docker启动一个容器时,Docker将在后台为容器创建一个独立的控制组策略集合。
在 /sys/fs/cgroup 下面有很多诸如 cpuset、cpu、 memory 这样的子目录,也叫子系统。
可以在memory内存看到运行的容器:
cd /sys/fs/cgroup/memory/docker/
ls
可以cpu中看到运行的容器:
二、容器资源控制
Linux Cgroups 的全称是 Linux Control Group。
我们只能限制一个进程使用的资源上限:包括 CPU、内存、磁盘、网络带宽等等。
Linux Cgroups 给用户暴露出来的操作接口是文件系统。
它以文件和目录的方式组织在操作系统的 /sys/fs/cgroup 路径下。
在 /sys/fs/cgroup 下面有很多诸如 cpuset、cpu、 memory 这样的子目录,也叫子系统。
在每个子系统下面,为每个容器创建一个控制组(即创建一个新目录)。
控制组下面的资源文件里填上什么值,就靠用户执行 docker run 时的参数指定。
1.内存限制
容器可用内存包括两个部分:物理内存和swap交换分区。
–m 设置内存使用限额
docker run -it --m 200M -d --name demo nginx
cd /sys/fs/cgroup/memory/docker/ #可以看到打开的进程
我们进入到刚才的容器中,看到memory.limit_in_bytes内容是内存限制
cd *************
cat memory.limit_in_bytes
但是刚才的demo镜像不能够查看空间,所以我们需要换一个镜像
docker run -m 200M -it --rm busyboxplus
free -m
我们专门创建一个用来测试内存的目录x1
cd /sys/fs/cgroup/memory
mmkdir x1
cd x1/
ls
我们可以发现,创建好的目录x1里面拥有很多配置文件,因为它直接继承上级目录下的所有文件!
然后我们限制上传的内存最大为200M
echo 209715200 > memory.limit_in_bytes
cat memory.limit_in_bytes
下载libcgroup-tools工具
yum install -y libcgroup-tools.x86_64
我们创建指定大小的空间,但是我们发现前面已经设置了最大内存为200M,但是为什么能创建300M的空间呢?
cgexec -g memory:x1 dd if=/dev/zero of=bigfile bs=1M count=300
那是因为它占用了我们的swap分区的大小!
我们每次创建一定大小空间之后,用free -m查看一下内存情况就明白了!
我们的mem空间并没有使用有效空间都是1432如下图,但是swap空间使用多了100M,这下刚才的疑惑就解决了!!
删除创建的bigfile文件,那么我们是不是把swap分区关闭,创建300M空间就会失败呢?
rm -f bigfile
swapoff -a
free -m
cgexec -g memory:x1 dd if=/dev/zero of=bigfile bs=1M count=300
果然没有了swap分区之后,创建300M分区直接报错!(killed)
但是在实际生产中,swap分区会使用,不能够关闭的!!
所以我们重新打开swap分区,删除bigfile文件!寻找别的方法来解决刚刚的问题:
swapon -a
swapon -s
free -m
rm -f bigfile
我们进入刚才的设置内存大小的路径下:
我们把200M的限制给内存+swap一共200M ,刚才的问题不就解决了马?
cd /sys/fs/cgroup/memory/x1
echo 209715200 > memory.memsw.limit_in_bytes %内存+swap一共给200M
cd /dev/shm
cgexec -g memory:x1 dd if=/dev/zero of=bigfile bs=1M count=300
cgexec -g memory:x1 dd if=/dev/zero of=bigfile bs=1M count=100
du -h *
cgexec -g memory:x1 dd if=/dev/zero of=bigfile bs=1M count=200
du -h *
我们可以看到创建300M空间直接失败!
创建100M成功,创建200M也不行,只能创建199M!
2.cpu限额
我们需要创建一个专门用于测试cpu的目录x2
cd /sys/fs/cgroup/cpu
mmkdir x2
cd x2/
ls
cpu.shares 不是限制进程能使用的绝对的 cpu 时间,而是控制各个组之间的配额!
cpu.shares,表示 CPU Cgroup 对于控制组之间的CPU 分配比例,缺省值是1024
例如:
group3 中的cpu.shares 是1024,group4 中的 cpu.shares 是 3072,那么 group3:group4 = 1:3
我们先设置cpu.shares的配额为100,应该是10/100的cpu损耗!
然后使用dd命令测试cpu的负载情况
echo 100 > cpu.shares
dd if=/dev/zero of=/dev/null &
输入top进入查看cpu消耗,是100,这不合适!是因为只有一个进程所以是100,所以我们还需要再创建一个压力来测试
我们把cpu线程PID写入tasks中
cat tasks
echo 10053 > tasks
我们再测试使用一个损耗打入后台
dd if=/dev/zero of=/dev/null &
top 查看cpu消耗都是100,这还是不合适!
top
因为我们的虚拟机是双cpu的可以独立工作,所以可以关闭一个cpu
cd /sys/devices/system/cpu/cpu1
cat online
echo 0 > online
此时查看top
一个cpu稳定在10左右,另一个90左右
但是实际生产中不能关闭另一个cpu,行不通!
重新打开cpu1,恢复cpu的配额
echo 1 > online
echo 1024 > cpu.shares
cpu.cfs_period_us,它是CFS算法的一个调度周期,一般值是 100000十万,单位是微秒,就是 100ms
cpu.cfs_quota_us,它表示CFS算法中,在一个调度周期里这个控制组被允许的运行时间,比如这个值为 50000时,就是 50ms。
如果用这个值cpu.cfs_quota_us除以调度周期cpu.cfs_period_us,50ms/100ms=0.5,表示这个控制组被允许使用的CPU最大配额就是0.5个CPU
cat cpu.cfs_quota_us
cat cpu.cfs_period_us
echo 20000 > cpu.cfs_quota_us
此时我们这样设置就是允许使用的cpu为0.2个cpu!!
top
查看看到cpu使用为20和设置的效果一样!
注意:追加是>>
如果这个时候我们把另一个cpu也追加入到线程里面
echo 10066 >> tasks
那么这个时候就是两个进程去争夺20的cpu配额
所以每个进程分的10!!如下图:
3.Block IO限制(磁盘IO)
–device-write-bps限制写设备的bps
目前的block IO限制只对direct IO有效。(不使用文件缓存)
docker run -it --rm --device-write-bps /dev/vda:30MB rhel7 bash
dd if=/dev/zero of bigfile bs=1M count=200 oflag=direct
dd if=/dev/zero of bigfile bs=1M count=200
我们可以看到加上oflag=direct参数速度为30MB左右,不加参数,速度为2。6G就差别很大!!
三.docker安全加固
利用LXCFS增强docker容器隔离性和资源可见性
[root@server1 ~]# yum install lxcfs-2.0.5-3.el7.centos.x86_64.rpm -y
[root@server1 ~]#docker pull ubuntu
[root@server1 ~]# lxcfs /var/lib/lxcfs & ##运行
[root@server1 lxcfs]# docker run -it -m 256m \\
> -v /var/lib/lxcfs/proc/cpuinfo:/proc/cpuinfo:rw \\
> -v /var/lib/lxcfs/proc/diskstats:/proc/diskstats:rw \\
> -v /var/lib/lxcfs/proc/meminfo:/proc/meminfo:rw \\
> -v /var/lib/lxcfs/proc/stat:/proc/stat:rw \\
> -v /var/lib/lxcfs/proc/swaps:/proc/swaps:rw \\
> -v /var/lib/lxcfs/proc/uptime:/proc/uptime:rw \\
> ubuntu
我们可以看到mem和swap的大小一致!
我们先运行一个普通的容器
发现控制网络的时候,被拒绝了!
docker run -it --rm busyboxplus
ip link set down eth0
1.设置特权级运行的容器
–privileged=true
有的时候我们需要容器具备更多的权限,比如操作内核模块,控制swap交换分区,挂载USB磁盘,修改MAC地址等。
docker run -it --rm --privileged=true busyboxplus
ip link set down eth0
这次控制网络eth0成功了!
2.设置容器白名单
–cap-add
–privileged=true 的权限非常大,接近于宿主机的权限,为了防止用户的滥用,需要增加限制,只提供给容器必须的权限。此时Docker 提供了权限白名单的机制,使用–cap-add添加必要的权限。
当我们运行容器给他一定的白名单时候,发现可以进行添加IP,删除IP操作!
docker run -it --rm --cap-add=NET_ADMIN busybox
/ # ip addr add 172.25.0.100/24 dev eth0
/ # ip addr del 172.25.0.100/24 dev eth0
进行添加IP:172.25.0.100
删除ip
以上是关于Docker限制容器的Block IO的主要内容,如果未能解决你的问题,请参考以下文章
限制容器的 Block IO - 每天5分钟玩转 Docker 容器技术(29)