乐于分享
好东西不私藏

Docker生产环境必做的那些事:资源限制、日志管控、配置清单一次说清

Docker生产环境必做的那些事:资源限制、日志管控、配置清单一次说清

「Docker避坑指南」系列第④篇(终篇),聚焦生产环境资源管控和日志管理,附完整 daemon.json 配置清单。


前三篇讲的主要是”装上能跑”的问题,这篇讲的是”跑起来不出事”。

有次一个容器发生内存泄漏,32GB的内存被慢慢吃干净了,服务器直接卡死。重启之后,又碰到磁盘被日志塞满的问题。这两件事前后脚发生,那天晚上真的很难熬。

事后复盘,发现根本原因是:从来没给容器设置过任何资源上限。Docker默认不限制容器能用多少资源,一个容器真的可以把整台机器的CPU、内存、磁盘全部吃完。


坑①:容器内存泄漏,把整台服务器拖死

为什么会这样:

Docker本身不限制容器资源,如果你启动容器时没有设置上限,一个有内存泄漏的程序可以无限制地申请内存,直到系统OOM。

预防做法——启动时设置内存上限:

# 限制容器最多使用512MB内存,内存+swap总共1GBdocker run -m 512m --memory-swap 1g nginx

同样地,CPU也要限制:

# 最多使用1.5个CPU核心docker run --cpus="1.5" nginx# 或者用相对份额(默认是1024,这里设512相当于争抢时最多拿50%)docker run --cpu-shares=512 nginx

在docker-compose里设置资源限制:

version: '3'services:  web:    image: nginx    deploy:      resources:        limits:          cpus: '1.5'          memory: 512M        reservations:          cpus: '0.5'          memory: 256M

监控容器资源使用情况:

# 实时查看所有容器的资源消耗docker stats# 只看一次快照,不滚动docker stats --no-stream --format \"table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.MemPerc}}"

我的经验:内存限制设为正常使用量的1.5-2倍,留一点余量,不要卡得太死,否则业务高峰期容器会被OOM Kill。


坑②:日志容器几小时写满500GB磁盘

事故过程:

一个负责接收日志的容器,某天收到的日志量异常大,几个小时后磁盘就满了,所有服务连带着出问题。

这个故障完全可以靠配置来预防。

第一层防护:全局限制容器日志大小

在 daemon.json 里配置,所有容器默认继承这个日志限制:

{"log-driver""json-file","log-opts": {"max-size""100m","max-file""3","compress""true"  }}

每个容器最多3个日志文件,每个100MB,压缩存储,最坏情况占300MB左右。

第二层防护:限制容器可写层大小(需要xfs文件系统)

docker run --storage-opt size=10G nginx

第三层防护:磁盘监控告警脚本

#!/bin/bashUSAGE=$(df / | tail -1 | awk '{print $5}' | sed 's/%//')if [ $USAGE -gt 80 ]; thenecho"告警:磁盘使用率 ${USAGE}%,请及时清理!"# 可以接入钉钉/企微机器人发告警fi

第四层防护:定时自动清理

# 添加到crontab,每天凌晨3点执行0 3 * * * docker system prune -f --volumes --filter "until=72h"

until=72h 表示只清理3天前停止的资源,不会误删最近的。


坑③:日志文件几十GB,查日志直接卡死

容器跑了一段时间,日志文件动辄几十GB,docker logs 命令执行了半天没响应。

查日志的正确姿势:

# 只看最后100行,不要一次全加载docker logs --tail 100 container_name# 实时跟踪(Ctrl+C退出)docker logs -f container_name# 查看特定时间段docker logs --since "2026-02-20T10:00:00" --until "2026-02-20T11:00:00" container_name# 加时间戳,方便对照docker logs -t container_name

如果日志量实在太大,考虑用日志驱动转发出去:

# 发到本机syslogdocker run --log-driver=syslog nginx# 发到远程日志服务器(ELK、Loki等)docker run --log-driver=syslog \  --log-opt syslog-address=tcp://192.168.1.100:514 \  nginx

日志发到专门的日志系统之后,本地就不用存了,磁盘压力小很多,查询也方便。


生产环境 daemon.json 完整配置清单

这是我目前在生产环境用的配置,融合了前面说的各种优化点,经过多年验证:

{"registry-mirrors": ["https://docker.rainbond.cc","https://docker.1ms.run","https://docker.m.daocloud.io"  ],"log-driver""json-file","log-opts": {"max-size""100m","max-file""3","compress""true"  },"storage-driver""overlay2","storage-opts": ["overlay2.override_kernel_check=true"  ],"default-ulimits": {"nofile": {"Name""nofile","Hard"64000,"Soft"64000    }  },"live-restore"true,"userland-proxy"false,"dns": ["223.5.5.5""8.8.8.8"],"max-concurrent-downloads"10,"max-concurrent-uploads"5,"default-address-pools": [    {"base""172.17.0.0/16","size"24    }  ]}

几个关键配置说明:

  • live-restore: true
     — Docker重启时不停止正在运行的容器,减少业务中断
  • userland-proxy: false
     — 关闭用户态代理,性能更好,推荐生产环境开启
  • default-ulimits
     — 提高文件描述符上限,避免高并发时”too many open files”
  • default-address-pools
     — 固定容器网络IP段,避免和内网地址冲突

安装后必做的10件事(速查)

  1. docker --version && docker run hello-world
     — 验证安装
  2. sudo usermod -aG docker $USER
     — 配置免sudo
  3. 配置 registry-mirrors — 镜像加速
  4. 配置 log-opts — 限制日志大小
  5. 配置 live-restore: true — 减少重启中断
  6. sysctl net.ipv4.ip_forward=1
     — 开启IP转发
  7. sudo systemctl enable docker
     — 设置开机自启
  8. docker network create mynet
     — 创建自定义网络
  9. 所有生产容器加 -m 内存限制
  10. 配置定时清理任务到crontab

写在最后

这个系列写了4篇,把我这几年在Docker运维中踩过的坑基本都梳理了一遍。

回过头来看,大多数坑的根源都一样:Docker的默认配置是为了”能跑起来”而设计的,不是为了”生产可用”。

从安装的第一天起,就应该按照生产标准配置——限制资源、配好日志、理解权限、选对驱动。这些事情早做一个小时,可能省的是后面好几个不眠夜。

如果这个系列对你有帮助,欢迎转发收藏。

本站文章均为手工撰写未经允许谢绝转载:夜雨聆风 » Docker生产环境必做的那些事:资源限制、日志管控、配置清单一次说清

猜你喜欢

  • 暂无文章