Skip to content

mayooot/ballast-docker-container

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ballast-docker-container

当使用 --storage-opt size=xGi 限制容器系统盘大小后,如果磁盘使用满后,会导致 docker start/restart 操作失败, 这个项目通过提前设置一个 /ballast 文件,提供一个解决思路。

前提知识

在售卖容器时,通常会限制容器系统盘大小,也就是 / 目录的大小,使用 XFS 文件系统 配合 --storage-opt 参数即可实现。

但是当用户长时间使用容器时,容器系统盘会满,一旦容器被停止,再次启动时就会报错。错误信息如下:

Error response from daemon: mkdir /localData/docker/overlay2/7adae703b531d3e114cd171999e5502fe685e13835569b6f1d9fb31ab812773b/merged: disk quota exceeded 

当然容器运行过程中这些都属于临时数据,如果用户想要持久化其实使用虚拟机更满足这种场景,而且还很方便的扩容缩容,而且作为一个平台应该 “教育” 用户正确使用容器,并让他们不要把容器当做虚拟机一样使用。

但是我确实在工作中遇到了这种情况,更改项目架构也不可能,所以经过和朋友讨论思考后,想到一种简单的方法来尝试解决这个问题。

实现思路

代码实现:container.go

Run

当用户开通一个容器,我们会限制用户容器的系统盘大小,比如说默认 20Gi 的空间,但是通过程序开通容器时,我们使用 --storage-opt size=xGi 限制时会把系统盘大小设置为 20Gi + 5Gi,5Gi 的文件作为一个 ballast(压舱石)存在于用户的容器中。

当用户使用了 19.9Gi(实际情况下要比这个数字更接近 20Gi) 的空间后,df -h 显示如下内容:

$ df -h
Filesystem                             Size    Used   
/                                      25Gi    24.9Gi

Stop

重点在 Stop 时,如果说 Used 已经很接近 Size 了,那么我们就调整 ballast 的大小,保证用户容器正确启动。

⚠️ 注意:虽然说容器启动时,可能只需要 几B 的空间,但是无论如何都不应该删除用户容器内的任何数据。

举个例子,当 Used 已经为 24.9Gi,限制的大小为 25Gi,我们 Stop 时,把 ballast 的大小减小 0.5Gi, 保证用户容器正确启动。

运行

$ git clone https://github.com/mayooot/ballast-docker-container.git
$ cd ballast-docker-container

$ go mod tidy

$ go test -v -run TestDockerContainerRun
$ go test -v -run TestDockerContainerStop
$ go test -v -run TestDockerContainerStart

$ docker exec -it test stat -c %s /ballast
4500000000

$ go test -v -run TestDockerContainerRemove

贡献

如果对你有帮助,欢迎 star 或者 fork 项目,也欢迎发起 issue 或者 pull request。

About

An example about limiting the storage of docker containers

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages