我编写了一个简单的go应用程序,并添加了一个flock系统,以防止同时运行两次:
import "github.com/nightlyone/lockfile"
lock, err := lockfile.New(filepath.Join(os.TempDir(), "pagerduty-read-api.lock"))
if err != nil {
panic(err)
}
if err = lock.TryLock(); err != nil {
fmt.Println("Already running.")
return
}
defer lock.Unlock()
Run Code Online (Sandbox Code Playgroud)
它在我的主机上运行良好。在docker上,我尝试通过以下方式共享卷tmp
:
docker run --rm -it -v /tmp:/tmp my-go-binary
Run Code Online (Sandbox Code Playgroud)
但这行不通。我想这是因为羊群系统没有移植到卷共享上。
我的问题:Docker是否可以选择让群集在正在运行的实例之间工作?如果没有,那么我具有相同行为的其他选择是什么?
谢谢。
今天早上我写了一个小 Python 测试程序,它只是将一百万个连续的整数写入文件,使用 flock() 锁定,为每个附加的数字获取和释放一次锁定。我启动了 5 个容器,每个容器都运行该测试程序,每个容器都写入 docker 卷中的同一个文件。
启用锁定后,数字全部写入而不会相互干扰,文件中正好有 500 万个整数。以这种方式编写时它们不是连续的,但这是预期的并且与 flock() 工作一致。
在没有锁定的情况下,许多数字的书写方式表明这些数字与无锁定的多任务处理相冲突。文件中只有 3,167,546 个数字,并且有 13,357 个空白行。加起来就是文件中的 3,180,903 行 - 与所需的 5,000,000 行大不相同。
虽然程序无法明确证明仅通过多次测试永远不会出现问题,但对我来说,Linux flock() 可以跨容器工作是一个非常有说服力的论点。
此外,flock 可以跨容器工作是有道理的。容器几乎只是一个共享内核、不同的 pid、不同的文件(卷除外)和不同的 IP 端口空间。
我在带有 Linux 内核 4.15.0-20-generic、Docker 19.03.0 的 Linux Mint 19.1 系统上运行我的测试 - 构建 aeac949 和 CPython 3.6.8。
Go 是一种很酷的语言,但我不知道为什么 flock() 在你的 Go 程序中似乎没有跨卷工作。
哈。
我想您想使用 dockervolume 或者您可能需要一些其他dockervolume 插件。
根据这篇文章Docker Volume File 权限和锁定,docker Volumes 仅提供了一种定义卷供多个容器使用或由容器重新启动后使用的方法。
在 docker 卷插件中,flocker 可能会满足您的要求。 Flocker 是一个适用于 Docker 化应用程序的开源容器数据卷管理器。
顺便说一句,如果您使用 kubernetes,您可能需要了解有关持久卷、持久卷声明、存储类的更多信息。