跳转到内容
View in the app

A better way to browse. Learn more.

彼岸论坛

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.
欢迎抵达彼岸 彼岸花开 此处谁在 -彼岸论坛

[Docker] 使用 Ballast 文件解决 Docker 容器磁盘占满无法启动的问题

发表于

使用 Ballast 文件解决 Docker 容器磁盘占满无法启动的问题

背景

在容器开发工作中,售卖算力容器是一个很常见的需求,不管是用 Docker 容器还是 K8s Pod 交付。

其中有一个问题是:我们提供给用户的容器默认是没有限制 / 目录的,虽然说这些都是临时文件,真正需要持久化的文件我们可以提供分布式存储,然后挂载到用户容器的某个目录。

一个简单而有效的方式是使用 XFS 文件系统配合 --storage-opt 参数就能限制用户容器的 / 目录,也可以说是限制用户容器的系统盘大小。

问题

但是当用户长期使用一个容器,比如在容器里进行模型训练,会导致系统盘空间越来越小,当系统盘空间已经非常接近我们设置的大小时,例如限制系统盘大小为 20Gi ,用户已经使用了 19.9999Gi ,这时候当用户 Stop 了容器(关机),再次 Restart/Start 容器(开机)时很可能会失败。

报错信息如下:

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

这好像没什么好的解决办法,因为造成问题的原因是用户把容器当成了虚机来用,一般情况下我们也不会持久化用户容器的临时文件。

但目前确实遇到了这个问题,所以和朋友一番讨论后,想出来了一个思路。

实现思路

前段时间研究了一下 Golang 控制 GC 频率的方法,其中使用的是 ballast ,就像下面代码中: 初始化了一个生命周期贯穿整个 Go 应用的超大 Slice ,保证 GC 在 10G 的一倍时才被触发。

详情参考这篇文章 性能优化 | Go Ballast 让内存控制更加丝滑

package main

import "runtime"

func main() {
	ballast := make([]byte, 10*1024*1024*1024) // 10G

	// do something

	runtime.KeepAlive(ballast)
}

所以脑洞大开,我们能不能也用 ballast 的思想来为容器提供一个 ballast ,当容器磁盘不足时,我们手动减少这个 “压舱石” 的大小,这样就能能保证容器关机后,再次重启时,不会因为磁盘不足,导致失败了。

当然这样的操作是基于一个前提的,就是:

无论如何都不应该删除用户容器里的任何东西,即使是日志或者垃圾文件。

所以使用一个人畜无害的压舱石,可能是比较优雅的方式。

坏处也很明显,就是用户可以删除这块压舱石,并且用户 df -h 看到的空间是和实际购买的不一样。

具体实现

用户开通容器时

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

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

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

用户关机时

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

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

源码地址

ballast-docker-container

如果对你有帮助,请给我一个 Star

Featured Replies

No posts to show

创建帐户或登录来提出意见

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.