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 的末尾: 或 正如你现在所了解的: 理论上我认为我应该被要求复制我的本地 mac 文件
系统文件夹 ./src 首先到我的虚拟机,然后我做这个卷
宣言。似乎 docker-compose 神奇地一次完成了这一切
不过呢? 没错,它就是这样做的:) 最后,我们可以看到我正在创建一个仅数据容器来持久化
我的mysql数据。我已经宣布:
卷:
- /var/lib/mysql 这个你错了 :) 如前所述,如果你不提供主机文件夹,那么 Docker 会保留这个路径。但仅针对此容器,所有容器都将保留在 docker 文件系统中。根本没有写给主机!只有在容器文件夹之前提供主机文件夹时才会发生这种情况! 希望这有帮助:)RUN usermod -u 1000 www-data
RUN usermod -G staff www-data
RUN usermod -u 1000 mysql
RUN usermod -G staff mysql
【讨论】:
感谢您的解释!关于你最后的 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 机器上看不到已安装的卷?卷物理存储在哪里?的主要内容,如果未能解决你的问题,请参考以下文章
哈哈,Docker 终于有 Windows 和 Mac 版了