1. Current Location: Home >  NAS >  NAS能跑多少个Docker容器?九个容器的内存账挨个抄完,压垮8G的不是数量是峰值

NAS能跑多少个Docker容器?九个容器的内存账挨个抄完,压垮8G的不是数量是峰值

NAS能跑多少个Docker容器的内存账,稳态与峰值两本账对比

装容器这件事,跟当年装手机App一个德行。我在飞牛上装Docker容器,从最早就一个qBittorrent下载器,到现在九个:下载的、看电影的、听歌的、看电子书的、看漫画的、管全屋智能的、去广告的、管照片的、管密码的。每装一个都想着「就多占一点点」,直到上个月某个早上,AdGuard后台让我重新登了一遍——运行时长只剩六个小时,容器半夜被人动过。

先说清楚:容器吃的不是一份内存,是「稳态+峰值」两本账

很多人算容器账的方式是拿容器数量乘个平均值,比如「一个容器吃300兆,8G能跑二十个」。这个算法在下载器、去广告这种老实容器身上勉强成立,但NAS上真正的大户根本不按这个规矩吃饭。

我家的Home Assistant稳态430兆,雷打不动;Jellyfin平时310兆,一转码就往上蹿;最狠的是Immich,平时600多兆挺温和,一旦跑人脸识别,内存直接顶到3个G以上。你要是只看「平时」,会觉得8G内存宽裕得能再装十个;你要是只看「跑识别的那两天」,又觉得这机器马上要爆。两本账分开记,才知道自己的NAS到底还剩多少余量。

抄账的命令就一行:

docker stats --no-stream

不带--no-stream它会一直刷,加上这个参数出一张快照就走。MEM USAGE那一列是实占内存,MEM USAGE / LIMIT那一列如果是百分数,说明你给容器设过上限,没设过就显示容器实占除以主机总内存。飞牛在SSH里敲这个命令,或者在容器详情页看,数字是一个来源。

我家九个容器的内存账,抄下来长这样

挑了个周日下午,全家设备都在线、没跑任何识别任务的时点,我把快照抄了下来:

容器干什么用稳态内存峰值脾气
Immich一套照片库620M上下跑人脸识别顶到3G以上
Home Assistant全屋智能中枢430M上下稳,基本不蹿
Jellyfin电影库310M上下转码时往上蹿一截
qBittorrent下载保种180M上下种子多了缓步涨
Komga漫画库260M上下全库扫描时七八百兆
calibre-web电子书120M上下稳
Navidrome音乐库90M上下稳
AdGuard Home全家去广告60M上下稳得像块砖
Vaultwarden密码库30M上下Rust写的,几乎不动

九个加起来2.1G上下,加上飞牛系统本身和各种缓存,free -h里总共吃掉3G出头,8G的机器还剩一大半。单看这张表,你会得出「再装五个也没事」的结论。我当初就是这么想的。

栽跟头那次:两个峰值撞到了一块

出事那晚我干了件事:给Immich换中文搜索模型,全库四万多张照片要重新跑一遍编码和人脸,我挑了半夜让它自己跑。结果那几天Komga的定期全库扫描也正好排在那晚,俩活撞上了。

Immich的机器学习容器满载3个G挂上,Komga扫描爬到七百多兆,再加上另外七个稳态的,容器这块就奔着5个G去了,系统再扣掉一块,第二天早上我看free -h,available那列只剩四百来兆。看available别看free那列——free把文件缓存也算成「用了」,available才是系统真还能掏出来的钱。

然后就轮到AdGuard倒霉。凌晨两点多,它被内核一刀杀了。第二天早上我登AdGuard后台要重新登录、运行时长归零,第一反应还以为是飞牛更新了什么。到SSH里一查才明白:

docker ps -a里它那条显示Exited (137)。这个137不是随便编的数,128加9,9就是SIGKILL,内核干的。再补一刀确认:

docker inspect 容器名 --format '{{.State.OOMKilled}} {{.State.ExitCode}}'

返回true 137,实锤内存不足被杀。AdGuard平时才60兆,杀谁不好杀它?因为内核挑倒霉蛋不按体型排,谁在内存最紧张的那一秒恰好申请内存,谁挨刀。它管全家DNS,半夜每一秒都有查询,自然最容易撞枪口。

容器半夜消失?先看它是不是被137杀了

