我如何才能从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)
问题描述
问题
我如何从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
- 以管理员身份运行git-bash。
- 问题
export MSYS = winsymlinks:nativestrict
在git-bash中。 - 从此开始,
ls -s
在Windows中工作。 - 从docker内部可以看到链接。
详细信息
我们将通过以下步骤:
- 准备工作:准备一个临时目录,其中包含一些文件
abc
目录。 - 看到它失败:我们将尝试进行符号链接并看到它失败
- 创建符号链接:。我们将在Windows中创建符号链接并查看它。我们将
xyz
指向abc
。 - 运行docker :然后,我们将使用
ubuntu
运行docker并更改xyz
中的内容。 - 签入ubuntu容器:我们还将在docker中的
abc
中看到更改。 - 在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 $ c中创建新内容$ c>并在
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 $中创建一些新内容c $ c>
运行并查看:
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
andlib-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 thelib-x
andlib-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
- Run git-bash as administrator.
- Issue
export MSYS=winsymlinks:nativestrict
in git-bash. - From there on,
ls -s
works in windows. - Links are seen from inside the docker.
Details
We'll walk thru these steps:
- Preparation: Prepare a temporal dir with some files within the
abc
directory. - See it fail: We'll try to make a symlink and see it fail.
- Create symlink: We'll create the symlink in windows and see it. We'll point
xyz
toabc
. - Run docker: We'll then run docker with
ubuntu
and change contents inxyz
. - Check in ubuntu container: We'll see the changes also in
abc
from within the docker. - Check in windows host: Well check both
abc
andxyz
from ouside the container.
1. Preparation
- In a git-bash go to
/c
and create a temporary dirtmp
. - 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 toabc
:ln -s abc xyz
- See it fails, by ls-ing the
tmp
and seexyz
is a regular dir. - To be sure, create new content in
xyz
and see it's not there inabc
.
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. Usewinpty
to allow-it
to work. - Bind-mount the
/c/tmp
directory so bothabc
andxyz
are reachable. I chose to mount it to/files
. - From inside,
cd /files
and see thatxyz
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 asxyz
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屋!