我如何才能从Windows主机看到从docker linux容器内部进行的符号链接(如果需要,可能涉及samba) [英] How can I make symlinks made from inside docker linux containers to be seen from a windows host (maybe involving samba, if needed)

查看:114
本文介绍了我如何才能从Windows主机看到从docker linux容器内部进行的符号链接(如果需要,可能涉及samba)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题



我如何从Windows主机上看到docker linux容器的符号链接? (即使我必须放置一个通过NFS或Samba公开文件系统的中间linux计算机)



Context



在DEVEL环境中,我在办公室中Linux的某个远程文件系统中具有以下结构:

  / files / repos / app-1 
/ files / repos / app-2
/ files / repos / lib-x
/ files / repos / lib-y

app-1 app-2 使用这样的供应商和符号链接的库:

  / files / repos / app-1 / vendor / my-公司/ lib-x => / files / repos / lib-x 
/ files / repos / app-1 / vendor / my-company / lib-y => / files / repos / lib-y
/ files / repos / app-2 / vendor / my-company / lib-x => / files / repos / lib-x
/ files / repos / app-2 / vendor / my-company / lib-y => / files / repos / lib-y

开发人员必须在Windows中。



因此,开发人员的IDE指向某个已安装的单元,例如Z:\,他们可以看到所有存储库和项目。



这使我们具备以下条件:




  • 从其自己的文件夹中编辑任何项目,并运行该项目的单元测试,包括运行 lib-x lib-y

  • 开发任何库,并在相关应用程序中对其进行更新(请注意,我说我使用的是DEVEL,而不是PRE或PROD)。

  • 从IDE中指向所有对象的完整结构的应用程序(例如 app-1 )还可以看到 lib-x lib-y ,因此自动补全功能非常完美。





问题



开发人员需要与服务器的连接才能进行开发,因此我们想转变为本地docker,以便使devels在家工作。



去docker



我们现在决定不再使用办公服务器,而是要在Docker容器中设置所有开发。



实际起作用的是



我们刚刚在Windows中安装了docker桌面,并将C:\repos从主机共享到docker中。



我们现在有一些开发机器 FROM ubuntu:xxx 并运行它们以装入卷。



我们在 app-1 app-2 中建立了指向 lib的符号链接-x lib-y 从Linux容器内部。



这确实有效完美,如果我们在本地dockers中运行应用程序,存储库也可以正常工作



Linux容器和Windows主机中的符号链接问题



现在的问题是IDE:在读取C:\repos\app-1中的文件时,无法从主机上看到在linux容器中创建的符号链接。



这使IDE无法跟随C:\repos\app-1\vendor\lib-x,并且所有代码完成帮助程序也被破坏了。 p>

我已经知道Windows不支持与Linux符号链接兼容的符号链接。



这迫使我们寻找替代解决方案



解决方案尽管我们使用了Samba



最初,我还是认为和以前的拓扑结构一样linux服务器只是通过samba共享了文件系统,而Windows可以读取符号链接的内容,因为它们是在服务器端而不是客户端去映射的,我认为我可以在samba服务器上运行另一台docker机器,以便在本地共享所见事物从Linux重新导入Windows主机。



为此,我设置了docker-compose:

 版本: 3.7 
服务:
桑巴舞:
容器名:samba
主机名:samba
图像:dperson / samba
数量:
-// c / Users / xavi / Documents / repos / test_samba:/ mount
端口:
- 139:139
- 445 :445
命令:samba.sh -s test_samba; / mnt / repos / test_samba; yes; no; yes; all
重新启动:始终

但这会冲突,因为已经在本地使用了445。



如果我拒绝本地SMB ,然后在下次重新启动时,docker无法将C:\共享到docker(我不认为它是通过SMB进行共享的,是否可以将其转换为NFS?)



如果我映射到另一个端口,例如10445:445,则客户端将无法访问它,因为Windows中的客户端samba端口似乎不可配置。



映射IP



所以我尝试映射IP:

 版本: 3.7 
服务:
samba:
container_name:samba
主机名:samba
图片:dperson / samba
数量:
-// c / Users / xavi / Documents / repos / test_samba:/ mount
端口:
- 139:139
- 192.168.4.83:445:445
命令: samba.sh -s test_samba; / mnt / repos / test_samba; yes; no; yes; all
重新启动:始终
网络:
samba:
ipv4_address:192.168。 4.83
网络:
桑巴舞:
ipam:
驱动程序:默认
配置:
-子网: 192.168.4.0/16

