在 Docker 容器中挂载文件系统

【翻译于《Mount Filesystems Within a Docker Container》】

1. 概述

Docker 容器是一个可移植的、轻量级的、隔离的环境,用于运行应用程序及其依赖项。在 Docker 容器中挂载文件系统允许从容器访问主机系统上的文件或目录。这样做对于在容器和主机之间共享数据或配置非常有用。

在本教程中,我们将学习如何在 Docker 容器中挂载文件系统。

2. 主机源目录

首先,要在 Docker 容器中挂载文件系统,必须在系统上安装 Docker。此外,让我们确定主机系统上的源目录,即我们希望在挂载过程中使用的系统上的路径。

为了说明这一点,让我们使用 mkdir 在主机上创建一个新目录:

shell 复制代码
$ mkdir /home/user1/hostpath

接下来,让我们检查新目录是否存在,并使用 ls 命令验证其属性:

bash 复制代码
$ ls -ld /home/user1/hostpath/
drwxrwxr-x 2 user1 user1 4096 Jul 17 04:43 /home/user1/hostpath/

在这里,-l 选项启用了目录的长列表,而 -d 标志确保我们显示有关目录文件系统对象的信息,而不是其内容。

准备好源目录后,现在让我们运行容器。

3. 使用卷

为了在 Docker 容器中挂载文件系统,我们在运行容器时使用 -v--volume 标志。它的参数由两个字段组成,用冒号 (:) 分隔:

主机源目录路径 容器目标目录路径 简而言之,我们在使用 docker 时将主机上的目录链接到容器内的目录:

shell 复制代码
$ docker run -it --rm -v /path/on/host:/path/in/container image_name /bin/bash

让我们分解一下这个命令:

-i -t(或 -it)支持对容器的交互式访问 --rm 在退出时删除容器以释放系统资源(CPU、内存)) /path/on/host 是我们要挂载的主机上目录的路径 /path/in/container 是容器中可访问目录的所需路径 image_name 是我们要运行的 Docker 映像的名称或 ID /bin/bash 在容器中提供了一个 Bash shell。 重要的是,如果我们不使用 --rm 选项,我们可能需要在退出后手动删除容器以释放存储空间。

4. 运行 Docker 容器

为了说明这一点,现在让我们将上面看到的通用语法中的 /path/on/host/path/in/container 替换为方案的相应源路径和目标路径:

bash 复制代码
$ docker run -it --rm -v /home/user1/hostpath:/home/cont_path ubuntu /bin/bash
root@e8439d98c634:/# 

此命令执行多项操作:

使用 ubuntu 镜像的副本启动一个 Docker 容器 在容器中创建 /home/cont_path 目录 将 /home/cont_path 目标目录映射到我们之前创建的 /home/user1/hostpath 源目录 容器启动并运行后,我们可以通过导航到容器中的目标目录来检查文件系统是否正确挂载:

ruby 复制代码
root@baeldung:/# cd /home/cont_path
root@baeldung:/home/cont_path# 

值得注意的是,使用 /home/user1/hostpath 目录,我们现在可以访问容器的 /home/cont_path 目录下任何新生成或修改的数据。Docker 还会复制两条路径之间的任何更改。因此,我们在 /home/cont_path 目录中所做的任何更改都会影响主机和容器系统。为了理解,让我们创建子目录结构 /home/cont_path/dir1/dir2:

shell 复制代码
# mkdir -p dir1/dir2

退出容器后,让我们检查主机上的目录,看看是否存在添加的内容:

shell 复制代码
$ ls /home/user1/hostpath/
dir1
$ ls ~/hostpath/dir1
dir2

值得注意的是,当主机目录和容器目录具有相同的内容时,将验证挂载操作是否成功。

5. 使用提升的权限

在 Docker 中,我们可以使用 --privileged--cap 标志在容器中挂载文件系统。

假设我们要设置一个依赖于从主机挂载 CIFS 共享的环境。如果我们尝试直接这样做,容器可能会遇到默认权限不允许挂载的问题。但是,--privileged--cap 可以为容器提供提升的权限。因此,它可以访问主机级资源,包括挂载文件系统。

为了演示,让我们探讨如何使用 --privileged--cap 选项在 Docker 容器中挂载文件系统。

5.1. 使用 --privileged 运行容器

同样,要授予容器提升的权限,我们将使用 --privileged 开关运行它:

bash 复制代码
$ docker run --privileged -it -v /home/user1/hostpath:/home/cont_path ubuntu /bin/bash
root@53d79f0bb259:/#

