程序锅

  • 首页
  • 分类
  • 标签
  • 归档
  • 关于

  • 搜索
基础知识 Etcd LeetCode 计算机体系结构 Kubernetes Containerd Docker 容器 云原生 Serverless 项目开发维护 ELF 深入理解程序 Tmux Vim Linux Kernel Linux numpy matplotlib 机器学习 MQTT 网络基础 Thrift RPC OS 操作系统 Clang 研途 数据结构和算法 Java 编程语言 Golang Python 个人网站搭建 Nginx 计算机通用技术 Git

容器 | 容器文件的 Quota

发表于 2021-07-11 | 分类于 容器 | 0 | 阅读次数 1802

1. 容器文件的 Quota

容器虽然有自己的文件系统,但是容器在容器文件系统(overlayfs)中写入的数据,最终还是存到宿主机的磁盘上,因为容器文件系统其实只是宿主机上的一个目录而已。那么,这不仅影响容器本身,还会影响宿主机。

一种方式是通过给容器挂载一个 volume,这个 volume 可以是选择文件啥的。并且,这也是推荐的方式,因为对于容器来说,如果有大量的写操作是不建议写入容器文件系统的,一般是需要给容器挂载一个 volume,用来满足大量的文件读写。

第二种方式是对容器写入 OverlayFS 的数据量做限制,比如只允许一个容器写 100MB 的数据。OverlayFS 文件系统的特性中没有直接限制文件写入量的特性。那么,我们可以从 overlay 的本质出发来进行限制。因为 overlayFS 是通过 lowerdir 和 upperdir 两层目录联合挂载来实现的,lowerdir 是只读的,数据只会写在 upperdir 中。那么,其实我们只要通过限制 upperdir 目录容量的方式,就可以限制一个容器 OverlayFS 根目录的写入数据量。

那么宿主机上的文件系统是否支持对一个目录限制容量呢?其实 Linux 上最常用的两个文件系统 XFS 和 ext4,它们有一个特性 Quota 可以限制一个目录的使用量。

需要注意的是:ext4 自身支持 project quota 功能(Linux 4.5 版本之后)。但是,overlay2 over ext4 不支持 project quota 功能。

官方文档也有提到:https://docs.docker.com/engine/reference/commandline/run/#set-storage-driver-options-per-container

For the overlay2 storage driver, the size option is only available if the backing fs is xfs and mounted with the pquota mount option.

1.1. XFS Quota

在 Linux 系统里的 XFS 文件系统缺省都有 Quota 的特性,这个特性可以为 Linux 系统里的一个用户(user),一个用户组(group)或者一个项目(project)来限制它们使用文件系统的额度(quota),也就是限制它们可以写入文件系统的文件总量。由于同一个用户或者用户组可以操作多个目录,多个用户或者用户组也可以操作同一个目录,假如对一个用户或者用户组的限制,其实很难实现对一个目录的限制。那么对一个目录的限制应该使用 projetc 方式。

  • 首先我们要使用 XFS Quota 特性,必须在文件系统挂载的时候加上对应的 Quota 选项,比如我们目前需要配置 Project Quota,那么这个挂载参数就是"pquota"。并且对于根目录来说,这个参数还必须作为一个内核启动的参数"rootflags=pquota",这样设置就可以保证根目录在启动挂载的时候,带上 XFS Quota 的特性并且支持 Project 模式。

    我们可以从 /proc/mounts 信息里,看看根目录是不是带"prjquota"字段。如果里面有这个字段,就可以确保文件系统已经带上了支持 project 模式的 XFS quota 特性。

  • 之后的第一步是给目标目录打上一个 Project ID,这个 ID 最终是写到目录对应的 inode 上。那么一旦目录打上这个 ID 之后,在这个目录下的新建的文件和目录也都会继承这个 ID。

  • 第二步,在 XFS 文件系统中,我们需要给这个 project ID 设置一个写入数据块的限制。有了 ID 和限制值之后,文件系统就可以统计所有带这个 ID 文件的数据块大小总和,并且与限制值进行比较。一旦所有文件大小的总和达到限制值,文件系统就不再允许更多的数据写入了。

我们可以使用 XFS 文件系统自带的工具 xfs_quota 来完成上述效果:

  • 首先新建的目录 /tmp/xfs_prjquota,由于我们想对它做 Quota 限制。所以在这里要对它打上一个 Project ID。在这里就通过 xfs_quota 这条命令,我们给 /tmp/xfs_prjquota 打上 Project ID 值 101,这个 101 就是个 ID 标识。

    # mkdir -p  /tmp/xfs_prjquota
    # xfs_quota -x -c 'project -s -p /tmp/xfs_prjquota 101' /
    Setting up project 101 (path /tmp/xfs_prjquota)...
    Processed 1 (/etc/projects and cmdline) paths for project 101 with recursion depth infinite (-1).
    
  • 之后,还是使用 xfs_quota 命令,对 101(我们刚才建立的这个 Project ID)做 Quota 限制。命令里面的"-p bhard=10m 101"就代表限制 101 这个 project ID,限制它的数据块写入量不能超过 10MB。

    # xfs_quota -x -c 'limit -p bhard=10m 101' /
    
  • 做好限制之后,我们可以尝试往 /tmp/xfs_prjquota 写入 20MB 数据。可以看到,执行 dd 写入命令,就会有个出错返回信息"No space left on device"。这表示已经不能再往这个目录下写入数据了,而最后写入数据的文件 test.file 大小也停留在了 10MB。

    # dd if=/dev/zero of=/tmp/xfs_prjquota/test.file bs=1024 count=20000
    dd: error writing '/tmp/xfs_prjquota/test.file': No space left on device
    10241+0 records in
    10240+0 records out
    10485760 bytes (10 MB, 10 MiB) copied, 0.0357122 s, 294 MB/s
    
    # ls -l /tmp/xfs_prjquota/test.file
    -rw-r--r-- 1 root root 10485760 Oct 31 10:00 /tmp/xfs_prjquota/test.file
    

1.2. Docker 容器中的限制实现

Docker 也已经实现了限流功能,也就是用 XFS Quota 来限制容器的 OverlayFS 大小。在用 docker run 启动容器的时候,加上一个参数 --storage-opt size= ,就能限制住容器 OverlayFS 文件系统可写入的最大数据量了。同时使用 df -h 命令查看的时候,看到的容量其实是做了限制的。

Docker 里 SetQuota() 函数(https://github.com/moby/moby/blob/19.03/daemon/graphdriver/quota/projectquota.go#L155)就是用来实现 XFS Quota 限制的,我们可以看到它里面最重要的两步,分别是 setProjectID() 和 setProjectQuota()。而这两个函数里分别调用了 ioctl() 和 quotactl() 这两个系统调用来修改内核中 XFS 的数据结构,从而完成 project ID 的设置和 Quota 值的设置。

1.3. kubernetes 中的实现

k8s 1.14 开始,默认开启 LocalStorageCapacityIsolation,可以通过限制resources.limits.ephemeral-storage 和resources.requests.ephemeral-storage 来保护宿主机 rootfs了。k8s 通过du来检查ephemeral-storage相关volume/目录的大小,然后如果超出limit就evict pod。

du 的开销比较大, 并且 evict pod 只适合 stateless pod,所以最新的 k8s,可能是在用filesystem quota来限制emptyDir的大小了。

巨人的肩膀

  1. 极客时间.《容器实战》
卷死我
dawnguo 微信支付

微信支付

dawnguo 支付宝

支付宝

  • 本文作者: dawnguo
  • 本文链接: /archives/141
  • 版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0 许可协议。转载请注明出处!
# 容器
容器 | Containerd 完整介绍
容器 | 容器网络
  • 文章目录
  • 站点概览
dawnguo

dawnguo

215 日志
24 分类
37 标签
RSS
Creative Commons
© 2018 — 2025 程序锅
0%