彻底解决 K8s 节点本地存储被撑爆的问题

news2024/11/17 3:23:33

一、存储的内容

要解决存储使用过多的问题,就得先了解存储中都保存了些什么内容,否则解决不了问题,还可能带来更多的风险。

1.1、镜像

容器要在节点上运行,kubelet 首先要拉取容器镜像到节点本地,然后再根据镜像创建容器。随着 Pod 的调度和程序的升级,日积月累,节点本地就会保存大量的容器镜像,占用大量存储空间。

如果使用的是 Docker 容器运行时,这些文件保存在 /var/lib/docker/image/overlay2 目录下。

1.2、可写层

关于可写层,了解容器本质的同学应该比较熟悉,容器运行时使用的是一种联合文件系统技术,它把镜像中的多层合并起来,然后再增加一个可写层,容器中写操作的结果会保存在这一层,这一层存在于容器当前节点的本地存储中。虽然镜像中的层是容器实例共享的,但是可写层是每个容器一份。

假如我们有一个名为 mypod 的 Pod 实例,在其中创建一个文件:/hello.txt,并写入 hello k8s 的字符。

$ kubectl exec mypod -- sh -c 'echo "hello k8s" > /hello.txt'
$ kubectl exec mypod -- cat /k8s/hello.txt
hello k8s

如果使用的是 Docker 容器运行时,可以在 Docker 的相关目录中找到可写层以及刚刚创建的这个文件,它们在 /var/lib/docker/overlay2 这个目录下。

如果毫无节制的使用可写层,也会导致大量的本地磁盘空间被占用。

1.3、日志

K8S 推荐的日志输出方式是将程序日志直接输出到标准输出和标准错误,此时容器运行时会捕捉这些数据,并把它们写到本地存储,然后再由节点上的日志代理或者 Pod 中的边车日志代理转运到独立的日志处理中心,以供后续分析使用。

这些日志保存在节点本地的 /var/log/container 目录下,我们可以实际创建一个 Pod 来确认下:

apiVersion: v1
kind: Pod
metadata:
  name: pod-log-stdout
spec:
  containers:
  - name: count
    image: busybox:latest
    args: [/bin/sh, -c,
            'i=0; while true; do echo "$i: $(date) a log entry."; i=$((i+1)); usleep 1000; done']

这个 Pod 每隔 1 毫秒会写 1 条数据到标准输出。要找到容器运行时根据标准输出创建的日志文件,首先要找到这个 Pod 部署的节点,然后登录到这个节点,就能找到对应的文件了。

如果程序输出的日志很多,占满磁盘空间就是早晚的事。

1.4、emptyDir

emptyDir 是一种基于节点本地存储的 Volume 类型,它通过在本地存储创建一个空目录来实际承载 Volume。使用这种存储卷可以在 Pod 的多个容器之间共享数据,比如一个容器造数据,一个容器消费数据。

看下面这个例子:

apiVersion: v1
kind: Pod
metadata:
  name: pod-vol-empty-dir
spec:
  containers:
  - name: count
    image: busybox:latest
    args: [/bin/sh, -c, 'echo "k8s" > /cache/k8s.txt;sleep 1800']
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir: {}

在 spec.volumes[] 中只需要添加一个名为 emptyDir 的字段,它的配置都可以使用默认值,然后这个卷会被挂载到容器的 /cache 路径。

容器的启动参数是一个 shell 命令,它会在容器的 cache 目录下创建 1 个名为 k8s.txt 的文件。容器创建后稍等一会,使用下面的命令获取这个文件的内容:

$ kubectl exec pod-vol-empty-dir -- cat /cache/k8s.txt
k8s

可以看到,文件内容正是容器启动命令中写入的 k8s 字符。

K8S 会在当前的 Node 自动创建一个目录来实际承载这个卷,目录的位置在 Node 的 /var/lib/kubelet/pods 路径下。要查看这个目录中的内容,需要先找到 Pod Id 和对应的 Node,然后登录到这个 Node,就能找到这个目录了。minikube 中的查找方法如下图所示:

注意用颜色框圈出来的内容,不同的 Pod 对应的数据不同。查找 Pod Id 的命令:

$ kubectl get pods -o custom-columns=PodName:.metadata.name,PodUID:.metadata.uid,PodNode:.spec.nodeName

如果不对 emptyDir Volume 做一些限制,也是有很大的风险会使用过多的磁盘空间。

二、存储的限制方法

通过上文的介绍,我们可以看到,除了容器镜像是系统机制控制的,其它的内容都跟应用程序有关。

应用程序完全可以控制自己使用的存储空间,比如少写点日志,将数据保存到远程存储,及时删除使用完毕的临时数据,使用 LRU 等算法控制存储空间的使用量,等等。不过完全依赖开发者的自觉也不是一件很可靠的事,万一有 BUG 呢?所以 K8S 也提供了一些机制来限制容器可以使用的存储空间。

2.1、K8S 的 GC

K8S 有一套自己的 GC 控制逻辑,它可以清除不再使用的镜像和容器。这里我们重点看下对镜像的清理。

这个清理工作是 kubelet 执行的,它有三个参数来控制如何执行清理:

  • imageMinimumGCAge 未使用镜像进行垃圾回收时,其存在的时间要大于这个阈值,默认是 2 分钟。

  • imageGCHighThresholdPercent 镜像占用的磁盘空间比例超过这个阈值时,启动垃圾回收。默认 85。

  • ImageGCLowThresholdPercent 镜像占用的磁盘空间比例低于这个阈值时,停止垃圾回收。默认 80。

可以根据自己的镜像大小和数量的水平来更改这几个阈值。

2.2、日志总量限制

K8S 对写入标准输出的日志有一个轮转机制,默认情况下每个容器的日志文件最多可以有 5 个,每个文件最大允许 10Mi,如此每个容器最多保留最新的 50Mi 日志,再加上 Node 也可以对 Pod 数量进行限制,日志使用的本地存储空间就变得可控了。这个控制也是 kubelet 来执行的,有两个参数:

  • containerLogMaxSize 单个日志文件的最大尺寸,默认为 10Mi。

  • containerLogMaxFiles 每个容器的日志文件上限,默认为 5。

以上文的 pod-log-stdout 这个 Pod 为例,它的日志输出量很多就会超过 10Mi,我们可以实际验证下。

不过如果没有意外,意外将要发生了,K8S 的限制不起作用。这是因为我们使用的容器运行时是 docker,docker 有自己的日志处理方式,这套机制可能过于封闭,K8S 无法适配或者不愿意适配。可以更改 docker deamon 的配置来解决这个问题,在 K8S Node 中编辑这个文件 /etc/docker/daemon.json (如果没有则新建),增加关于日志的配置:

{
    "log-opts": {
        "max-size": "10m",
        "max-file": "5"
    }
}

然后重启 Node 上的 docker:systemctl restart docker。注意还需要重新创建这个 Pod,因为这个配置只对新的容器生效。

在 docker 运行时下,容器日志实际上位于 /var/lib/docker/containers 中,先找到容器 Id,然后就可以观察到这些日志的变化了:

2.3、emptyDir Volume 限制

对于 emptyDir 类型的卷,可以设置 emptyDir.sizeLimit,比如设置为 100Mi。

apiVersion: v1
kind: Pod
metadata:
  name: pod-vol-empty-dir-limit
spec:
  containers:
  - name: count
    image: busybox:latest
    args: [/bin/sh, -c,
            'while true; do dd if=/dev/zero of=/cache/$(date "+%s").out count=1 bs=5MB; sleep 1; done']
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir:
      sizeLimit: 100Mi

稍等几分钟,然后查询 Pod 的事件:

可以看到 kubelet 发现 emptyDir volume 超出了 100Mi 的限制,然后就把 Pod 关掉了。

2.4、临时数据的总量限制

对于所有类型的临时性本地数据,包括 emptyDir 卷、容器可写层、容器镜像、日志等,K8S 也提供了一个统一的存储请求和限制的设置,如果使用的存储空间超过限制就会将 Pod 从当前 Node 逐出,从而避免磁盘空间使用过多。

