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

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️⃣ 尽快升级服务器
如果内存不足问题持续,最终只有升级硬件才能彻底解决。

相关文章:

  • 第10次:电商项目配置开发环境
  • Ubuntu 20.04 安装 ROS 2 Foxy Fitzroy
  • CSS的三大特性:层叠、继承与优先级
  • 实现使用Lucene对某个信息内容进行高频词提取并输出
  • Python爬虫学习路径与实战指南 03
  • SpringBoot+Mybatis通过自定义注解实现字段加密存储
  • 阿里云服务迁移实战: 05-OSS迁移
  • SMPP协议解析
  • UBUS 通信接口的使用——添加一个object对象(ubus call)
  • 日常开发小Tips:后端返回带颜色的字段给前端
  • Html1
  • SSR vs SSG:前端渲染模式终极对决(附 Next.js/Nuxt.js 实战案例)
  • 【MySQL】表的复合查询
  • Milvus(10):JSON 字段、数组字段
  • SpringBoot中获取系统及硬件信息
  • C++学习:六个月从基础到就业——模板编程:模板元编程基础
  • mermaid 序列图 解析
  • 如何用python脚本把一个表格有4万多条数据分为两个文件表,每个2万条数据?
  • 华为云IoT平台与MicroPython实战:从MQTT协议到物联网设备开发
  • 基于PHP的宠物用品商城
  • 78家公募年度业绩比拼:23家营收净利双升,十强座次微调
  • 初步结果显示加拿大自由党赢得大选,外交部回应
  • A股三大股指小幅低收:电力股大幅调整,两市成交10221亿元
  • 湖南华容县通报“大垱湖水质受污染”,爆料者:现场已在灌清水
  • 大理杨徐邱再审上诉案宣判:驳回上诉,维持再审一审判决
  • 超级干细胞有助改善生育治疗