3 种方法限制 K8s Pod 磁盘容量使用

容器在运行期间会产生临时文件、日志。如果没有任何配额机制,则某些容器可能很快将磁盘写满,影响宿主机内核和所有应用。

容器的临时存储,例如 emptyDir,位于目录/var/lib/kubelet/pods 下:

/var/lib/kubelet/pods/
└── ac0810f5-a1ce-11ea-9caf-00e04c687e45  # POD_ID├── containers│   ├── istio-init│   │   └── 32390fd7│   ├── istio-proxy│   │   └── 70ed81da│   └── zookeeper│       └── e9e21e59├── etc-hosts          # 命名空间的Host文件└── volumes            # Pod的卷├── kubernetes.io~configmap  # ConfigMap类型的卷│   └── istiod-ca-cert│       └── root-cert.pem -> ..data/root-cert.pem├── kubernetes.io~downward-api│   └── istio-podinfo│       ├── annotations -> ..data/annotations│       └── labels -> ..data/labels├── kubernetes.io~empty-dir # Empty类型的卷│   ├── istio-data│   └── istio-envoy│       ├── envoy-rev0.json│       └── SDS├── kubernetes.io~rbd       # RBD卷│   └── pvc-644a7e30-845e-11ea-a4e1-70e24c686d29 # /dev/rbd0挂载到这个挂载点├── kubernetes.io~csi       # CSI卷└── kubernetes.io~secret    # Secret类型的卷└── default-token-jp4n8├── ca.crt -> ..data/ca.crt├── namespace -> ..data/namespace└── token -> ..data/token

持久卷的挂载点也位于/var/lib/kubelet/pods 下,但是不会导致存储空间的消耗

容器的日志,存放在/var/log/pods 目录下。

使用 Docker 时,容器的 rootfs位于/var/lib/docker 下,具体位置取决于存储驱动。

Pod 驱逐机制

磁盘容量不足触发的驱逐

具体细节参考:/kubernetes-study-note#out-of-resource[1]

当不可压缩资源(内存、磁盘)不足时,节点上的 Kubelet 会尝试驱逐掉某些 Pod,以释放资源,防止整个系统受到影响。

其中,磁盘资源不足的信号来源有两个:

  1. imagefs:容器运行时用作存储镜像、可写层的文件系统

  2. nodefs:Kubelet 用作卷、守护进程日志的文件系统

当 imagefs 用量到达驱逐阈值,Kubelet 会删除所有未使用的镜像,释放空间。

当 nodefs 用量到达阈值,Kubelet 会选择性的驱逐 Pod(及其容器)来释放空间。

本地临时存储触发的驱逐

较新版本的 K8S 支持设置每个 Pod 可以使用的临时存储的 request/limit,驱逐行为可以更具有针对性。

如果 Pod 使用了超过限制的本地临时存储,Kubelet 将设置驱逐信号,触发 Pod 驱逐流程:

  1. 对于容器级别的隔离,如果一个容器的可写层、日志占用磁盘超过限制,则 Kubelet 标记 Pod 为待驱逐

  2. 对于 Pod 级别的隔离,Pod 总用量限制,是每个容器限制之和。如果各容器用量之和+Pod 的 emptyDir 卷超过 Pod 总用量限制,标记 Pod 为待驱逐

从编排层限制

从 K8S 1.8 开始,支持本地临时存储(local ephemeral storage),ephemeral 的意思是,数据的持久性(durability)不做保证。临时存储可能 Backed by 本地 Attach 的可写设备,或者内存。

Pod 可以使用本地临时存储来作为暂存空间,或者存放缓存、日志。Kubelet 可以利用本地临时存储,将 emptyDir 卷挂载给容器。Kubelet 也使用本地临时存储来保存节点级别的容器日志、容器镜像、容器的可写层

Kubelet 会将日志写入到你配置好的日志目录,默认 /var/log。其它文件默认都写入到 /var/lib/kubelet。在典型情况下,这两个目录可能都位于宿主机的 rootfs 之下。

Kubernetes 支持跟踪、保留/限制 Pod 能够使用的本地临时存储的总量。

限制 Pod 用量

打开特性开关:LocalStorageCapacityIsolation,可以限制每个 Pod 能够使用的临时存储的总量。

注意:以内存为媒介(tmpfs)的 emptyDir,其用量计入容器内存消耗,而非本地临时存储消耗。

使用类似限制内存、CPU 用量的方式,限制本地临时存储用量:

spec.containers[].resources.limits.ephemeral-storage
spec.containers[].resources.requests.ephemeral-storage

单位可以是 E, P, T, G, M, K,或者 Ei, Pi, Ti, Gi, Mi, Ki(1024)。

下面这个例子,Pod 具有两个容器,每个容器最多使用 4GiB 的本地临时存储:

apiVersion: v1
kind: Pod
metadata:name: frontend
spec:containers:- name: dbimage: mysqlenv:- name: MYSQL_ROOT_PASSWORDvalue: "password"resources:requests:ephemeral-storage: "2Gi"limits:ephemeral-storage: "4Gi"- name: wpimage: wordpressresources:requests:ephemeral-storage: "2Gi"limits:ephemeral-storage: "4Gi"

对 Pod 用量的监控

不监控

如果禁用 Kubelet 对本地临时存储的监控,则 Pod 超过 limit 限制后不会被驱逐。但是,如果磁盘整体上容量太低,节点会被打上污点,所有不能容忍此污点的 Pod 都会被驱逐。

周期性扫描

Kubelet 可以执行周期性的扫描,检查 emptyDir 卷、容器日志目录、可写容器层,然后计算 Pod/容器使用了多少磁盘。

这个模式下有个问题需要注意,Kubelet不会跟踪已删除文件的描述符。也就是说,如果你创建一个文件,打开文件,写入 1GB,然后删除文件,这种情况下 inode 仍然存在(直到你关闭文件),空间仍然被占用,但是 Kubelet 却没有算这 1GB.

Project Quotas

此特性在 1.15+处于 Alpha 状态。

Project quotas 是 Linux 操作系统级别的特性,用于在目录级别限制磁盘用量。只有本地临时存储(例如 emptyDir)的后备(Backing)文件系统支持 Project quotas,才可以使用该特性。XFS、ext4 都支持 Project quotas。

K8S 将占用从 1048576 开始的 Project ID,占用中的 ID 注册在/etc/projects、/etc/projid 文件中。如果系统中其它进程占用 Project ID,则也必须在这两个文件中注册,这样 K8S 才会改用其它 ID。

Quotas 比周期性扫描快,而且更加精准。当一个目录被分配到一个 Project 中后,该目录中创建的任何文件,都是在 Project 中创建的。为了统计用量,内核只需要跟踪 Project 中创建了多少 block 就可以了。

如果文件被创建、然后删除,但是它的文件描述符仍然处于打开状态,这种情况下,它仍然消耗空间,不会出现周期性扫描的那种漏统计的问题。

要启用 Project Quotas,你需要:

  1. XFS 文件系统默认支持,不需要操作

  2. ext4 文件系统,你需要在未挂载之前,启用:

    $ sudo tune2fs -O project -Q prjquota /dev/vda
    
  1. 开启 Kubelet 特性开关:LocalStorageCapacityIsolationFSQuotaMonitoring

  2. 确保文件系统支持 Project quotas:

  3. 确保文件系统挂载时,启用了 Project quotas。使用挂载选项 prjquota

inode 耗尽问题

有的时候,我们会发现磁盘写入时会报磁盘满,但是 df 查看容量并没有 100%使用,此时可能只是因为 inode 耗尽造成的。

当前 k8s 并不支持对 Pod 的临时存储设置 inode 的 limits/requests。

但是,如果 node 进入了 inode 紧缺的状态,kubelet 会将 node 设置为 under pressure,不再接收新的 Pod 请求。

从容器引擎限制

Docker 提供了配置项 --storage-opt,可以限制容器占用磁盘空间的大小,此大小影响镜像和容器文件系统,默认 10G。

你也可以在 /etc/docker/daemon.json 中修改此配置项:

{"storage-driver": "devicemapper","storage-opts": [// devicemapper"dm.basesize=20G",// overlay2"overlay2.size=20G",]
}

但是这种配置无法影响那些挂载的卷,例如 emptyDir。

从系统层限制

你可以使用 Linux 系统提供的任何能够限制磁盘用量的机制,为了和 K8S 对接,需要开发 Flexvolume 或 CSI 驱动。

磁盘配额

前文已经介绍过,K8S 目前支持基于 Project quotas 来统计 Pod 的磁盘用量。这里简单总结一下 Linux 磁盘配额机制。

配额目标

Linux 系统支持以下几种角度的配额:

  1. 在文件系统级别,限制群组能够使用的最大磁盘额度

  2. 在文件系统级别,限制单个用户能够使用的最大磁盘额度

  3. 限制某个目录(directory, project)能够占用的最大磁盘额度

前面 2 种配额,现代 Linux 都支持,不需要前提条件。你甚至可以在一个虚拟的文件系统上进行配额:

# 写一个空白文件
$ dd if=/dev/zero of=/path/to/the/file bs=4096 count=4096
# 格式化
...
# 挂载为虚拟文件系统
$ mount -o loop,rw,usrquota,grpquota /path/to/the/file /path/of/mount/point# 进行配额设置...

第 3 种需要较新的文件系统,例如 XFS、ext4fs。

配额角度

配额可以针对 Block 用量进行,也可以针对 inode 用量进行。

配额可以具有软限制、硬限制。超过软限制后,仍然可以正常使用,但是登陆后会收到警告,在 grace time 倒计时完毕之前,用量低于软限制后,一切恢复正常。如果 grace time 到期仍然没做清理,则无法创建新文件。

统计用量

启用配额,内核自然需要统计用量。管理员要查询用量,可以使用 xfs_quota 这样的命令,比 du 这种遍历文件计算的方式要快得多。

启用配额

在保证底层文件系统支持之后,你需要修改挂载选项来启用配额:

  1. uquota/usrquota/quota:针对用户设置配额

  2. gquota/grpquota:针对群组设置配额

  3. pquota/prjquota:针对目录设置配额

LVM

使用 LVM 你可以任意创建具有尺寸限制的逻辑卷,把这些逻辑卷挂载给 Pod 即可:

volumes:
- flexVolume:# 编写的flexVolume驱动放到# /usr/libexec/kubernetes/kubelet-plugins/volume/exec/kubernetes.io~lvm/lvmdriver: kubernetes.io/lvmfsType: ext4options:size: 30Givolumegroup: dockername: mnt
volumeMounts:- mountPath: /mntname: mnt

这需要修改编排方式,不使用 emptyDir 这种本地临时存储,还需要处理好逻辑卷清理工作。

Flexvolume 驱动的示例可以参考:/flexvolume-study-note#lvm[2]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/744724.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

学生时期学习资源同步-1 第一学期结业考试题6

原创作者:田超凡(程序员田宝宝) 版权所有,引用请注明原作者,严禁复制转载

C语言之文件操作(万字详解)

个人主页(找往期文章包括但不限于本期文章中不懂的知识点): 我要学编程(ಥ_ಥ)-CSDN博客 目录 前言 文件的打开和关闭 流和标准流 文件指针 文件的打开和关闭 文件的顺序读写 顺序读写函数介绍 fputc的使用 fgetc的使用 fput…

伪类和伪元素?

CSS 中的伪类和伪元素是两个不同的概念,它们都可以用来为元素添加一些特殊的样式或效果。 伪类(Pseudo-classes): 伪类是 CSS 中用于选择元素在特定状态下的关键字,常见的伪类有 :hover、:active、:focus、:checked 等…

轮趣 IMU N100 九轴 IMU 在 ROS 下安装驱动

本篇介绍如何在ROS环境中使用 WHEELTEC N100 惯导模块。 轮趣 IMU N100 的 ROS 驱动程序下载链接:轮趣 IMU 资料 - 坚果云 - 云盘|网盘|企业网盘|同步|备份|无限空间|免费网络硬盘|企业云盘 1、CP2102 固定串口号 1.1 、修改串口号 在 Windows 中需要把 WHEELTE…

【话题】人工智能迷惑行为大赏

随着ChatGPT热度的攀升,越来越多的公司也相继推出了自己的AI大模型,如文心一言、通义千问等。各大应用也开始内置AI玩法,如抖音的AI特效~在使用过程中往往会遇到一些问题,让你不得不怀疑,这真的是人工智能吗…

nslookup和dig命令的使用方法以及区别

nslookup和dig是两个在DNS查询中常用的命令工具,它们的使用方法有所不同。 nslookup命令的使用方法如下: 1.正向解析:直接输入 nslookup 域名,例如 nslookup www.baidu.com,即可查询指定域名的IP地址。 2.查询域名制定…

Nodejs 第五十四章(net)

net模块是Node.js的核心模块之一,它提供了用于创建基于网络的应用程序的API。net模块主要用于创建TCP服务器和TCP客户端,以及处理网络通信。 TCP(Transmission Control Protocol)是一种面向连接的、可靠的传输协议,用于…

Linux系统Docker部署Plik系统结合内网穿透实现公网访问本地文件

文章目录 1. Docker部署Plik2. 本地访问Plik3. Linux安装Cpolar4. 配置Plik公网地址5. 远程访问Plik6. 固定Plik公网地址7. 固定地址访问Plik 本文介绍如何使用Linux docker方式快速安装Plik并且结合Cpolar内网穿透工具实现远程访问,实现随时随地在任意设备上传或者…

php中register_shutdown_function 函数用法详解

register_shutdown_function 是PHP中的一个功能,用于在脚本执行完毕或调用exit()后执行特定函数。此功能自PHP 4起被引入,并且持续支持到PHP 8。 功能说明 通过register_shutdown_function(callable $callback, mixed ...$args)方法注册回调函数&#…

支小蜜校园防霸凌系统都可以使用在哪些地方

校园防霸凌系统,作为一种有效的预防和干预工具,近年来在全球范围内受到越来越多的关注和应用。该系统综合运用现代科技手段,旨在识别、预防和应对校园内可能发生的霸凌行为,为师生提供一个安全、和谐的学习和生活环境。那么&#…

ArrayList 和 LinkedList 有什么区别?

1、典型回答 ArrayList 和 LinkedList 是 Java 中常用的集合类,它们都实现了 List 接口,如下图所示: 但二者有以下几点不同: 1、底层数据结构实现不同: ArrayList 底层使用数组实现,它通过一个可调整大小…

力扣热题100_矩阵_73_矩阵置零

文章目录 题目链接解题思路解题代码 题目链接 73.矩阵置零 给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1: 输入:matrix [[1,1,1],[1,0,1],[1,1,1]] 输出&…

如何在Windows搭建WebDav服务,并外网可访问

目录 1. 安装IIS必要WebDav组件 2. 客户端测试 3. 使用cpolar内网穿透,将WebDav服务暴露在公网 3.1 打开Web-UI管理界面 3.2 创建隧道 3.3 查看在线隧道列表 4. 公网远程访问 4.1 浏览器访问测试 4.2 映射本地盘符访问 4.3 安装Raidrive客户端 总结&…

STM32第九节(中级篇):RCC——时钟树讲解(第一节)

目录 前言 STM32第九节(中级篇):RCC——时钟树讲解 时钟树主系统时钟讲解 HSE时钟 HSI时钟 锁相环时钟 系统时钟 SW位控制 HCLK时钟 PCLKI时钟 PCLK2时钟 RTC时钟 MCO时钟输出 6.2.7时钟安全系统(CSS) 小结 前言 从…

2024Python二级

1. 2. 前序遍历首先访问根节点再访问左子树和右子树 3. 4. sub不属于保留字 5. 6. 7. 8. continue是再重新开始进行循环,不是题目中所规定字母的话就对它进行输出 9. Python没有主函数的说法 10. 未转化为数据所要求的形式,应首先考虑eval 11. l…

【unity接入SDK案例】从0到1 如何接入百度地图SDK到unity中【一】

👨‍💻个人主页:元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏:Uni…

BUUCTF-Misc9

刷新过的图片1 1.打开附件 2.F5-steganography-master 利用F5-steganography-master工具 3.修改扩展名为压缩包 4.得到flag [BJDCTF2020]你猜我是个啥1 1.打开附件 是一个压缩包,但解压不了,不是压缩文件 2.010 Editor 用010 Editor查看,最…

Leet code 三步问题

解题思路:动态规划 先观察 1级台阶 1种方法 2级台阶 2种方法 3级台阶 4种方法 4级台阶 7种方法 5级台阶 13种方法 可以看出规律 从3级台阶后 每级台阶需要从前三层台阶和相加 注意:后面值会过大 需要在相加之后就模运算1000000007 代码如下 clas…

智慧路灯杆AI监测应用,让高速出行更安全

高速公路是现代交通出行的重要组成,高速公路上的交通安全也一直是人们关注的焦点。针对更好监测和管理高速公路上的交通状况,可以基于智慧路灯杆打造AI交通监测应用,通过智能感知高速路段的路况、车况、环境状况,实现实时风险感知…

轻松驾驭时间流:MYSQL日期与时间函数的实用技巧

​🌈 个人主页:danci_🔥 系列专栏:《MYSQL应用》💪🏻 制定明确可量化的目标,坚持默默的做事。 MySQL的时间函数用于处理日期和时间数据。以下是一些常用的MySQL时间函数。 内容有点多&#xff0…