为了验证,我们可以使用带有 --format 选项的 docker inspect 命令。此 docker 命令提供有关正在运行的容器的其他数据。重要的是,它可以显示容器是否在特权模式下运行。

因此,让我们使用 --format 标志和容器 ID 作为参数来检查我们的容器是否以提升的权限运行:

ini 复制代码
$ docker inspect --format='{{.HostConfig.Privileged}}' 22a2439bb82f
true

事实上,true 意味着我们处于特权模式。但是,对于不使用该模式的容器,该命令将打印 false。

5.2. 授予特定权限

为了加强我们对容器功能的控制,我们可以使用 --cap 标志。此选项与 -drop 或 -add 后缀一起使用,以更改 Linux 中容器的默认功能。

值得注意的是,具有较高权限的容器在容器内挂载的文件系统上具有一些默认功能:

  • READ
  • WRITE
  • MKNOD

为了说明如何使用这两个标志,让我们将容器设置为使用除 MKNOD 之外的所有功能:

shell 复制代码
$ docker run --cap-add=ALL --cap-drop=MKNOD -it -v /home/user1/hostpath:/home/cont_path ubuntu /bin/bash

让我们分解命令中的新标志:

--cap-add=ALL 将所有功能添加到容器中 --cap-drop=MKNOD 删除 MKNOD 功能,从而阻止容器使用 mknod 创建特殊文件 此外,为了让容器执行一些系统管理任务,我们可以赋予它 SYS_ADMIN 功能。为此,我们可以使用 --cap-add=SYS_ADMIN

shell 复制代码
$ docker run --cap-add=SYS_ADMIN -it -v /home/user1/hostpath:/home/cont_path ubuntu /bin/bash

值得注意的是,SYS_ADMIN 参数为容器提供管理权限(如装载权限)。

6. 挂载多个目录

当然,我们可以通过在 docker run 命令中指定多个 -v 标志来挂载多个目录。每个 -v 开关代表一个单独的挂载:

javascript 复制代码
$ docker run -v ~/hostpath/path_A:/home/path_1 -v ~/hostpath/path_B:/home/path_2 image_name

此命令挂载两个目录:

~/hostpath/path_A 到容器中的 /home/path_1 ~/hostpath/path_B 到容器中的 /home/path_2 值得注意的是,我们可以通过添加更多的 -v 选项来根据需要挂载任意数量的目录。

为了成功挂载,主机的文件系统必须在容器内可访问。此外,为了确保准确的读写访问,我们可以评估挂载目录的权限和所有权。当我们遇到权限问题时,我们可能需要更改权限或使用其他设置选项。

通常,我们可以毫不费力地在主机和容器之间交换数据和资源。通过在 Docker 容器中挂载文件系统,可以成功进行这种数据交换。此外,它还可以提高灵活性并改善任何容器化应用程序的整体功能。

7. 结论

在本文中,我们了解了如何在 Docker 容器上挂载主机文件系统。首先,我们学习了如何设置主机。然后,我们使用 -v 选项将文件系统挂载到 Docker 容器上。此外,我们以提升的权限将主机文件系统挂载到 Docker 容器上,允许它访问主机级资源。最后,我们测试了文件系统以确认它工作正常。

相关推荐
景天科技苑2 小时前
【云原生开发】K8S多集群资源管理平台架构设计
云原生·容器·kubernetes·k8s·云原生开发·k8s管理系统
wclass-zhengge3 小时前
K8S篇(基本介绍)
云原生·容器·kubernetes
颜淡慕潇3 小时前
【K8S问题系列 |1 】Kubernetes 中 NodePort 类型的 Service 无法访问【已解决】
后端·云原生·容器·kubernetes·问题解决
川石课堂软件测试5 小时前
性能测试|docker容器下搭建JMeter+Grafana+Influxdb监控可视化平台
运维·javascript·深度学习·jmeter·docker·容器·grafana
昌sit!11 小时前
K8S node节点没有相应的pod镜像运行故障处理办法
云原生·容器·kubernetes
追风林12 小时前
mac 本地docker-mysql主从复制部署
mysql·macos·docker
A ?Charis14 小时前
Gitlab-runner running on Kubernetes - hostAliases
容器·kubernetes·gitlab
城南vision14 小时前
Docker学习—Docker核心概念总结
java·学习·docker
wclass-zhengge14 小时前
Docker篇(Docker Compose)
运维·docker·容器
北漂IT民工_程序员_ZG15 小时前
k8s集群安装(minikube)
云原生·容器·kubernetes