然后我们创建一个 Pod,它会每秒写 1 个 5M 的文件,同时使用 spec.containers[].resources.requests.limits 给存储资源设置了一个限制,最大 100Mi。

apiVersion: v1
kind: Pod
metadata:
  name: pod-ephemeral-storage-limit
spec:
  containers:
  - name: count
    image: busybox:latest
    args: [/bin/sh, -c,
            'while true; do dd if=/dev/zero of=$(date "+%s").out count=1 bs=5MB; sleep 1; done']
    resources:
      requests:
        ephemeral-storage: "50Mi"
      limits:
        ephemeral-storage: "100Mi"

稍等几分钟,然后查询 Pod 的事件:

$ kubectl describe pod pod-ephemeral-storage-limit

可以看到 kubelet 发现 Pod 使用的本地临时存储空间超过了限制的 100Mi,然后就把 Pod 关掉了。

通过这些存储限制,基本上就可以说是万无一失了。当然还要在节点预留足够的本地存储空间,可以根据 Pod 的数量和每个 Pod 最大可使用的空间进行计算,否则程序也会因为总是得不到所需的存储空间而出现无法正常运行的问题。

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

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

相关文章

3分钟读懂RD与RT

Route-Distinguisher(后简称"RD"),Route-Target(后简称"RT")经常出现在EVPN、MPLS VPN中,但它们是完全不同的两个概念,初学者往往难以区分两者的差异。学霸题:区…

Jmeter入门

性能测试:模拟多个用户的操作对服务器硬件性能的影响 TPS:Transaction per Second,每秒事务处理能力 RT:Response Time,响应时间 安装 由于本人只有window系统,故只讲解win下的安装 安装JDK 下载地址&a…

2023年最热门的网络安全岗位分析

大数据、人工智能、云计算、物联网、5G等新兴技术的高速发展,蒸蒸日上。但是随之也出现了许多问题,比如:政府单位、企业、个人信息泄露,网络安全问题日益严峻,网络空间安全建设刻不容缓。 网络安全人才需求量巨大&…

双核驱动,合力共进,郁锦香与凯里亚德酒店强强联合释放多元化商业价值

近日,以“清风雅茗 亨嘉之会”为主题的2022锦江酒店(中国区)厦门站品牌投资品鉴会圆满落幕,众多投资人和酒店品牌方负责人齐聚一堂,在充满文艺气息的滨海城市厦门,感受精致、愉悦的慢生活。在品牌见面环节&…

NodeJs实战-Express构建照片存储网站(1)-ejs视图引擎填充数据

ejs视图引擎填充数据express 生成项目安装 express-generator生成项目程序结构理解项目结构生成的文件的含义视图渲染填充照片数据增加路由器修改 app.js修改 routes增加对应的视图页面路由器 res.render 查找视图逻辑新增文件之后的项目结构图效果图项目地址express 生成项目 …

kali Linux常用快捷键及vim的基本使用

kali Linux 系统快捷键 Ctrl Alt T :打开一个新的命令行终端。 如果是在桌面打开的是这种情况 Ctrl C 复制。 Ctrl Z 撤消。 Ctrl S :保存 Ctrl Q :退出。 终端快捷键 TAB :补全命令。 Ctrl :放大文字…

Netty系列(一):Springboot整合Netty,自定义协议实现

Netty是由JBOSS提供的一个java开源框架,现为 Github上的独立项目。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。 也就是说,Netty 是一个基于NIO的客户、服务器端的编程框架&…

目标检测论文解读复现之十六:基于改进YOLOv5的小目标检测算法

前言 此前出了目标改进算法专栏,但是对于应用于什么场景,需要什么改进方法对应与自己的应用场景有效果,并且多少改进点能发什么水平的文章,为解决大家的困惑,此系列文章旨在给大家解读最新目标检测算法论文&#xff0c…

Java项目使用intellij-IDEA查看依赖包版本是否有冲突(方法及工具)

编译器及版本idea-ultimate依赖管理工具maven 第一个是idea本身的 Step1:点击右侧的maven Step2:右键依赖项,点击分析依赖关系 Step3:可以在模块名位置进行切换,左侧三角的标志则表示该包引入了多个版本&#xff…