但是似乎仍然会产生问题:




  • 该IP似乎仅用于内部docker网络,但不能从主机看到

  • 似乎该原始服务仍然不监听127.0.0.1:445,而是监听0.0 .0.0:445,因此仍会阻止该攻击要听192.168.4.83:445



这样的问题



如何我可以让Windows主机看到符号链接的解映射内容以使IDE看到从docker linux容器内部链接的供应商内容吗?

解决方案

TL; DR



  1. 以管理员身份运行git-bash。

  2. 问题 export MSYS = winsymlinks:nativestrict 在git-bash中。

  3. 从此开始, ls -s 在Windows中工作。

  4. 从docker内部可以看到链接。


详细信息


我们将通过以下步骤:


  1. 准备工作:准备一个临时目录,其中包含一些文件 abc 目录。

  2. 看到它失败:我们将尝试进行符号链接并看到它失败

  3. 创建符号链接:。我们将在Windows中创建符号链接并查看它。我们将 xyz 指向 abc

  4. 运行docker :然后,我们将使用 ubuntu 运行docker并更改 xyz 中的内容。

  5. 签入ubuntu容器:我们还将在docker中的 abc 中看到更改。

  6. 在Windows主机中签入:同时选中 abc xyz


1。准备



  • 在git-bash中转到 / c 并创建一个临时目录 tmp

  • 在其中,创建一个 abc 目录并在其中放置一些内容。


  cd / c 
mkdir tmp
cd tmp /
mkdir abc
cd abc /
echo 1111> old_1
echo 2222> old_2
echo 3333> old_3

这是一个示例会话:



2。看到它失败了


首先,让我们尝试一下正常



  • 在git-bash中,导航到 / c / tmp

  • 然后执行符号链接,使 xyz 指向 abc ln -s abc xyz

  • 通过ls-ing tmp 看到失败请参阅 xyz 是常规目录。

  • 可以肯定的是,在 xyz 并在 abc 中看到它


尝试创建链接(不起作用)

  cd / c / tmp / 
ln -s abc xyz

xyz new_bad >,并且不会 abc 中看到它。

  cd xyz / 
touch new_bad
cd ../abc/
ls -l

清除错误的 xyz

  rm -Rf xyz / 

这里是一个示例会话:



3。创建符号链接


这是真正的东西。灵感来自@Slayvin在这里以及这里的



  • 一旦您是CLI管理员,请导航至目标并设置以下环境变量:


  export MSYS = winsymlinks:nativestrict 

这将告诉git-bash运行时子系统实际使用符号链接功能。



  • 我们只是管理员,因此我们会成功。如您所料: ls -s abc xyz



有效!!!现在下一步是在docker中测试!


注意:根据塞巴斯蒂安的回答,在这里


4。运行docker +5。签入docker



  • 不再需要具有管理员特权的bash 。因此,我们将其关闭并重新实例化正常的bash。

  • 在其中,使用docker运行ubuntu continainer。使用 -it 与ubuntu的bash进行交互。使用 winpty 允许 -it 工作。

  • 绑定安装 / c / tmp 目录,因此 abc xyz 均为可达的。我选择将其安装到 / files

  • 从内部安装 cd / files 并看到 xyz 实际上是一个符号链接。

  • xyz


运行并查看:

  winpty docker run -it --rm --mount type = bind,source = c:\tmp,target = / files --name ubuntu-link ubuntu 
cd / files /
ls -l

创建内容:

  cd xyz 
echo yeaaahh; > new_good

通过转到 abc 来检查它是否真的是一个符号链接:

  cd .. 
cd abc /
cat new_good

示例会话:



6。签入Windows主机



  • 从Docker中退出。呆在git-bash中。

  • 再次:此git-bash 不需要享有特权。我们必须成为管理员的唯一时刻是创建目录。

  • 从没有特权的bash中,浏览<$​​ c $ c> abc 以及 xyz ,然后看到我们在docker内部创建的内容同时出现在原始目录和符号链接中。


示例会话:



最终检查


我们终于可以转到经典的 CMD 查看其外观。我们可以清楚地看到它是目录的符号链接,并且在那里也可以看到目标:



金色


如果您拥有开发人员工具,激活如上所述,唯一缺少的是ENV VAR。


我们可以通过在窗口中编辑 .bashrc 来进行设置主页:




这样做,我们可以完全正常地使用git-bash并开始从Windows创建符号链接而没有任何过载。



警告


以这种方式创建的符号链接可从Windows运行,并可从docker内部看到。但不是相反的。如果您在容器内创建符号链接,则不会在Windows中创建符号链接。


因此,在装入的卷中,总是从git-bash设置符号链接,然后从容器中使用它们。如果您从容器中创建它们,它们 still 可以从容器中使用。


