文章

记一次 VPS 硬盘容量爆炸修复

1月20日突然发现服务器的很多服务停了,也没法用 VS Code SSH 进去,进行了一番修复。

1月20日起床,我发现有几个运行在服务器上的 Telegram Bot 停止了运行。

躺在床上,赶紧用手机上的 JuiceSSH 进去看了一下,有好几个 Docker 服务都停了。其中一个是我 Telegram Bot 的自建 API 服务器,提示

1
can't create directories in the directory "/var/lib/telegram-bot-api/". Use --dir option to specify a writable working directory

我觉得很奇怪,一开始以为是 Docker Image 出了问题。于是起床打开电脑,发现居然无法用 VS Code 的 Remote 功能 SSH 进入服务器。

1
Failed to connect to the remote extension host server (Error: WrappedError(WrappedError { message: "error unpacking /root/.vscode-server/cli/servers/Stable-cd4ee3b1c348a13bafd8f9ad8060705f6d4b9cba.staging/server/node_modules/@xterm/addon-webgl/lib/addon-webgl.mjs.map", original: "Custom { kind: StorageFull, error: TarError { desc: \"failed to unpack vscode-server-linux-x64/node_modules/@xterm/addon-webgl/lib/addon-webgl.mjs.map into /root/.vscode-server/cli/servers/Stable-cd4ee3b1c348a13bafd8f9ad8060705f6d4b9cba.staging/server/node_modules/@xterm/addon-webgl/lib/addon-webgl.mjs.map\", io: Os { code: 28, kind: StorageFull, message: \"No space left on device\" } } }" }))

反复尝试后无果。直接复制这段问 ChatGPT 老师。回答说“The error message indicates that the system is running out of disk space (No space left on device)”。

于是进一步询问如何查容量使用。

1
2
df -h
du -ah / | sort -rh | head -n 20

然而由于空间已经所剩无几,连运行完检索最大20个文件的 pipeline 的容量都不足了。因为我服务器上所有的服务都是跑在 Docker 上的,我估计大概率又是哪个 Docker 容器出问题了。

于是我先清理了一下不用的容器

1
docker prune image

有了空间再运行 du -ah / | sort -rh | head -n 20

1
2
3
4
5
6
7
8
9
10
11
12
13
14
76G     /var/lib/docker/overlay2/c4fd02de5c772625977613bd995d71be1faa6f8fd237d54c88028b6b75123240
39G     /var/lib/docker/overlay2/c4fd02de5c772625977613bd995d71be1faa6f8fd237d54c88028b6b75123240/merged
38G     /var/lib/docker/overlay2/c4fd02de5c772625977613bd995d71be1faa6f8fd237d54c88028b6b75123240/merged/tmp/rod/user-data
38G     /var/lib/docker/overlay2/c4fd02de5c772625977613bd995d71be1faa6f8fd237d54c88028b6b75123240/merged/tmp/rod
38G     /var/lib/docker/overlay2/c4fd02de5c772625977613bd995d71be1faa6f8fd237d54c88028b6b75123240/merged/tmp
38G     /var/lib/docker/overlay2/c4fd02de5c772625977613bd995d71be1faa6f8fd237d54c88028b6b75123240/diff/tmp/rod/user-data
38G     /var/lib/docker/overlay2/c4fd02de5c772625977613bd995d71be1faa6f8fd237d54c88028b6b75123240/diff/tmp/rod
38G     /var/lib/docker/overlay2/c4fd02de5c772625977613bd995d71be1faa6f8fd237d54c88028b6b75123240/diff/tmp
38G     /var/lib/docker/overlay2/c4fd02de5c772625977613bd995d71be1faa6f8fd237d54c88028b6b75123240/diff
4.3G    /var/lib/docker/volumes
3.0G    /var/lib/docker/overlay2/3762ba957ba504bf1fe2de7e08b46ab449133ccb2292fab0f61e26901efb916e/merged
3.0G    /var/lib/docker/overlay2/3762ba957ba504bf1fe2de7e08b46ab449133ccb2292fab0f61e26901efb916e
2.8G    /var/lib/docker/overlay2/64759dec53597f35b23513cf7bec2880d43ef6acc79ece0338a5d0ec314702c7/merged
2.8G    /var/lib/docker/overlay2/64759dec53597f35b23513cf7bec2880d43ef6acc79ece0338a5d0ec314702c7

虽然不知道是哪个容器造成的容量无限吞噬,只好直接 docker prune 了,然后关闭 Docker,手动移除/var/lib/docker/overlay2/c4fd02de5c772625977613bd995d71be1faa6f8fd237d54c88028b6b75123240 目录。

之后就好了,好像也没啥事。


更新:

手动移除 /var/lib/docker/overlay2/ 是不合适的。实际上这些文件是 Docker container 挂载在硬盘的文件目录。只要关闭对应的 container,这些文件就会立刻消失。

可以使用这个命令查看哪个目录占空间最多:

1
du -h --max-depth=1 /var/lib/docker/overlay2 | sort -hr | head -20

Claude 帮我写了一个脚本查看每个目录对应的 container 是哪个:

1
2
3
4
5
6
for container in $(docker ps -q); do
  echo "Container: $(docker inspect --format '' $container)"
  echo "ID: $container"
  echo "Overlay: $(docker inspect --format '' $container)"
  echo "---------------------------------------"
done

查出来后关掉对应的 container 就好。

本文由作者按照 CC BY 4.0 进行授权