【云原生】Docker网络原理及Cgroup硬件资源占用控制

内容预知 1.dockers的网络模式 获取容器的进程号 docker网络模式的特性 1.1 host主机模式 1.2 container模式 1.3 none模式 1.4 bridge 桥接模式 1.5 容器的自定义网络 (1)未创建自定义网络时,创建指定IP容器的测试 (2&a…

双坐标轴柱状图

双坐标轴柱状图 setwd(“H:/分析评价 20220531/6-分析过程”) #设置工作路径 library(xlsx)#加载excel文件包 #---------------------------------------------------------------------------------------------------------- tiff(file“1-占比.tiff”,res600,width6000,hei…

负载均衡有哪些?

目录 【一】前言 【二】负载均衡分类 2.1 DNS 2.2 硬件负载均衡 2.3 软件负载均衡 2.4 组合负载均衡 【三】负载均衡算法 3.1 负载均衡算法分类 3.2 轮询 3.3 加权轮询 3.4 负载最低优先 3.5 性能最优类 3.6 Hash 【四】总结 【一】前言 在互联网尤其是移动互联…

【前沿技术RPA】 一文了解UiPath的项目活动设置

🐋作者简介:博主是一位.Net开发者,同时也是RPA和低代码平台的践行者。 🐬个人主页:会敲键盘的肘子 🐰系列专栏:UiPath 🦀专栏简介:UiPath在传统的RPA(Robotic…

【计算机组成原理Note】5.2 指令周期的数据流

5.2 指令周期的数据流 5.2.1 指令周期 指令周期:CPU从主存中每取出并执行一条指令所需的全部时间。 指令周期:常常用若干机器周期来表示,机器周期又叫CPU周期。 一个机器周期又包含若干时钟周期(也称为节拍、T周期或CPU时钟周期&#xff…

SpringCloud微服务(十一)——Sentinel服务熔断限流

SpringCloud Alibaba Sentinel服务熔断与限流 简介 github:[https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E9%A1%B5](https://github.com/alibaba/Sentinel/wiki/如何使用) 官网:https://spring-cloud-alibaba-group.github.io/github-pages/…

为什么追踪员工的时间和出勤率很重要

监控员工的出勤时间和出勤率对于提高业务绩效和生产力至关重要。实施有效计时策略的组织可以帮助员工跟上项目目标和截止日期,提高客户满意度,并加强对员工产出的整体意识。所以每个企业组织都应该掌握员工出勤时间和出勤数据。 为什么要掌握员工出勤时…

阿里架构师耗时 1 年,把 P8 所需要的整个 Java 体系,都整理到了一起

有人调侃我们说: 程序员不如送外卖。送外卖是搬运食物,自己是搬运代码,都不产出新的东西…… 透支体力,又消耗健康,可替代性极强,30 岁之后就要面临被优化的危险…… 想跳槽,但是更高的平台难…

微信小程序怎么弄?【小程序制作】

微信小程序怎么弄?很多人都会想弄一个微信小程序,因为微信小程序这个轻应用现在的使用频率已经赶上微信了,有如此大的用户群体,企业和商家当然都想在这个庞大流量池里分一杯羹。那么微信小程序怎么弄呢?下面一起来看看…

群签名、环签名、盲签名

文章目录群签名定义安全性构造环签名定义安全性构造盲签名定义安全性构造群签名 定义 群签名方案是算法组 ΠGS(Gen,Sign,Ver,Open)\Pi_{GS}(Gen, Sign, Ver, Open)ΠGS​(Gen,Sign,Ver,Open), Gen(1λ,n)Gen(1^\lambda,n)Gen(1λ,n):密钥生成算法&…

百度Q3财报显AI技术厚度,“慢生意”稳步驶入“快车道”

一周前,笔者参加了一场百度主办的关于AIGC话题的沙龙,因为话题无比火爆,活动延迟到了一点钟才结束,以至于让约定的好友饭局也一等再等。 倒没有丝毫抱怨的意思,正是这个烧脑的活动,让我感受并体验到了当下最…