这事之后我总结了个排查顺序,家里谁的容器莫名重启过,照着走:

第一步,docker ps -a看状态。Exited后面括号里的数字先记下来:137是内存被杀,1是程序自己报错,143是收到了正常停止信号(重启策略或者手动停的),139是段错误,那是程序自己的毛病。

第二步,137就查内存账。把docker stats --no-stream的快照存一份,跟出事时间对一下——是某个峰值容器在干重活,还是你自己最近又新装了什么。

第三步,不是137再看日志。docker logs --tail 100 容器名翻最后百来行,程序报错基本都在里面。我以前老是顺序搞反,容器一重启就先翻日志,翻半天什么都没有——被内核杀的进程,日志里不会留遗言。

减负三板斧:砍、限、换

账算明白之后,我干了三件事,按狠程度从轻到重排:

第一板斧是砍。功能重叠的容器合并掉:电影海报墙飞牛自带的影视App也能干,我把Jellyfin的一个备用库砍了;以前装过一个专门下歌词的容器,Navidrome自己就能刮封面,砍了。这一步不心疼,砍完稳态省了小五百兆。

第二板斧是限。给峰值型容器上笼子,新建容器时加一个参数:

docker run -m 512m --memory-swap 512m ...

-m是内存上限。我给Komga限了768兆——扫描慢点就慢点,扫描那点事从来不着急,犯不着让它把整机拖下水。注意别限Immich这种真干重活的,识别3个G你给它限到1G,它不会被「劝」着少用,只会被反复杀,识别任务永远跑不完。限制是给「峰值没意义」的容器用的,不是给「峰值就是正事」的容器用的。

第三板斧是换。AdGuard Home换不动,它已经是同类里最省的;但我把它的重启策略确认设成了always,被杀了自己爬起来,DNS断个几秒钟家里人无感。重活错峰:Immich的识别我改成手动触发、白天家里没人时跑,Komga的扫描间隔从每天改成每周。顺带把Watchtower那种自动升容器的也改成只盯一两个无状态的,别的手动升——更新风暴一来十几个容器同时拉新镜像、同时重启,那一下也是个小峰值。峰值不可怕,两个峰值叠一块才可怕,错开就各过各的。

什么时候才轮到加内存

三板斧抡完,我家现在稳态3G、峰值也就5G上下,8G还有余量,这台N100接着用。真到了砍也砍不动、限也不能限、峰值还是天天顶满的地步,才轮到掏钱。

掏钱之前先看机器:有的NAS内存是板载焊死的,想加都没门路,那就要么换机器要么认命少跑;有空槽的,4G升8G还是8G升16G的账我以前单独写过一篇,三档实测都摆在那,链接放这。还有一条弯路别走:别指望swap救命。内存不够让系统往盘上倒,机械盘做swap整机卡到鼠标都费劲,那不是减负是摊薄痛苦。

最后给个对号表:

你家的状况先干什么
还没装容器,规划中按稳态+峰值两本账配,峰值型的错峰跑
装了五六个,没出过事docker stats抄一份底账存着,出事有得对
容器半夜莫名重启先查137,再查内存账,最后才翻日志
砍完限完还是顶满查内存插槽,该加加该换换

容器数量从来不是答案,峰值管理才是。我家九个跑得欢,别人家五个天天崩,差的不是内存条,是那两本账有没有分开记。

Docker那三个名词还犯迷糊的,先补镜像、端口映射、目录挂载那一课;Immich的安装和中文搜索模型、Home Assistant吃多少内存、Komga和calibre-web这套书库漫画库、Jellyfin和飞牛影视的内存对比、AdGuard Home全屋去广告、Vaultwarden密码库、qBittorrent下载机,各自那篇都写了细账。容器的bridge和host网络模式、容器怎么升级不丢数据,配上这篇正好凑一套。内存升不升级的三档实测,交给那篇收尾。

Read More


Copyright Notice Scan to read on mobile
All Rights Reserved: 《SHUNOT》 => 《NAS能跑多少个Docker容器?九个容器的内存账挨个抄完,压垮8G的不是数量是峰值》
Article URL: https://www.shunot.com/en/nas/1331.html
Unless otherwise stated, all articles are original by 《SHUNOT》. Reposting is welcome! Please indicate the original URL when reposting, thank you.

Contact Us

Online Consultation: Click here to send me a message

WeChat ID: master_135

Scan to follow