Mac 上的 Docker 机器:在 docker 主机/docker 机器上看不到已安装的卷?卷物理存储在哪里?

Posted

技术标签:

【中文标题】Mac 上的 Docker 机器:在 docker 主机/docker 机器上看不到已安装的卷?卷物理存储在哪里?【英文标题】:Docker Machine on Mac: Cannot see mounted Volumes on docker host/docker-machine? Where are volumes physically stored? 【发布时间】:2016-02-08 02:31:38 【问题描述】:

我在 Macbook Pro 笔记本电脑上运行 docker-machine (0.5.0)docker-compose (1.5.0) 以启动我的容器。

这意味着我正在使用 docker-machine 创建我的 virtualbox boot2docker 驱动的 HOST 机器,它将运行我的 docker 守护进程并托管我的所有容器。

我认为我在 HOSTS 和 VOLUME 的概念上遗漏了一些关键的东西,因为它们指的是 Docker 和文档。

这是我的 docker-compose.yml 文件(web 只是构建 php:5.6-apache 映像):

web:
  restart: "always"
  build: ./docker-containers/web
  ports:
    - "8080:80"
  volumes:
    - ./src:/var/www/html
  links:
    - mysql:mysql

mysql:
  restart: "always"
  image: mysql:5.7
  volumes_from:
    - data
  ports:
    - "3306:3306"
  environment:
    - MYSQL_ROOT_PASSWORD=XXX

data:
  restart: "no"
  image: mysql:5.7
  volumes:
    - /var/lib/mysql
  command: "true" 

Docker Compose 卷的文件文档在这里:http://docs.docker.com/compose/compose-file/

它为卷声明 - 将路径安装为卷,可选择指定主机上的路径 (HOST:CONTAINER) 或访问模式 (HOST:CONTAINER:ro)。

在这种情况下,HOST 指的是我的由 docker-machine 创建的 VM,对吗?还是我本地的 macbook 文件系统?将我的虚拟机上的路径挂载到容器?

web 下我声明:

volumes:
  - ./src:/var/www/html

这是将我的 macbook pro 上的本地 macbook 文件系统 ./src 文件夹映射到我的 Web 容器。如果我的理解是正确的,它不应该将我的 VM 上的 ./src 文件夹映射到 /var/www/html 内网络容器?!从理论上讲,我认为我应该首先将我的本地 mac 文件系统文件夹 ./src 复制到我的 VM,然后我进行此卷声明。似乎 docker-compose 神奇地一次完成了这一切? 困惑

最后,我们可以看到我正在创建一个纯数据容器来保存我的 mysql 数据。我已经声明:

volumes:
   - /var/lib/mysql

这不应该在我的 HOST boot2docker VM 上创建一个 /var/lib/mysql 文件夹,然后我可以导航到 VM 上的这个文件夹,是/否?当我使用 docker-machine ssh 进入我的机器,然后导航到 /var/lib 时,根本没有 NO mysql 文件夹?!为什么它没有被创建?我的配置有问题吗? :/

提前致谢!任何关于我在这里做错的解释将不胜感激!

【问题讨论】:

***.com/questions/23439126/… 回答你的问题了吗? 【参考方案1】:

好的,这里有几点需要解决。

让我们从什么是 docker 卷开始(此时不要考虑你的 macbook 或 vagrant 机器。请注意 docker 使用不同的文件系统,此时它可能驻留在哪里) : 也许想象一下,Docker 中的每个卷本身只是 Docker 使用的内部文件系统的一部分。 容器可以使用这些卷,就像它们是可以由它们挂载并在它们之间共享的“小硬盘驱动器”(或由它们中的两个同时挂载,例如将某些 ftp 服务器的超快速版本挂载到两个客户端)或其他任何东西:P)。

原则上,您可以通过 Dockerfile 的 VOLUME 指令声明这些卷(仍然不考虑您的计算机/流浪者本身,只是码头工人;))。 标准示例,像这样运行一个 webserver 容器:

FROM: nginx
VOLUME /www

现在进入 /www 的所有内容理论上都可以从一个容器挂载和卸载,也可以挂载到多个容器。 现在单独使用 Nginx 很无聊,所以我们想让 php 运行 nginx 存储的文件以产生一些更有趣的内容。 => 我们需要将该卷挂载到某个 php-fpm 容器中。 因此,在我们的 compose 文件中,我们会这样做

web:
  image: nginx
php:
  image: php-fpm
  volumes_from:
    - web

=> 瞧!在 nginx/web 容器中由 VOLUME 指令声明的每个文件夹都将在 php 中可见。这里需要注意的重要一点,无论 nginx 的 /www 中的什么,都将覆盖 /www 中的任何 php。 如果你把:ro,php甚至不能写入那个文件夹:)

现在接近您的问题,还有第二种声明卷的方法,它不需要在 Dockerfile 中声明它们。这可以通过从主机安装卷来完成(在这种情况下是你的 vagrant/boo2docker 东西)。让我们讨论一下,就好像我们首先在本机 Linux 上运行一样。

如果你要这样写:

volumes:
 - /home/myuser/folder:/folder

在您的 docker-compose.yml 中,这意味着 /home/myuser/folder 现在将被挂载到 docker 中。它将覆盖 docker 在 /folder 中的任何内容,就像 /www 也可以从声明它的东西中访问。现在运行 docker 守护进程的 Linux 机器。

理论讲了这么多 :),实际上您可能只需要以下建议即可让您的工作顺利进行 :):

