2 核 2G 的云服务器资源非常紧张,运行 Docker 时出现内存不足(OOM)是常见问题。以下是系统化的解决方案,按优先级排序:
一、立即缓解措施
1. 查看当前内存使用情况
# 查看整体内存使用
free -h
# 查看 Docker 容器内存占用
docker stats --no-stream
# 查看具体容器详情
docker inspect <container_id> | grep -i memory
2. 设置容器内存限制
为每个容器设置合理的内存上限,防止单个容器耗尽所有资源:
docker run -d --memory="512m" --memory-swap="512m" --name myapp your-image
或使用 docker-compose.yml:
services:
app:
image: your-image
deploy:
resources:
limits:
memory: 512M
reservations:
memory: 256M
3. 清理未使用的资源
# 停止并删除未运行的容器
docker container prune
# 删除未使用的镜像
docker image prune -a
# 删除未使用的卷和构建缓存
docker volume prune && docker builder prune
二、优化 Docker 配置
4. 修改 Docker 守护进程配置
编辑 /etc/docker/daemon.json:
{
"default-runtime": "runc",
"exec-opts": ["native.cgroupdriver=cgroupfs"],
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"storage-driver": "overlay2",
"bip": "172.18.0.1/16"
}
然后重启 Docker:
sudo systemctl restart docker
5. 调整 Linux 内核参数
编辑 /etc/sysctl.conf:
vm.swappiness=10
vm.vfs_cache_pressure=50
应用配置:
sudo sysctl -p
三、应用层优化
6. 优化应用程序内存使用
- Java 应用:设置合理的 JVM 参数
java -Xms256m -Xmx512m -jar app.jar - Node.js 应用:限制最大堆内存
node --max-old-space-size=512 app.js - Python 应用:避免一次性加载大量数据到内存
7. 使用轻量级替代方案
- 替换重型数据库(如 MySQL → SQLite 或 PostgreSQL 精简版)
- 使用更轻量的运行时(如 Alpine 基础镜像)
- 考虑将部分服务迁移到无服务器架构
四、监控与告警
8. 建立监控机制
安装轻量级监控工具:
# 安装 cAdvisor
docker run -d
--name=cadvisor
--volume=/:/rootfs:ro
--volume=/var/run:/var/run:ro
--volume=/sys:/sys:ro
--volume=/var/lib/docker/:/var/lib/docker:ro
--volume=/dev/disk/:/dev/disk:ro
gcr.io/cadvisor/cadvisor:latest
# 或使用专门的监控工具
apt-get install htop -y
9. 设置 OOM 告警
创建监控脚本 /usr/local/bin/oom_monitor.sh:
#!/bin/bash
MEMORY_THRESHOLD=80
CURRENT_USAGE=$(free | awk '/Mem:/ {printf "%.0f", $3/$2 * 100}')
if [ $CURRENT_USAGE -gt $MEMORY_THRESHOLD ]; then
echo "Memory usage is ${CURRENT_USAGE}% - Alert!" | mail -s "Memory Alert" admin@example.com
fi
添加到 crontab:
*/5 * * * * /usr/local/bin/oom_monitor.sh
五、长期优化建议
10. 升级硬件配置
如果以上方法仍无法满足需求,考虑:
- 升级到 4G 内存实例
- 使用内存优化型实例
- 采用集群部署分散负载
11. 架构优化
- 实施微服务拆分,降低单体应用复杂度
- 引入 Redis 等缓存减少数据库压力
- 使用 CDN 静态资源减轻应用服务器负担
12. 定期维护计划
# 每周自动清理任务
echo "0 2 * * 0 /usr/local/bin/docker_cleanup.sh" >> /etc/crontab
关键提示:在 2G 内存环境下,建议总容器内存限制不超过 1.5G,预留 500M 给系统和 Docker 自身使用。优先保证核心业务服务的稳定性,非关键服务可考虑降级或异步处理。
CLOUD技术笔记