如果多个容器同时read/write节点上的一块磁盘,如何对每个容器的read/write操作限速,以防止其相互干扰、相互竞争。
cgroup v1的blkio子系统,可以限制磁盘的I/O。
一. 磁盘读写的指标
衡量磁盘读写的常见指标:
- IOPS(Input/Output Operations per Second): 每秒读写磁盘的次数;
- Throughput(吞吐量): 每秒读写磁盘的数据量,也称为带宽(BandWidth);
Throughput = 数据块大小 * IOPS
在IOPS固定的情况下,读写的数据块越大,吞吐量也越大。
二. cgroup v1的blkio子系统
blkio cgroup的虚拟文件系统挂载点/sys/fs/cgroup/blkio/,包含以下参数:
- blkio.throttle.read_iops_device:读IOPS限制;
- blkio.throttle.read_bps_device:读吞吐量限制;
- blkio.throttle.write_iops.device:写IOPS限制;
- blkio.throttle.write_bps_device:写吞吐量限制;
比如,限制容器对磁盘/dev/vdb的写吞吐量 <= 10MB/s:
## 1.首先拿到/dev/vdb的主次设备号
# 其中 252:16是/dev/vdb的主次设备号
# ls -l /dev/vdb -l
brw-rw---- 1 root disk 252, 16 Nov 2 08:02 /dev/vdb
## 2.然后写cgroup
echo "252:16 10485760" > $CGROUP_CONTAINER_PATH/blkio.throttle.write_bps_device
可以使用fio工具,在容器中进行验证:
docker exec fio_test1 fio -direct=1 -rw=write -ioengine=libaio -bs=4k -size=100MB -numjobs=1 -name=/tmp/fio_test1.log
值得注意的是:
Cgroupv1 blkio只能对Direct I/O进行限速,不能对Buffered I/O进行限制。
三. Direct I/O 与 Buffered I/O
Direct I/O和Buffered I/O发生在用户 写 磁盘文件时。
Direct I/O:
- 通过Linux内核的filesystem --> block layer --> disk driver --> disk hardware;
Buffered I/O:
- 用户进程将数据写入Page cache后就返回了;
- Linux内核线程把内存中的数据flush到磁盘;
在Linux中,基于性能考虑,绝大多数的应用都使用Buffered I/O模式。
四. 为什么cgroup v1 blkio不能限制Buffered I/O
对下图中的进程 pid_y 的cgroup进行限制,它分别属于memory cgroup 和 blkio cgroup:
在blkio cgroup对 pid_y 做磁盘I/O限制的时候,blkio不会关心:
- pid_y 用了哪些内存,哪些属于Page cache,何时flush到磁盘;
- pid_y 中的Page cache被flush到磁盘时,由于是内核线程执行flush,产生的磁盘I/O不被计算到进程 pid_y上;
也就是说:
cgroup v1 blkio独立与memory子系统,它无法统计由Page cache刷入磁盘的I/O;
即 cgroup v1 blkio不能对Buffered I/O进行限速;
五. cgroup v2解决这一问题
cgroup v2解决了不能对Buffered I/O进行限速的问题。
在cgroup v2中:
- 一个进程属于一个控制组;
- 每个控制组可以定义多个子系统;
上图中,pid_y 属于控制组group2,而group2同时配置了io和memory子系统;
在此情况下,cgroup对 pid_y 的磁盘读写进行限速的时候,就可以知道 pid_y 写入Page Cache的数据量,这样Buffered I/O的磁盘限速就实现了。
也就是说,在cgroup v2中:
内核将Page cache flush到磁盘产生的I/O也会被计算到进程的I/O中;
对磁盘限速时,可以同时限制Directed I/O和Buffered I/O;
值得注意的是,目前runC、containerd和kubernetes刚开始支持cgroup v2,生产环境上cgroup v1迁移到cgroup v2还需要一个过程。
参考:
1.blkio的文档:https://www.kernel.org/doc/Documentation/cgroup-v1/blkio-cont...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。