当前位置: 首页 > ds >正文

docker排查OOM Killer

文章目录

    • 一.检查
      • 1.内存不足 (OOM Killer)
      • 2. CPU 资源限制
      • 3. 存储空间不足
      • 4. 应用自身崩溃
      • 5. 健康检查失败
      • 针对性建议
    • 二.内存不足
      • 问题根源
      • 解决方案(按优先级排序)
        • 1. 紧急措施:立即释放内存
        • 2. 启用 Swap 交换空间(必须做!)
        • 3. 降低容器内存限制(关键调整)
        • 4. 优化 Java 应用
        • 5. 终极方案:升级服务器配置
      • 验证是否解决
      • 注意事项
    • 三.总结

一.检查

1.内存不足 (OOM Killer)

  • 最常见原因:当容器内存超过限制或宿主机内存不足时,Linux 的 OOM Killer 会强制终止进程。
  • 检查方法
    docker stats              # 查看容器资源使用情况
    dmesg | grep -i kill      # 查看系统日志是否有OOM记录
    journalctl -k | grep -i oom
    
  • 解决方案
    • 增加容器内存限制:docker run -m 2g ...
    • 优化应用内存使用(如调整 JVM 堆大小,如果是 Java 应用)
    • 增加宿主机内存或减少其他容器资源占用

2. CPU 资源限制

  • 如果容器 CPU 使用率持续 100%,可能被调度器终止
  • 检查
    docker stats
    top
    
  • 解决
    • 增加 CPU 份额:docker run --cpu-shares=512 ...
    • 限制 CPU 核心数:docker run --cpus=1.5 ...

3. 存储空间不足

  • 磁盘写满会导致各种异常
  • 检查
    df -h
    docker system df
    

4. 应用自身崩溃

  • 查看应用日志:
    docker logs <container_id> --tail 100 -f
    
  • 检查是否有未捕获的异常

5. 健康检查失败

  • 如果配置了健康检查且失败,Docker 会重启容器
  • 检查
    docker inspect <container_id> | grep -A 10 Healthcheck
    

针对性建议

  1. 优先检查内存

    # 查看被杀死容器的退出代码
    docker inspect <container_id> | grep -i exitcode# 如果退出码是137(128+9=SIGKILL),通常是OOM
    
  2. 如果是 Java 应用

    • 确保设置了合理的 JVM 内存参数(如 -Xmx
    • 添加 -XX:+ExitOnOutOfMemoryError 让 JVM 主动退出而不是被杀死
  3. 临时解决方案(测试用):

    # 完全禁用OOM Killer(不推荐生产环境)
    docker run --oom-kill-disable ...
    

二.内存不足

在这里插入图片描述
free -h 的输出可以看到,你的 宿主机内存已经几乎耗尽1.7G 总量中 1.5G 已使用,仅剩 70M 空闲),并且 注意 Swap 交换空间(我的是 Swap: 0B)。这是导致 OOM Killer 频繁杀死容器的直接原因!


问题根源

  1. 宿主机内存严重不足

    • 物理内存剩余仅 70MB,任何突发内存需求都会触发 OOM Killer。
    • 没有 Swap 空间,系统无法将冷内存换出到磁盘,加剧了内存压力。
  2. 容器内存限制未生效

    • 虽然你为容器设置了内存限制(如 Halo 1.715GiB),但 宿主机总内存仅 1.7GiB,容器限制总和已超过物理内存。

解决方案(按优先级排序)

1. 紧急措施:立即释放内存
# 查找占用内存最多的进程并终止(慎重操作!)
top -o %MEM  # 按内存排序,记录PID后按 `k` 输入PID终止# 清理缓存(临时释放部分内存)
sync && echo 3 > /proc/sys/vm/drop_caches
2. 启用 Swap 交换空间(必须做!)
# 创建 2GB Swap 文件(根据磁盘空间调整大小)
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile# 永久生效(写入 /etc/fstab)
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab# 验证
free -h  # 应显示 Swap > 0
3. 降低容器内存限制(关键调整)
# 必须保证所有容器内存限制总和 < 1.5GiB(预留空间给系统)
docker update --memory 1G --memory-swap 1G mysql      # Halo 限制为1GB
4. 优化 Java 应用
# 确保 JVM 堆内存小于容器限制(例如限制为800MB)
java -Xms512m -Xmx800m -jar app.jar
5. 终极方案:升级服务器配置
  • 如果是云服务器(如阿里云),至少升级到 2.5GB 或 4GB 内存
  • 1.7GB 内存运行多个容器(尤其是 Java 应用)本身就很吃力。

验证是否解决

# 1. 确认 Swap 已启用
free -h  # 查看 Swap 列是否 > 0# 2. 监控容器内存
watch -n 1 "docker stats --no-stream"# 3. 检查 OOM 事件
dmesg | grep -i oom  # 应该不再有新的记录

注意事项

  1. 不要依赖 Swap 长期解决内存不足
    Swap 性能远低于物理内存,频繁交换会导致服务卡顿。

  2. MySQL 特殊处理
    如果 MySQL 因内存限制频繁崩溃,需要优化配置:

    docker exec mysql mysql -e "SET GLOBAL innodb_buffer_pool_size=128*1024*1024;"
    

三.总结

你的问题本质是 “1.7GB 内存的宿主机试图运行超过自身容量的服务”。按以下顺序操作:
1️⃣ 立即启用 Swap → 2️⃣ 大幅降低容器内存限制 → 3️⃣ 优化 容器内存分配 → 4️⃣ 尽快升级服务器
如果内存不足问题持续,最终只有升级硬件才能彻底解决。

http://www.xdnf.cn/news/3190.html

相关文章:

  • SVN子路径权限设置及登录方法详解
  • docker学习笔记6-安装wordpress
  • AB3 有效括号序列
  • C++的vector中emplace_back() 与 push_back() 的区别
  • 新型电子式EDT-5土动三轴实验系统
  • NodeJS读写(同步异步、流式、分片策略)
  • CentOS环境下搭建seata(二进制、MySQL)
  • 安装deepspeed时出现了以下的错误,如何解决CUDA_HOME does not exist
  • vue3+flex动态的绘制蛇形时间轴
  • 远程桌面导致Quartus 破解失效
  • Silvaco仿真中的victory mesh
  • 【MySQL数据库】--1.安装教程
  • HHsuite同源序列搜索数据库构建
  • 如何在Windows中更改文档默认打开方式
  • 【保姆级教程-Centos7环境下部署Prometheus并设置开机自启】
  • 【Yolo精读+实践+魔改系列】Yolov2论文超详细精讲(翻译+笔记)
  • temu,shein采购测评避坑指南:如何避免砍单封号,实现长效运营?
  • Harbor默认Redis与Notary组件弱口令漏洞分析与修复指南
  • ​【空间数据分析】缓冲区分析--泰森多边形(Voronoi Diagram)-arcgis操作
  • labview项目文件架构
  • WSL2下Docker desktop的Cadvisor容器监控
  • Spring Security 的 CSRF 防护机制
  • 时态--09--动词过去式、过去分词
  • 搜索——哈希优化策略
  • MTK Genio500 移植GMS及youtube问题处理的解决办法
  • docker拉取国内镜像
  • Javascript 中的继承?如何实现继承?
  • 解密Cloak斗篷技术:FP独立站推广利器
  • [论文阅读]Adversarial Semantic Collisions
  • 为什么要学习《易经》?