踩了个大坑!K8s 挂载目录的日志,居然也在吃容器内存?

最近一直收到某个服务pod容器内存超过80%的告警,堆内存加上堆外内存目前看也只有1G左右,但pod内存却达到4G多,查来查去查到active_file对应的logs占用大量内存,目前现状是k8s中springboot服务日志挂载到宿主机/logs目录,/logs目录的所有日志大小有3G,容器内存显示也包含日志的3G,即使挂载出来了也没生效?

挂载设置如下:

YAML 复制代码
volumeMounts:
    - mountPath: /logs
      name: logs-volume
volumes:
 - hostPath:
    path: /logs
    type: ''
   name: logs-volume

那为什么logs挂载到外部还是会占用大量内存?

这里查询资料,K8s/Docker 对容器的内存统计基于 Linux Cgroup 的 memory.usage_in_bytes,该值包含两部分:

  • RSS(常驻内存):Java 进程本身的堆、栈、堆外内存,是程序实际运行占用的内存

  • Page Cache(页面缓存) :进程读写磁盘文件时,内核为提升IO性能而缓存的文件数据,logs占用的内存是 Linux 内核的文件页面缓存(Page Cache)被统计到了容器的 cgroup 内存使用中

Java 复制代码
# 查看cgroup内存统计,关注 rss 字段(进程实际占用),cache 字段是可回收的文件缓存
cat /sys/fs/cgroup/memory/memory.stat
手动清理 Page Cache(临时方案)
进入容器或宿主机执行(需要权限):
# 清理文件缓存,不会影响运行
echo 1 > /proc/sys/vm/drop_caches

当SpringBoot应用向/logs 目录写入 3G 日志时:

  • 即使 /logs 通过 hostPath 挂载到宿主机磁盘,容器内进程写入的所有日志数据都会先进入 Page Cache这部分 3G 的缓存数据会被完整统计到容器的内存使用量中

  • K8s 计算工作集内存(container_memory_working_set_bytes)时使用公式:总内存使用 - 非活跃文件缓存,而频繁写入的日志文件属于"活跃文件(active_file)",不会被扣除,因此最终显示的内存占用就包含了这3G日志大小

关键点是 :即使挂载到了宿主机,但在大量请求服务时,服务在读写日志文件,这时就会一直在操作日志文件没有释放,在 cgroup 的内存统计中,哪个进程触发了 I/O,产生的 Page Cache 就归到哪个进程的 cgroup 里。但之前已经轮换的日志压缩文件不会占用。

还有一点,就是多个一个服务的多个实例在同一个节点,那操作的日志文件就会两个实例同时进行读写 这就可能会导致其中一个实例不会释放这个日志文件或操作轮转失败 一直存在 那内存就会越来越高。

按以下步骤解决

  1. 重启服务释放占用内存达到止血的目的。

  2. 清除一部分日志。

  3. 将同一服务的多实例分配到不同节点。

  4. 将日志轮转时长调短,降低日志量和文件大小,间接减少 Page Cache 上限。

  5. 建议避免在容器内读取日志文件;(但这个日志在写应该很少能满足)

  6. 将logs挂载到NFS中进行收集。

相关推荐
Goboy1 小时前
夯爆了,我被一个一句话接入的免费可观测平台策反了,那一刻我决定放弃用了3年的Prometheus
后端·docker·kubernetes
吴声子夜歌1 小时前
Kubernetes权威指南——深入掌握Service(一)
云原生·容器·kubernetes
weirong1 天前
图解 client-go Informer:手写一个 mini-Informer 才敢说懂
kubernetes
.冰块.1 天前
流量大了自动加 Pod!K8s HPA 扩缩容与 ResourceQuota/LimitRange 资源管控实战
linux·云原生·容器·kubernetes·hpa·quota·limitrange
无言听风雨丶2 天前
Linux 容器本质探秘:Cgroup 与 Namespace 深度解析与实战
linux·运维·服务器·kubernetes
无言听风雨丶2 天前
Kubernetes GitOps 持续交付实战:用 Argo CD 让 Git 成为集群事实源
git·elasticsearch·kubernetes
无言听风雨丶2 天前
Kubernetes 控制平面深度剖析:从 kubectl apply 到 etcd 写入的全链路
平面·kubernetes·etcd
openFuyao3 天前
openFuyao x 复旦大学软件工程实验室 Panel 回顾:Agentic时代,集群调度技术体系将如何演进?
kubernetes·openfuyao
螺蛳粉 螺蛳粉3 天前
第 05 篇:etcd 深入:Raft 共识、watch 机制与快照备份恢复实战(底座认知 05)
docker·云原生·容器·kubernetes·etcd·分布式存储·kube-apiserver
相思难忘成疾3 天前
从零搭建 Kubernetes 1.30 集群:kubeadm 部署一主多从实战(RHEL 9.3 + Docker + flannel)
linux·运维·kubernetes