结论


可以通过git-bash从linuxflavor命令完全完成。只有您需要管理员才能创建链接并告诉git-bash运行时使用该功能。而且该链接需要从Windows完成,而不是从ubuntu内部完成。


Question

How can I see symlinks of docker linux-containers from a windows host? (Even if I have to place an intermediate linux machine exposing the filesystem via NFS or Samba)

Context

In a DEVEL environment, I have this structure in a certain remote filesystem in a Linux within the office:

/files/repos/app-1
/files/repos/app-2
/files/repos/lib-x
/files/repos/lib-y

both app-1 and app-2 use those libraries which are vendored and symlinked like this:

/files/repos/app-1/vendor/my-company/lib-x => /files/repos/lib-x
/files/repos/app-1/vendor/my-company/lib-y => /files/repos/lib-y
/files/repos/app-2/vendor/my-company/lib-x => /files/repos/lib-x
/files/repos/app-2/vendor/my-company/lib-y => /files/repos/lib-y

The developers need to be in Windows.

So the developers have their IDE pointing to some mounted unit, for example Z:\ where they see all the repos and projects.

This allows us the following:

  • Edit any of the projects from it's own folder, and run the unit-tests for that project, including running the lib-x and lib-y.
  • Develope any of the libraries and have them updated in the depending applications (note I say I am in DEVEL, not PRE or PROD).
  • From the IDE, pointing see the "complete structure" of any of the applications (for instance app-1) also see the classes of the lib-x and lib-y so the autocompletion and so works perfectly.

This has been working like this for nearly a decade and works perfectly.

Problems

The developers need the connection to the server to develop and we wanted to mutate to local dockers so we can make the devels work from home.

Going to docker

We now decided that we are not going to use anymore the office-servers and we are going to setup all the development within docker containers.

What does actually work

We just installed docker desktop in Windows and shared C:\repos from the host into the dockers.

We now have some devel machines FROM ubuntu:xxx and run them mounting the volumes.

We made the symlinks within the app-1 and app-2 to lib-x and lib-y from inside the linux containers.

This does work perfectly and also the repositories work fine if we run the applications in the local dockers

Problem with symlinks in linux container and windows host

The problem is now the IDE: While it reads the files in C:\repos\app-1, the symlink that has been created within the linux containers can't be seen from the host.

This makes the IDE to be unable to follow C:\repos\app-1\vendor\lib-x and all the code-completion helpers are broken.

I already know Windows does not support symlink compatible with linux symlinks.

This forces us to look for an alternate solution.

Solution we've though with Samba

Initially I thought that as well as in the old topology a linux server just shared the filesystem via samba and the windows could just read the symlinks contents as they were demapped at the serverside and not the clientside, I thought that I could run another docker machine with a samba server just to locally share the "things seen from the linux" into the Windows host again.

To do so, I setup this docker-compose:

version: "3.7"
services:
    samba:
        container_name: samba
        hostname: samba
        image: dperson/samba
        volumes:
            - //c/Users/xavi/Documents/repos/test_samba:/mount
        ports:
            - "139:139"
            - "445:445"
        command: samba.sh -s "test_samba;/mnt/repos/test_samba;yes;no;yes;all"
        restart: always

But this conflicts as 445 is locally already used.

If I turn down the local SMB, then in the next reboot, docker is unable to share C:\ into docker (I was not consciuos it does this sharing via SMB, could it be turned into a NFS or so?)

If I map to another port, like 10445:445 then the client is unable to access it, as client samba ports in windows seem to be not configurable.

Mapping an IP

So I tried to map an IP:

version: "3.7"
services:
    samba:
        container_name: samba
        hostname: samba
        image: dperson/samba
        volumes:
            - //c/Users/xavi/Documents/repos/test_samba:/mount
        ports:
            - "139:139"
            - "192.168.4.83:445:445"
        command: samba.sh -s "test_samba;/mnt/repos/test_samba;yes;no;yes;all"
        restart: always
        networks:
            samba:
                ipv4_address: 192.168.4.83
networks:
    samba:
        ipam:
            driver: default
            config:
                -   subnet: "192.168.4.0/16"

But is seems that this still creates problems:

  • It seems the IP is only for internal docker networking but not seen from the host
  • It seems the original service still listens not to 127.0.0.1:445 but to 0.0.0.0:445 so still "blocking" the attachment to listen to 192.168.4.83:445

So question

How could I make a windows host to see the "demapped contents of symlinks" to make the IDE see the vendored content that is linked from inside docker linux containers?

解决方案

