docker-compose 等待启动,直到挂载主机文件系统
Posted
技术标签:
【中文标题】docker-compose 等待启动,直到挂载主机文件系统【英文标题】:docker-compose wait to launch until a host filesystem is mounted 【发布时间】:2021-04-01 19:21:58 【问题描述】:这个问题的重点是强制 docker-compose 等待启动 mysql 容器,直到挂载主机文件系统。在我的例子中,主机文件系统保存着 mysql 数据库文件。
对于依赖于 mysql 容器的服务,有一些脚本,例如 wait-for-it,它们作为容器入口点的一部分运行。这些脚本检查网络端口上服务的可用性。但我看不到如何让容器启动等待文件系统安装在主机上。
当主机启动时,NFS 和 RAID 文件系统的启动速度可能不如容器启动的快。如果文件系统在容器启动后挂载到主机上,则容器中的绑定卷不会更新。然后容器最终无法访问已安装/绑定的文件系统。
【问题讨论】:
假设您的系统使用 systemd(这很常见),解决方案是使docker
服务依赖于文件系统的适当 .mount
单元。这将阻止 docker 在文件系统挂载之前启动。例如。如here所述。
很好的答案@larsks。我假设您的意思是将mnt-mountpoint.mount
添加到/lib/systemd/system/docker.service
中After
行的末尾。我通过卸载文件系统然后停止并启动 docker 守护进程进行了测试。不幸的是,这些容器都是从卸载文件系统开始的。接下来我将测试重新启动。
对linked question 的更彻底阅读表明,我还需要将mnt-mountpoint.mount
添加到Requires
行。现在,如果文件系统未挂载,docker 服务将拒绝启动。 @larsks 请发布您的答案,以便我接受。
【参考方案1】:
假设您的系统使用 systemd(这很常见),解决方案是让 docker 服务依赖于文件系统的适当 .mount 单元。这将阻止 docker 在文件系统挂载之前启动。描述了添加对挂载点的依赖项,例如in this answer 结束 https://unix.stackexchange.com。
对于/etc/fstab
中列出的每个文件系统,systemd 都会生成一个名为<filesystem>.mount
的单元。例如,在我的系统上,/etc/fstab
包含以下内容:
/dev/tank/scratch /scratch xfs defaults 1 2
我看到以下 systemd 单元:
# systemctl list-units -t mount |grep scratch
scratch.mount loaded active mounted /scratch
我们可以通过在单元的[Unit]
部分添加类似以下内容来使 Docker 等服务依赖于这个挂载点:
[Unit]
Requires=scratch.mount
After=scratch.mount
Requires
指令的意思是“当你启动这个服务时(例如docker
),也启动这里列出的单元”,After
指令的意思是“启动这个之前的命名单元”。
【讨论】:
我相信这是正确的答案,但不幸的是它在系统启动期间对我不起作用。我认为这是因为 systemd 有一个 4 岁的 bug 正好涉及这种使用模式。我很难理解像 systemd 这样被数百万(?)Linux 主机使用的实用程序如何存在这样的错误。变通办法的贡献将不胜感激。我的 Ubuntu 18 系统运行 systemd 版本 237。 啊,真糟糕,我以为你表示它正在工作。明天有空的时候再仔细看看。 谢谢。它在您停止并启动 docker 守护程序之后 启动时起作用,但不是作为启动过程的一部分。【参考方案2】:最低级别的服务是mysql。修改它的入口点以在已知位于已挂载文件系统上的目录丢失时退出。
所有依赖服务都可以使用dockerize或wait-for-it脚本等待mysql网络端口打开。
mysql:
image: mysql:5.7.30
restart: always
entrypoint: ["bash", "-c", "touch /testdir/dir_on_filesystem/write-test && rm /testdir/dir_on_filesystem/write-test && echo 'Test for mounted filesystem passed' && mysqld --user=root"]
volumes:
- /mnt/mountpoint/mysql:/var/lib/mysql
- /mnt/mountpoint:/testdir
如果你能保证/mnt/mountpoint/mysql
在mysql容器第一次启动之前就存在于文件系统中,那么你可以使用那个目录代替/testdir/dir_on_filesystem
进行测试。
请注意,此入口点测试还确保文件系统不是以只读方式安装的。当 RAID 阵列在系统引导期间重新同步时,它可以以只读状态开始,直到重新同步取得一些进展。可写性检查并不是绝对必要的,因为如果 mysql 容器无法写入其数据库文件,它将退出。
【讨论】:
以上是关于docker-compose 等待启动,直到挂载主机文件系统的主要内容,如果未能解决你的问题,请参考以下文章
Docker部署Docker-compose部署redis容器及启动失败挂载失败等问题
Docker部署Docker-compose部署redis容器及启动失败挂载失败等问题