在宿主机挂载NFS并将目录映射到Docker容器时,如果Docker容器在NFS挂载完成之前启动,可能会导致容器无法找到挂载的目录。为了解决这个问题,可以通过修改 docker.service 文件来确保Docker服务在NFS挂载完成后再启动。以下是详细步骤:


1. 确认NFS挂载的 systemd 服务名称

首先,需要确认NFS挂载的 systemd 服务名称。通常,NFS挂载会通过 systemd.mount 单元管理。

  1. 查看NFS挂载的 .mount 单元名称:
    systemctl list-units --type=mount
    # 或者
    systemctl list-units | grep mount
    输出示例:
    mnt-nfs.mount
    
    这里的 mnt-nfs.mount 就是NFS挂载的 systemd 服务名称,一般会以mnt开头。

2. 修改 docker.service 文件

通过修改 docker.service 文件,添加依赖关系,确保Docker服务在NFS挂载完成后启动。

  1. 备份并编辑 docker.service 文件:

    cp /lib/systemd/system/docker.service /lib/systemd/system/docker.service.bak
    vim /lib/systemd/system/docker.service
  2. [Unit] 部分添加以下内容:

[Unit]
After=nfs.mount
Requires=nfs.mount

其中,nfs.mount 是NFS挂载的 .mount 单元名称(根据第一步确认的名称替换)。

  • 如果NFS挂载是必须的
  • 使用 Requires,确保NFS挂载成功后再启动Docker服务。
  • 示例:
[Unit]
After=nfs.mount
Requires=nfs.mount
  • 如果NFS挂载是可选的
  • 使用 Wants,允许Docker服务在NFS挂载失败的情况下仍然启动。
  • 示例:
[Unit]
After=nfs.mount
Wants=nfs.mount

修改后的 docker.service 文件示例:

[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service nfs.mount
Requires=nfs.mount
Wants=network-online.target
 
[Service]
Type=notify
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
  1. 保存并退出编辑器。

3. 重新加载 systemd 配置并重启Docker服务

修改完成后,需要重新加载 systemd 配置并重启Docker服务。

  1. 重新加载 systemd 配置:
sudo systemctl daemon-reload
  1. 重启Docker服务:
sudo systemctl restart docker

4. 验证配置是否生效

验证Docker服务是否在NFS挂载完成后启动。

  1. 查看Docker服务的启动顺序:
systemctl list-dependencies docker.service

输出中应该包含 nfs.mount,表示Docker服务依赖于NFS挂载。

  1. 重启宿主机,观察Docker容器是否能够正常访问NFS挂载的目录。

5. 注意事项

  • 如果NFS挂载失败,Docker服务将不会启动。因此,确保NFS挂载配置正确。
  • 如果NFS挂载的 .mount 单元名称不是 nfs.mount,请根据实际情况替换为正确的名称。
  • 如果使用 docker-compose 或其他容器编排工具,仍需确保NFS挂载在容器启动前完成。

总结

通过修改 docker.service 文件,添加 After=nfs.mountRequires=nfs.mount 依赖关系,可以确保Docker服务在NFS挂载完成后启动,从而避免容器找不到挂载目录的问题。这是一种简单且有效的方法,适用于使用 systemd 的Linux系统。