TL;DR

  1. Run git-bash as administrator.
  2. Issue export MSYS=winsymlinks:nativestrict in git-bash.
  3. From there on, ls -s works in windows.
  4. Links are seen from inside the docker.

Details

We'll walk thru these steps:

  1. Preparation: Prepare a temporal dir with some files within the abc directory.
  2. See it fail: We'll try to make a symlink and see it fail.
  3. Create symlink: We'll create the symlink in windows and see it. We'll point xyz to abc.
  4. Run docker: We'll then run docker with ubuntu and change contents in xyz.
  5. Check in ubuntu container: We'll see the changes also in abc from within the docker.
  6. Check in windows host: Well check both abc and xyz from ouside the container.

1. Preparation

  • In a git-bash go to /c and create a temporary dir tmp.
  • Inside it, create an abc dir and throw some contents there.

cd /c
mkdir tmp
cd tmp/
mkdir abc
cd abc/
echo 1111 > old_1
echo 2222 > old_2
echo 3333 > old_3

Here's a sample session:

2. See it fail

First let's try the "normal" way and see it fail.

  • In a git-bash, navigate to /c/tmp
  • Then do a symlink making xyz to point to abc: ln -s abc xyz
  • See it fails, by ls-ing the tmpand see xyz is a regular dir.
  • To be sure, create new content in xyz and see it's not there in abc.

Try to create the link (won't work)

cd /c/tmp/
ln -s abc xyz

Create new_bad in xyz and don't see it in abc.

cd xyz/
touch new_bad
cd ../abc/
ls -l

Clear the wrong xyz

rm -Rf xyz/

Here's a sample session:

3. Create symlink

Here it comes the real stuff. The inspiration comes from @Slayvin's answer here, as well as here Git Bash Shell fails to create symbolic links and the official git-for-windows repo here https://github.com/git-for-windows/git/pull/156

  • First open a new git-bash in Administrator mode. The reason is that only admins can create links in windows.

  • Once you are a CLI admin, navigate to the destination and set this evironment variable:

export MSYS=winsymlinks:nativestrict

This will tell the runtime subsytem of git-bash to actually use the symlinks feature. As we are admins we'll succeed.

  • The do just "normal symlinks" as you would expect: ls -s abc xyz

It works!!! Now next move is to test within docker!

NOTE: As per Sebastian's answer here https://stackoverflow.com/a/40914277/1315009 you DON'T need to be administrator to create symlinks in git-bash if you enabled the developer tools. In the search-bar write for developers and enable it:

4. Run docker + 5. Check in docker

  • The bash with admin privileges is no longer needed. So we'll close it and re-instantiate a "normal" bash.
  • In it, run an ubuntu continainer with docker. Use -it to interact with the ubuntu's bash. Use winpty to allow -it to work.
  • Bind-mount the /c/tmp directory so both abc and xyz are reachable. I chose to mount it to /files.
  • From inside, cd /files and see that xyz is actually a symlink.
  • Create some new content in xyz

Run and see:

winpty docker run -it --rm --mount type=bind,source="c:\tmp",target=/files --name ubuntu-link ubuntu
cd /files/
ls -l

Create content:

cd xyz
echo "yeaaahh" > new_good

Check it's really a symlink by going to abc:

cd ..
cd abc/
cat new_good

Sample session:

6. Check in windows host

  • Step out from the docker. Stay in the git-bash.
  • Again: This git-bash does not need to be privileged. The only moment we had to be admin was to "create" the symlink in windows.
  • From the unprivileged bash, explore abc as well as xyz and see that there's the content we created from inside the docker, appearing in both the original directory and in the symlink.

Sample session:

Final check

We can finally go to a classical CMD to see how it looks like. We can see it's clearly indicated that it's a symlink for a directory and we also see the target there:

Golden touch

If you have the "developer tools" activates as stated above, the only missing thing is the ENV VAR.

We can set this by editing the .bashrc at your windows home:

By doing this we can just use git-bash completely normally and start creating the symlinks from windows without any overload.

Caution

The symlinks created this way work from windows and are seen from inside docker. But not the oposite. If you create symlinks inside the container they don't get created in windows.

Therefore, in mounted volumes, setup the symlinks always from git-bash and consume them from the container. If you create them from the container, they still can be consumed from the container. But won't be usable from windows.

Conclussion

It can be done fully from the linux flavour commands via git-bash. Only that you need to be admin to create the links and tell the git-bash runtime to use that feature. And that the link needs to be done from windows, instead from inside the ubuntu.

这篇关于我如何才能从Windows主机看到从docker linux容器内部进行的符号链接(如果需要,可能涉及samba)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