在 docker 容器中创建卷或挂载有什么区别?

YAT*_*PTA 5 containers docker

Docker 提供了两种方式来备份和同步本地机器上的容器数据,即volumemount。除了我注意到的一些事情之外,两者的行为方式都相同:

  1. 卷总是将数据保存在 /var/lib/docker/volumes 中,而挂载点可以在我们想要的任何地方创建。
  2. 如果分配了挂载点的容器也分配了卷,则来自挂载点的所有数据都会自动复制到卷,反之则不然。
  3. 我们无法在 Dockerfile 中描述挂载点,但可以在 Dockerfile 中提供卷。

好的,所以我们可以说方法论有一些优点和缺点,但在优化方面仍然存在一些分类或差异。

请提供一个解释性的答案。

BMi*_*tch 4

实际上有三种类型的卷:

  • 主机卷:您所说的容器中的挂载,更常见的术语是绑定挂载。
  • 命名卷:由您指定名称的 docker 管理的任何卷。
  • 匿名卷:任何没有源的卷,docker 都会将其创建为具有长唯一 ID 的本地卷,并且其行为类似于命名卷。

卷有源和目标。源标识卷的类型,因此文件/目录的路径(包括前导斜杠)会产生主机卷。如果您不提供来源,您将获得匿名卷。如果您在 Dockerfile 中定义卷,则无法在其中指定源,因此默认情况下 docker 将创建匿名卷,除非您在运行时以其他方式指示它。

对于每种类型,以下是优点/缺点:

  • 主持人:
    • Pro:轻松从主机访问底层文件
    • 缺点:当容器用户的 uid 与主机 gid 不匹配时,会出现 uid/gid 权限问题
    • 缺点:数据未初始化
  • 命名:
    • 优点:轻松在不同容器/图像之间创建重用。如果您只给它一个名称而没有其他设置,则本地驱动程序将默认将您的数据存储在 /var/lib/docker/volumes 中,该数据只能由 root 从 docker 外部访问。
    • Pro:当图像内容为空/新且创建容器时,将内容初始化为图像内容。此初始化包括图像的文件所有者和权限,这可以解决大多数 uid/gid 问题。
    • 优点:可以使用本地驱动程序连接到安装命令可以连接的任何东西,包括绑定安装或 NFS 安装。其他驱动程序允许您引用更多位置的数据(例如云提供商)。
    • 缺点:管理内容应该通过容器来完成。
  • 匿名的:
    • 优点:无需计划使用
    • 缺点:数据通常会丢失,因为没有从卷到创建它的容器/映像的映射。在我看来,这是存储卷的最糟糕的方式,也是任何人都不应该在 Dockerfile 中定义卷的原因。

如果可能,我使用命名卷。数据的初始化和更好地处理 uid/gid 问题胜过主机卷的便利性。如果我确实需要在 docker 外部直接访问数据,那么我会尝试使用指向绑定安装的命名卷,而不是默认的本地驱动程序设置。一个简单的例子是:

$ docker volume create --driver local \
  --opt type=none \
  --opt device=/home/user/test \
  --opt o=bind \
  test_vol
Run Code Online (Sandbox Code Playgroud)

为了定义我的卷,因为您不想在 Dockerfile 中执行此操作,所以我使用 docker-compose.yml 并在其中定义我的卷。如果它是使用集群模式部署的,我将指向一个具有命名卷的 NFS 服务器,以便在容器迁移到不同主机时允许访问数据。否则,它是一个本地命名卷,可以轻松地与 docker-compose 一起使用。