
授权与合规声明本文全部操作对象均为自建隔离靶场本机容器或隔离虚拟机涉及安全测试的环节必须以取得合法授权为前提。未经授权的渗透测试违反《中华人民共和国网络安全法》与《刑法》相关条款须承担相应法律责任。本文只讲环境配置、版本对照与靶场隔离不含任何攻击步骤、利用载荷与绕过手法请勿将文中环境指向任何非自有系统。一、靶场不见了先分清是哪一件事1.1 事情往往是这样开始的你昨天还开着靶场练前两关今天早上想看容器列表发现它不在那儿了。屏幕上没有留下什么线索容器就是消失了。另一种情形更让人心慌你同时开了两个靶场一个练上传、一个练日志分析用到一半整台机器开始卡切窗口要等风扇也响了。这两种现象嘴上说的都是靶场不行了可它们落在完全不同的两层上。前一种是某一个容器退出了后一种是整台机器的资源被吃掉了。两件事的处理方向不一样所以本文的第一个动作不是去查配置、也不是去重装而是先做一次分流。1.2 分流只需要两个问题分流靠两个问题不需要复杂工具。第一个问题除了靶场别的东西是不是也慢了如果你的编辑器、浏览器、终端都还流畅只有那一个容器不见了那问题大概率在容器这一侧。如果整台机器一起变慢、切窗口有延迟那就要往机器整体资源这一层看。第二个问题消失的是不是每次都不太一样如果每次没的都是最近起来的那个或者占用最大的那个而不是固定某一个组件这本身就是一个很强的提示——它不是被某段代码弄坏的而是在一次资源紧张里被选中了。这两个问题对应的是两条只读动作⚠️代码待验证dockerps-a# 看容器还在不在包括已停止的容器dockerstats# 看正在运行的容器各自占用了多少两条都只做看不会改变环境里的任何东西。你看到的现象更可能落在哪一侧先做哪个只读动作只有一个容器不见了机器其它程序正常单个容器的运行状态看容器列表包括已停止的容器机器整体变卡多个程序一起变慢宿主机整体资源余量看正在运行的容器各自占用多少每次没的都是同一个组件该组件自身的配置或日志先看它自己的输出再回到资源这一层每次没的都是占用最大的那个资源这一层看守护进程一侧的整体容量口径1.3 本文只讲资源层先把范围说清楚。本文讲的是资源层容器有没有上限、上限由谁定、撞到上限之后是谁来做决定。有几件事本文不写不讲挂载与文件、不讲磁盘占用与清理、不讲权限位读法、不给任何可以照抄的资源参数示范也不含任何攻击步骤与利用手法。文中出现的每一条命令都只做看这件事不改变你环境里的任何东西。二、前提默认情况下容器没有任何上限2.1 官方原话是这么写的要理解容器为什么能把整台机器拖住得先接受一个前提不加任何参数的时候容器身上是没有资源上限的。Docker 官方文档在讲资源约束的那一页开门见山写了这一句逐字引用By default, a container has no resource constraints and can use as much of a given resource as the host’s kernel scheduler allows.中文意思是默认情况下容器没有资源约束某个资源能用多少取决于宿主机的内核调度器允许给多少。2.2 这句话真正说的是什么不少人会把默认没有限制读成默认给得少方向正好相反。它说的是容器不开口要宿主机也不主动拦只要机器上还有它就能拿。这里有两个角色要分清。一个是容器它对自己用了多少、机器上还剩多少往往并不清楚另一个是宿主机的内核它是真正做决定的那一方。没有上限的时候容器会一路用下去直到内核发现系统本身快撑不住了才会出手。也就是说在撞上那堵墙之前你收不到任何提醒。所以靶场跑着跑着不见了这件事很多时候并不是容器做错了什么而是它一直在正常地用资源直到整台机器的余量被吃光。2.3 为什么靶场特别容易撞上这一层一个靶场镜像里装的东西通常不只是一段网页代码。为了让环境开箱可用镜像里往往同时带着 Web 服务器、应用运行环境、数据库有的还额外带着缓存或队列组件。这些组件是绑在一起启动的你只敲了一条启动命令背后起来的是好几件事。于是我只开了两个靶场这句话换算到资源层面就变成了好几个组件同时在跑。这解释了一个常见现象有人单开一个没事一开第二个就开始卡。不是第二个特别重而是余量本来就不多。顺带说一句官方靶场集合 Vulhub 在自己的 README 里给过一条资源建议「推荐使用至少 1GB 内存的 VPS 或虚拟机」截至 2026-09-25 仍为该口径。这条建议的性质值得留意它说的是跑这类环境本身需要一个内存下限也就是说资源需求是有门槛的能启动和够用不是一回事。三、内核这一层内存不足的时候会发生什么3.1 官方对这个机制的完整表述顺着上一章往下问如果真的把机器吃干了会发生什么Docker 官方文档给了明确回答。这里要先分清一件事官方写的是机制不是一段会出现在你屏幕上的提示文本。本文只用中文概述这个机制不贴任何运行时提示。官方的大意是这样的。在 Linux 宿主机上如果内核检测到内存不足以完成重要的系统功能它会进入一种被官方称为 OOM即内存不足的状态并开始终止进程来释放内存。关键在于后半句任何进程都可能被终止包括 Docker 本身以及其他重要的应用程序。官方还补了一句后果——如果被杀掉的是不该杀的那个进程有可能把整个系统拖垮。把这段翻成一句能记住的话内存不足时出手的是内核方式是终止进程而它挑谁并不看你的心情。3.2 最有用的一条为什么先没的往往是你的容器官方文档里有一条写得很直白、但很多人没有读到的说明逐字引用Docker attempts to mitigate these risks by adjusting the OOM priority on the Docker daemon so that it’s less likely to be killed than other processes on the system. The OOM priority on containers isn’t adjusted. This makes it more likely for an individual container to be killed than for the Docker daemon or other system processes to be killed.官方说得很清楚Docker 会调整守护进程的 OOM 优先级让它比系统上其它进程更不容易被终止而容器的 OOM 优先级没有被调整。结论官方也直接给了这使得单个容器比守护进程或其它系统进程更可能被终止。这就是本文开头那个现象在文档里对应的那句话。你在容器列表里看到的少了一个很可能不是它运行出错了而是在一次内存不足里被优先选中了。3.3 所以重启通常解决不了问题理解了这一层就能明白为什么重启一下重装一遍经常是无效动作容器被终止的原因不在容器内部而在整台机器的余量上。你把它重新起来只要余量还是那么紧它就会再一次走进同一条路。所以顺序应该反过来——先确认这件事是不是发生在资源这一层再决定要不要去动容器的配置。四、上限怎么设以及上限是怎么算的4.1 参数名以及它的下限既然默认没有上限那第一步就是在容器这一侧给它一个上限。Docker 官方文档里管这件事的参数名叫--memory也可以简写成-m。官方对它的说明是逐字引用The maximum amount of memory the container can use. If you set this option, the minimum allowed value is6m(6 megabytes). That is, you must set the value to at least 6 megabytes.这里只需要记住两件事它是容器可用内存的最大值设了它之后能接受的最小值是 6 兆字节不能再比这更小。至于它写在启动命令的哪个位置请以你自己的工具官方文档为准——本文不给可照抄的执行示范只讲这个参数名代表什么。4.2 硬上限与软上限设了上限之后还有一个容易混淆的区分这条上限是硬性的还是可以商量的。官方把两类分开讲逐字引用Hard limits let the container use no more than a fixed amount of memory. Soft limits let the container use as much memory as it needs unless certain conditions are met, such as when the kernel detects low memory or contention on the host machine.口径官方怎么说对练习环境意味着什么硬上限容器不得使用超过一个固定量的内存这条线是随时生效的机器再有余量也不会被多吃软上限允许容器用到它需要的量除非满足某些条件官方举的条件是内核检测到低内存或宿主机出现争用平时不会收紧注意软上限那句里的条件。它允许容器用到它需要的那么多除非出现某些情况——官方举的例子是内核检测到低内存或者宿主机上出现争用。也就是说软上限不是一条随时生效的线而是一条在压力下才收紧的线。对练习环境来说这个区别的意义很实际只有硬上限才谈得上不把机器上别的东西挤出去。4.3 给练习环境设上限是在保护你自己的机器很多人第一次看到限制内存这个词会本能地觉得这是在限制靶场怕关卡跑不动。这个理解反了。在没有上限的前提下环境的运行方式不是用够就好而是有多少用多少。给它一个上限是把这条曲线按住让机器上其它东西还有余量。这里还有一条官方动作可以配套看在给环境定量之前官方建议先做测试弄清这个应用实际需要多少内存。这条对靶场同样成立——先看它平稳跑起来大概占多少再定一条比它宽裕、但不至于把整台机器交出去的线。五、swap 这一层以及一个最常见的误读5.1 swap 是修饰项不是独立开关内存之外还有一层就是 swap。官方对它的定位说得很清楚逐字引用is a modifier flag that only has meaning if--memoryis also set. Using swap allows the container to write excess memory requirements to disk when the container has exhausted all the RAM that’s available to it. There is a performance penalty for applications that swap memory to disk often.两个要点它是修饰项只有在--memory也设了的时候才有意义另外用 swap 意味着超出内存的那部分被写到磁盘上官方也点明了代价——频繁换出换入会有性能损耗。5.2 三种设置语义完全不同官方给了--memory-swap三种典型的设置方式语义差别很大这条参数的设置官方语义换成白话与--memory设为同一个值容器用不到 swap相当于把 swap 这条路关掉不设而--memory已设容器可使用的 swap 量与--memory等量前提是宿主机配了 swap只管了内存swap 的量由内存上限推导出来显式设为-1允许无限使用 swap直到宿主机上可用的量为止上限交给宿主机容器自己不再设限三条并排看最容易踩的是第二条不设--memory-swap而只设了--memory时容器能用的 swap 量是与内存上限等量的。也就是说“我只管了内存并不等于swap 也一并管住了”。5.3 在容器里看内存看到的不是你以为的那个数这一章最值得记住的是官方专门提醒的一个误读逐字引用Inside the container, tools likefreereport the host’s available swap, not what’s available inside the container. Don’t rely on the output offreeor similar tools to determine whether swap is present.官方说得很直接在容器里用free这类工具看到的是宿主机的可用 swap不是容器内可用的那一份不要把这类输出当成容器里有没有 swap的依据。这一条为什么重要因为排障时最容易犯的错就是拿一个看起来是容器内部的数去下结论。你在容器里看到的那个数字其实是整台机器的拿它判断我这个靶场有没有被限制住方向从第一步就错了。正确的做法是回到宿主机这一侧用守护进程给出的整体信息来判断。⚠️代码待验证dockerinfo# 在宿主机一侧看守护进程给出的整体信息5.4 还有一个值是从宿主机继承来的官方另给了一条关于--memory-swappiness的口径取值0表示关闭匿名页换出取值100表示所有匿名页都可换出而如果你根本不设它这个值是从宿主机继承来的。这条的价值不在于该设成几而在于提醒你容器里有一个你从没写过的参数它的值不是你定的是你那台机器定的。排障时碰到同样的配置在别人机器上表现不一样这类继承来的默认值就该先排除。下面这份资料把资源这一层的判断顺序整理成了一页和本章的 swap 误读呼应配套资料把容器有没有上限、swap 怎么算、在哪里看才是对的整理成一页放在资料包里扫码即可获取六、官方的四条动作和一条明确的别这么做6.1 官方给的四条缓解动作讲完机制官方在文档里也给了应对方向。原文一共四条都是事前动作不是出事之后的补救⚠️代码待验证官方给出的四条缓解动作大意照抄官方口径 1. 把应用投入使用之前先做测试弄清它到底需要多少内存。 2. 确保你的应用只跑在资源足够的机器上。 3. 给容器能使用的内存设一个上限。 4. 在宿主机上配置 swap 时要有意识swap 比内存慢但可以作为内存耗尽前的一层缓冲。官方动作它防的是什么落到靶场上的做法先测出需要多少内存凭感觉定量定得太紧或太松先让环境平稳跑一遍看它平时的占用水平只在资源足够的机器上跑一开始就把机器放在悬崖边上别在同时跑着其它重负载的机器上练给容器设内存上限一个容器把整机余量吃光用硬上限把这条曲线按住留意 swap 配置以为没配 swap 其实配了或以为配了其实没配回到宿主机一侧确认别在容器里下结论四条里最容易被跳过的是第一条和第二条。它们不是技术动作而是判断动作先知道要多少再决定在哪跑。很多人出问题恰恰是这两步没做直接跳到第三条去调参数。6.2 官方明确劝阻的一件事如果读到这里你想的是那能不能让它别终止我的容器官方对这件事有一句明确的劝阻逐字引用You shouldn’t try to circumvent these safeguards by manually setting--oom-score-adjto an extreme negative number on the daemon or a container, or by setting--oom-kill-disableon a container.官方原话是你不应该试图通过手动把守护进程或容器上的--oom-score-adj设成一个极端的负数或者给容器设上--oom-kill-disable来绕过这些保护措施。这句话值得多读一遍。它把前面那套内存不足时内核终止进程的机制明确定位成保护措施而不是一个要修掉的毛病。你想办法让它不生效等于把保护措施拆掉风险就从一个容器退出变成整台机器出问题。这也回答了一个很常见的思路——能不能让它别动我的容器官方的态度是不要这么做。6.3 一条前置条件和一条官方红线如果确实要动终止机制官方给了前提条件逐字引用By default, if an out-of-memory (OOM) error occurs, the kernel kills processes in a container. To change this behavior, use the--oom-kill-disableoption. Only disable the OOM killer on containers where you have also set the-m/--memoryoption. If the-mflag isn’t set, the host can run out of memory and the kernel may need to kill the host system’s processes to free memory.官方要求只有在同时设了内存上限的容器上才允许关闭这个机制。理由官方也写了——如果没设内存上限宿主机可能真的把内存耗尽内核就可能需要终止宿主机上的进程来释放内存。也就是说你以为你在保护容器实际是把风险挪给了整台机器。最后补一条官方口径。Vulhub 在自己的 README 注意事项里写着「所有环境仅供测试与学习严禁用于生产环境」该条沿用原核验日期 2026-09-16。配着本章看意思很完整这类环境本来就该待在资源可控、随时可以推倒重来的地方。给你的练习环境配多少资源、放在哪台机器上跑本身就是使用这类环境的一部分。七、把这一层变成动作7.1 三个只读动作前面几章讲的都是判断这一章给动作。三条动作全部都只是看不改变你环境里的任何东西。第一步看容器还在不在。⚠️代码待验证dockerps# 看正在运行的容器dockerps-a# 看包括已停止的容器在内这一步回答的是开头分流里的第一个问题。重点不是看它运行得好不好而是先确认它在不在。第二步看正在运行的容器各自用了多少。⚠️代码待验证dockerstats# 看正在运行的容器的实时资源占用这一步的价值在于横向对比同一台机器上哪个容器明显偏高。如果你发现每次出问题的都是占用最大的那一个第三章那条容器比守护进程更可能被终止就在你这里落地了。第三步看守护进程一侧的整体情况。⚠️代码待验证dockerinfo# 看守护进程视角的整体配置与容量信息dockerversion# 确认你在跟哪一个客户端与守护进程打交道docker info回答的是这台机器被交出去多少docker version用来确认你面对的是哪一个守护进程两条同样不涉及改动。7.2 现象到动作的对照表把前面几章的判断收成一张表出问题时按行对号现象更可能落在哪一层先做哪个只读动作容器突然不在了机器其它程序正常资源层里某一个容器被终止看容器列表再对它做一次排查一开第二个靶场整机就卡宿主机整体资源余量看正在运行的容器各自占用在容器里查内存数字对不上直觉看到的其实是宿主机的量回到守护进程一侧看整体信息想让它别终止我的容器官方明确劝阻的那条路停下来先补上内存上限同样的配置在别人机器上表现不同有从宿主机继承来的值先确认哪些参数你没设过这张表只需要记住一句先定位到层再决定动作。定位在前动作在后。7.3 一页自检表与三条可带走的动作出问题的时候先把下面这张自检表过一遍它把前面几章的问题收成了六行检查项为什么查它在哪一层这台机器同时还在跑什么余量是共享的别人也在用宿主机容器有没有设过内存上限默认没有上限这是最常见的缺口容器上限是硬的还是软的只有硬上限才随时生效容器swap 到底配了没有不能拿容器内的数字下结论宿主机消失的是不是总在变总在变说明不是某个组件的毛病资源层我想做的动作是不是绕过官方明确劝阻过这条路判断三条可以带走的动作先分流只有容器没了还是整台机器一起慢。再看全局先看守护进程一侧的容量口径再看单个容器的占用。别绕过不要用极端优先级或关闭终止机制来解决这件事。本文的使用限制所有命令均为待验证本文写作环境没有可用的 docker 环境文中每条命令都没有实际运行过因此全部标了代码待验证参数写法与默认行为请以各自官方文档为准。本文不写任何命令的输出文本只描述现象与机制不贴运行结果、不贴任何提示原文。本文不给可照抄的资源参数示范--memory这类只作为参数名在正文里解释含义不写成让读者照着敲的命令。其它层不在本文范围挂载与文件、磁盘占用与清理、权限位读法均另有专文本文也不含任何攻击步骤与利用手法。把这一层的判断顺序整理成一页放在资料里和本章的自检表呼应配套资料把分流、看全局、别绕过三步和上面这张自检表合成一页放在资料包里扫码即可获取附表 A本文引用事实与官方出处对照表#事实照口径一手出处核验日期本文位置1官方原文By default, a container has no resource constraints and can use as much of a given resource as the host’s kernel scheduler allows.默认情况下容器没有资源约束https://docs.docker.com/engine/containers/resource_constraints/2026-09-25第 2 章2「推荐使用至少 1GB 内存」的 VPS 或虚拟机https://github.com/vulhub/vulhubVulhub 官方 README2026-09-16第 2 章3内存不足时内核会终止进程以释放内存任何进程都可能被终止包括 Docker 本身与其他重要应用若杀错进程可能拖垮整个系统。官方把这一机制称为 OOM内存不足https://docs.docker.com/engine/containers/resource_constraints/2026-09-25第 3 章4官方原文Docker attempts to mitigate these risks by adjusting the OOM priority on the Docker daemon so that it’s less likely to be killed than other processes on the system. The OOM priority on containers isn’t adjusted. This makes it more likely for an individual container to be killed than for the Docker daemon or other system processes to be killed.容器比守护进程更可能被终止同第 1 行2026-09-25第 3 章5官方原文The maximum amount of memory the container can use. If you set this option, the minimum allowed value is6m(6 megabytes). That is, you must set the value to at least 6 megabytes.同第 1 行2026-09-25第 4 章6官方原文Hard limits let the container use no more than a fixed amount of memory. Soft limits let the container use as much memory as it needs unless certain conditions are met, such as when the kernel detects low memory or contention on the host machine.同第 1 行2026-09-25第 4 章7官方给出的四条缓解动作先做测试弄清应用的内存需求确保应用只跑在资源足够的宿主机上给容器可用的内存设上限在宿主机上配置 swap 时需留意swap 比内存慢但可作为内存耗尽时的缓冲同第 1 行2026-09-25第 4、6 章8官方原文is a modifier flag that only has meaning if--memoryis also set. Using swap allows the container to write excess memory requirements to disk when the container has exhausted all the RAM that’s available to it.swap 是修饰项代价是性能损耗同第 1 行2026-09-25第 5 章9--memory-swap三种语义与--memory同值则容器用不到 swap不设而--memory已设则可用与--memory等量的 swap显式设为-1则允许无限使用直到宿主机可用量为止同第 1 行2026-09-25第 5 章10官方原文Inside the container, tools likefreereport the host’s available swap, not what’s available inside the container. Don’t rely on the output offreeor similar tools to determine whether swap is present.同第 1 行2026-09-25第 5 章11--memory-swappiness的 0 表示关闭匿名页换出、100 表示所有匿名页可换出不设该值时取值继承自宿主机同第 1 行2026-09-25第 5 章12官方原文You shouldn’t try to circumvent these safeguards by manually setting--oom-score-adjto an extreme negative number on the daemon or a container, or by setting--oom-kill-disableon a container.同第 1 行2026-09-25第 6 章13官方原文Only disable the OOM killer on containers where you have also set the-m/--memoryoption. If the-mflag isn’t set, the host can run out of memory and the kernel may need to kill the host system’s processes to free memory.同第 1 行2026-09-25第 6 章14「所有环境仅供测试与学习严禁用于生产环境」https://github.com/vulhub/vulhubVulhub 官方 README 注意事项⑤2026-09-16第 6 章说明第 1、3–13 行的 Docker 官方事实由本批次于2026-09-25一手核验第 2、14 行为沿用的已核验事实核验日期保留原锚点 2026-09-16未改标。本文所有命令均未实测已在正文逐处标注代码待验证。附表 B术语速查表术语一句话解释资源层本文的观察对象容器能用多少、有没有上限、撞上上限时谁做决定资源约束官方对给容器设定资源上限这件事的说法默认情况下一个都没有OOM内存不足官方对内核检测到内存不足以完成重要系统功能这一机制的称呼终止进程内核在内存不足时的出手方式任何进程都可能被选中包括 Docker 自己守护进程容器背后的管理进程官方会调低它被终止的概率容器这一侧则不调硬上限容器不得使用超过一个固定量的内存随时生效软上限允许用到需要的量仅在特定条件如低内存或争用下才收紧swap把超出内存的部分写到磁盘上比内存慢但可作为耗尽前的缓冲修饰项官方对 swap 相关参数的定位不先设内存上限它单独设没有意义继承值你没写过的参数取值来自宿主机常见于 swap 倾向这一项只读动作本文给出的全部动作类型只看不改不启动、不删除、不修改配置代码待验证本文命令未在本机实测的标记请以官方文档为准写在最后这篇用到的资料写这篇文章时我把 Docker 官方讲资源约束的那一页通读了一遍。发现容器跑着跑着不见了这个现象官方把机制写得很清楚默认没有上限、内存不足时内核会终止进程、而容器的优先级没有被调整所以先被选中的往往是容器。这几句散在不同段落里于是顺手整理了几份配套的东西靶场环境对照表DVWA、upload-labs 在 Windows / macOS / Linux 三平台的可行性与推荐路径Web 安全学习路线图从基础打牢到安全管理四个阶段各学什么常用靶场清单每个靶场练什么、适合哪个阶段资料是我自己整理的放在下面这个码上扫码即可获取添加时备注「靶场」优先通过。拿到之后建议先看环境对照表那一份先把这台机器还要同时跑什么想清楚再回头看你的容器有没有上限——资源这一层的问题多数是在这里定下来的。