boot2docker/docker-machine/kitematic 和所有这些东西处理这个问题的方式很简单,他们首先只是将 vagrant 机器中的一个卷安装到 docker 容器中,然后他们也简单地将这个东西安装到你的Mac 文件系统,希望一切顺利:P

现在,我们所有人在 Mac 上使用这个(或者只是试图帮助他们的同事进入甜蜜甜蜜的 Docker 世界:P)所面临的实际问题是权限。我的意思是考虑一下(root 或其他用户处理容器中的文件,用户 vagrant 可能会处理 vagrant 主机中的文件,然后您的 Mac 用户“skalfyfan”在 Mac 中处理这些文件。它们都有不同的用户 ID 和诸如此类 = > 随之而来的许多问题,在某种程度上取决于您在 Docker 中实际运行的内容。Mysql 和 Apache 尤其痛苦,因为它们不是在容器中以 root 身份运行。这意味着,它们经常无法写入 Mac 文件系统。

在尝试下面的第二种方法之前,只需尝试将您的容器卷放在您的 Mac 主目录下。随着时间的推移,这将解决大多数情况下 MySQL 的问题。 顺便说一句:无需声明卷的完整路径。

只需将 compose-yml 放在您的 Mac 用户文件夹中,这就是最重要的。没有 chmod 777 -R :P 会帮助你,它只需要在你的主文件夹下:)

仍然有一些应用程序(例如 Apache)仍然会给您带来困难。容器中运行的任何用户 id 与您的 Mac 用户 id 不同的事实将使您的生活陷入困境。为了解决这个问题,您需要以不与 Mac 权限冲突的方式调整用户 ID 和用户组。您在 Mac 上想要的组是人员,一个有效的 UID 将是例如 1000。 因此,您可以将其放在 Dockerfile 的末尾:

RUN usermod -u 1000 www-data
RUN usermod -G staff www-data

RUN usermod -u 1000 mysql
RUN usermod -G staff mysql

正如你现在所了解的:

理论上我认为我应该被要求复制我的本地 mac 文件 系统文件夹 ./src 首先到我的虚拟机,然后我做这个卷 宣言。似乎 docker-compose 神奇地一次完成了这一切 不过呢?

没错,它就是这样做的:)

最后,我们可以看到我正在创建一个仅数据容器来持久化 我的mysql数据。我已经宣布: 卷: - /var/lib/mysql

这个你错了 :) 如前所述,如果你不提供主机文件夹,那么 Docker 会保留这个路径。但仅针对此容器,所有容器都将保留在 docker 文件系统中。根本没有写给主机!只有在容器文件夹之前提供主机文件夹时才会发生这种情况!

希望这有帮助:)

【讨论】:

感谢您的解释!关于你最后的 cmets,如果我在 compose 中声明卷时没有给出主机文件夹,那么 Docker 将保留这条路径。你能澄清它对 Docker 的含义吗? i> 在容器中保留路径?如果它停止,重新启动它会保留数据吗?如果容器被删除,数据只会丢失?这就是 Docker 仅在容器中保留路径的意思吗? 是的,完全正确:停止就好了,你重新启动,数据仍然存在。删除 => 卷中的数据也消失了。此处的半重要提示:卷仍然存在,但您无法访问,并且会污染您的 hd => 使用 -v 标志删除容器:) 最后一个问题!在我的“数据”(仅限数据)容器中,我只是将其更改为:volumes: - /var/test/mysql:/var/lib/mysql,然后运行 ​​docker- compose build, docker-compose up -d 重建一切。我希望现在在 HOST VM 上看到 /var/test/mysql 但仍然没有? head scratch 我现在注意到的一件事是,当我通过 SSH 连接到我的 VM 和 docker ps 以查看所有正在运行的容器时,data容器无处可见,即使它正在被创建。也许那是另一个教程 :) 谢谢! 啊等一下 :) 我想我在 boot2docker 中解释得很糟糕,这可能是学习这个的最糟糕的方法! (说真的,如果你可以通过 Vagrant/Virtualbox 启动一个 Debian 或 Ubuntu 机器,然后在上面尝试这些东西,而文件系统的复杂性要少一层 :)。无论如何,关于实际问题:我假设您在 Mac 上运行了 docker-compose 命令,对吗?在这种情况下,您需要按照我所说的提供相对于您的 Mac 文件系统的路径!此外,卷的所有路径都需要位于您的 Mac 用户主文件夹中。否则它将无法正常工作。 docker ps -a 的输出是什么? 我的 Mac 上的 docker-compose 命令正确。我的项目文件夹是我的用户目录中的几个子目录(例如 /Users/myname/dev/projectName)。我刚刚将我的数据容器更改为:volumes: - ./data/mysql:/var/lib/mysql 其中 ./data 是当前在我本地 Mac 上的项目文件夹中的一个空目录。 docker ps -a 的输出显示 web、mysql 容器正在运行以及 data 容器 Exited (0) X seconds ago

以上是关于Mac 上的 Docker 机器:在 docker 主机/docker 机器上看不到已安装的卷?卷物理存储在哪里?的主要内容,如果未能解决你的问题,请参考以下文章

mac docker certs.d在哪儿

哈哈,Docker 终于有 Windows 和 Mac 版了

Win10上运行Docker

Docker - Mac 上的“端口不可用”问题

kubernetes (kubectl) 端口转发在 Mac 上无法用于 IBM MQ/Docker 部署

Mac 使用 docker 搭建 kafka 集群 + Zookeeper + kafka-manager