Windows 10下Docker Toolbox文件夹共享映射

之前分享了WINDOWS 10和CYGWIN的Docker Toolbox共用,其中只是一些简单的变量设置,本质上还是依赖着WIN 10中的Virtual Box!随着使用,我发现一个必须面对的问题。那就是如何让WINDOWS下的目录与docker容器生成映射关系,从而达到docker文件共享的效果。

举个简单的例子,根据最新版官方的logstash docker容器使用指引


# pipeline
docker run --rm -it -v ~/pipeline/:/usr/share/logstash/pipeline/ docker.elastic.co/logstash/logstash:5.3.0
# or settings
docker run --rm -it -v ~/settings/:/usr/share/logstash/config/ docker.elastic.co/logstash/logstash:5.3.0

以上命令的意图是将docker宿主机和容器的目录进行映射绑定。

我现在用的是Docker Toolbox for windows, 那么意味着我们要实现在WIN的CYGWIN BASH下去很方便修改Logbash配置咯。我们也就需要多一步操作: 将WIN目录与Docker Machine进行映射。

这就必须通过Virtual Box来实现啦。既然我们思路理清楚啦。那么,我们看看如何实现。

  • VirtualBox GUI
  • Docker for Windows GUI – 之前提过,因为我PC(WINDOWS 10 Pro)上装不起HyperV, 所以我也就卸载了Docker for Windows,改用了Toolbox.所以我也没法测试,只是我看到官方文档截图中有这么一想:设置Docker Machine与WIN系统文件夹之间的共享。我想其底层也还是去执行了VBox的文件夹共享指令。
  • 全命令行模式 – 别怪我装B!我没好意思说,我的VBox针对Docker的虚拟母机在GUI下是没法操作的(报错如下图)。我不知道这是因为我VBox之前主要用于华为eNSP,还是因为这个虚拟机是我在bash shell下用命令行生成的。所以,我不得不使用全命令行模式来实现。
VirtualBox界面报错
在Cygwin bash下新建的Docker虚拟母机无法在GUI下访问。我删除过一次安装时建立的,然后命令行重建过一次。求大神

我们入正题:

Virtual Box与WIN 10之间的文件夹共享设置

参考官方文档:https://www.virtualbox.org/manual/ch04.html#sharedfolders


docker-machine stop
mkdir ~/.docker
vboxmanage sharedfolder add default --name dockershare --hostpath "h:\git-sdk-64\home\.docker" --automount
#vboxmanage sharedfolder remove default --name dockershare #这是删除共享

dockershare是我们设定的共享名称,即在Virtual Box中对共享的一个标识。其他的都很容易理解啦。

Virtual Box中虚拟机docker machine中通过挂载设定映射

默认情况下,Boot2Docker下会有一个/c/Users是与其宿主机(我这里的WIN 10 PC)的%%HOME%%/users存在映射的。其他系统详见Boot2Docker的ReadMe.

所以,如果你没有特别需求,也可以直接使用默认的配置,不需要折腾。我去,怎么不早说。哈哈哈~ 不过在Mysys Bash下执行docker container和docker machine的映射命令还有一点需要注意的(点这里)。

我们先回归该段主题,将boot2docker系统与VBox建立映射。


docker-machine start
docker-machine ssh
sudo vi /mnt/sda1/var/lib/boot2docker/bootlocal.sh
###以下为bootlocal.sh脚本内容###
#!/usr/bin/env bash
SHAREDDIR='/h'
mkdir -p $SHAREDDIR
mount -t vboxsf -o defaults,uid=`id -u docker`,gid=`id -g docker`,dmode=755,fmode=644 dockershare $SHAREDDIR #dockershare是虚拟机中的文件夹名称
###
docker-machine stop
docker-machine start

我们验证一下:


touch /h/git-sdk-64/home/.docker/test.txt
docker-machine ssh
ls -al /h
#是不是看到test.txt啦?

通过vboxsf挂载的方式,我们可以更加有效的控制文件夹权限。相对于第一种方式(vboxmanage.exe),它默认是r/w,可以设定为readonly. WIN中共享过去的会在虚拟机中变成777的权限,这对于docker容器中有些服务的配置文件而言是不可接受的,例如my.cnf。所以我们可以利用上面的挂载脚本来绕过该坑。

boot2docker与docker container之间的volume绑定

这就回到开篇的logstash docker指令啦。


winpty docker run --rm -it -v //h/logstash/pipeline/:/usr/share/logstash/pipeline/ docker.elastic.co/logstash/logstash:5.3.0

请牢记:指令中的/h已经是代表WIN系统中的路径”h:/git-sdk-64/home/.docker/”啦。但是我们还有2点需要特别注意的,如下:

注意事项

  • winpty封装是为了保证在win cmd模拟环境下运行之后的docker指令,否则会报一条错误”the handle is invalid.
  • 我们在指定docker machine(boot2docker)路径的时候必须以双斜线开头,否则mingw(msys2)会将它转换为windows路径。

以上两点看起来有点矛盾,既然winpty已经将指令模拟到cmd shell环境,那么使用win路径格式又怎么会有问题?主要是因为docker指令本身还是传递到Vbox虚拟机(即docker machine/boot2docker)上去执行的。
那么,又怎么会还被转化为win路径呢?这容易理解一下。因为这是在winpty起效果之前就被整条命令运行的mingw shell给转换了咯。

是不是感觉有点绕得晕乎乎的?没有?好吧,我反正是差点晕了~知道为啥很多人选择MAC本了吧?穷屌丝伤不起……