簡體   English   中英

如何從 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 容器的符號鏈接? (即使我必須放置一個中間 linux 機器通過 NFS 或 Samba 暴露文件系統)

語境

在 DEVEL 環境中,我在辦公室內 Linux 的某個遠程文件系統中具有此結構:

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

app-1app-2都使用這些庫,這些庫是這樣出售和符號鏈接的:

/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

開發人員需要在 Windows 中。

因此,開發人員將他們的 IDE 指向某個已安裝的單元,例如 Z:\,在那里他們可以看到所有的存儲庫和項目。

這使我們能夠:

  • 從它自己的文件夾中編輯任何項目,並為該項目運行單元測試,包括運行lib-xlib-y
  • 開發任何庫並在依賴的應用程序中更新它們(注意我說我在 DEVEL,而不是 PRE 或 PROD)。
  • 從 IDE 中,指向查看任何應用程序的“完整結構”(例如app-1 )還可以查看lib-xlib-y的類,因此自動補全等完美運行。

這已經像這樣工作了近十年並且運行良好。

問題

開發人員需要連接到服務器來進行開發,我們想變異為本地 docker,這樣我們就可以讓開發人員在家工作。

前往 docker

我們現在決定不再使用辦公服務器,我們將在 docker 容器中設置所有開發。

什么真正起作用

我們剛剛在 Windows 中安裝了 docker 桌面並將 C:\repos 從主機共享到 docker。

我們現在有一些FROM ubuntu:xxx的開發機器並運行它們安裝卷。

我們從 linux 容器內部將app-1app-2中的符號鏈接到lib-xlib-y

如果我們在本地 docker 中運行應用程序,這確實可以正常工作,並且存儲庫也可以正常工作

linux 容器和 windows 主機中的符號鏈接問題

現在的問題是 IDE:當它讀取 C:\repos\app-1 中的文件時,可以從主機中看到在 ZE206A54E97690CCE50CC872DD70EE't96 中創建的符號鏈接。

這使得 IDE 無法跟隨 C:\repos\app-1\vendor\lib-x 並且所有代碼完成助手都被破壞了。

我已經知道 Windows 不支持與 linux 符號鏈接兼容的符號鏈接。

這迫使我們尋找替代解決方案。

我們使用 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使用 samba 服務器再次將“從 linux 看到的東西”本地共享到 Windows 主機。

為此,我設置了這個 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

但是這種沖突,因為 445 已經在本地使用。

如果我關閉本地 SMB,那么在下次重新啟動時,docker 無法將 C:\ 共享到 docker 中(我沒有意識到它可以通過 SMB 變成 NFS 嗎?)

如果我將 map 連接到另一個端口,例如 10445:445,則客戶端無法訪問它,因為 windows 中的客戶端 samba 端口似乎不可配置。

映射 IP

所以我嘗試了 map 和 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"

但似乎這仍然會產生問題:

  • 似乎 IP 僅用於內部 docker 網絡,但從主機看不到
  • 看來原始服務仍然不聽 127.0.0.1:445 而是聽 0.0.0.0:445 所以仍然“阻止”附件聽 192.168.4.83:445

所以問

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?

我的設置遇到了類似的問題:在 Windows 10 上開發(IDE 和 Docker 都在運行),並且網站在容器內運行(Linux)。

我曾經在網站所需的庫上工作,同時在兩個項目上工作。 為此,庫目錄在供應商路徑中進行了符號鏈接(在主機/Windows 中)。

就像是:

+ my-website  
  ↪ vendor  
    ↪ company  
      ↪ my-package (->symlink here)
  ↪ ...
  ↪ docker-compose.yml

+ external-packages  
  ↪ company  
    ↪ my-package (real files here)

但是對於 Docker,該設置不再起作用。 所以訣竅是像這樣在 docker-compose 中安裝一個卷:

volumes:
  - ./:/my-app 
  - ../external-packages/company:/my-app/vendor/company

因此,web 服務器(在容器內)“看到”了vendor中的文件,我們可以在my-package文件夾之間保留符號鏈接(在 Windows 中制作),因此 IDE 也可以看到它們。

我希望這能幫到您。

TL;博士

  1. 以管理員身份運行 git-bash。
  2. 在 git-bash 中發出export MSYS=winsymlinks:nativestrict
  3. 從那里開始, ls -s在 windows 中工作。
  4. 從 docker 內部可以看到鏈接。

細節

我們將按照以下步驟進行:

  1. 准備工作:准備一個臨時目錄,其中包含abc目錄中的一些文件。
  2. 看到它失敗:我們將嘗試創建一個符號鏈接並看到它失敗。
  3. 創建符號鏈接:我們將在 windows 中創建符號鏈接並查看它。 我們將xyz指向abc
  4. 運行 docker:然后我們將運行 docker 和ubuntu並更改xyz中的內容。
  5. 檢查 ubuntu 容器:我們還將在 docker 中看到abc的變化。
  6. 入 windows 主機:從容器外檢查abcxyz

1. 准備

  • 在 git-bash go 到/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

這是一個示例 session:

准備

2.看到失敗

首先讓我們嘗試“正常”的方式,看看它是否失敗。

  • 在 git-bash 中,導航到/c/tmp
  • 然后做一個符號鏈接使xyz指向abcln -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/

這是一個示例 session:

失敗的嘗試

3.創建符號鏈接

真正的東西來了。 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

  • 首先以管理員模式打開一個新的 git-bash。 原因是只有管理員可以在 windows 中創建鏈接。

管理員模式下的 git-bash

  • 成為 CLI 管理員后,導航到目標並設置此環境變量:
export MSYS=winsymlinks:nativestrict

這將告訴 git-bash 的運行時子系統實際使用符號鏈接功能。 因為我們是管理員,所以我們會成功。

  • 正如您所期望的那樣,只是“正常的符號鏈接”: ls -s abc xyz

帶有符號鏈接的 git bash

有用!!! 現在下一步是在 docker 中進行測試!

注意:根據塞巴斯蒂安在https://stackoverflow.com/a/40914277/1315009的回答,如果您啟用了開發人員工具,則無需成為管理員即可在 git-bash 中創建符號鏈接。 在搜索欄中for developers編寫並啟用它:

查找開發工具 啟用開發工具

4. 運行 docker + 5. 簽入 docker

  • 不再需要具有管理員權限的 bash。 所以我們將關閉它並重新實例化一個“正常”的 bash。
  • 在其中,運行帶有 docker 的 ubuntu 容器。 使用-it與 ubuntu 的 bash 交互。 使用winpty允許-it工作。
  • 綁定掛載/c/tmp目錄,以便abcxyz都可以訪問。 我選擇將它掛載到/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

樣品 session:

泊塢窗會議

6.簽入windows主機

  • 從 docker 中走出來。 留在 git-bash 中。
  • 再說一遍:這個 git-bash不需要特權。 我們必須成為管理員的唯一時刻是在 windows 中“創建”符號鏈接。
  • 從非特權 bash 中,探索abcxyz並看到我們從 docker 內部創建的內容,出現在原始目錄和符號鏈接中。

樣品 session:

在此處輸入圖像描述

最終檢查

我們終於可以將 go 轉為經典的CMD看看它的樣子。 我們可以看到它清楚地表明它是一個目錄的符號鏈接,我們還在那里看到了目標:

在此處輸入圖像描述

金色觸感

如果您如上所述激活了“開發人員工具”,則唯一缺少的是 ENV VAR。

我們可以通過在 windows 主頁編輯.bashrc來設置它:

編輯.bashrc 設置環境變量

通過這樣做,我們可以完全正常地使用 git-bash 並開始從 windows 創建符號鏈接而不會出現任何過載。

有用

警告

以這種方式創建的符號鏈接從 windows 工作,並且可以從 docker 內部看到。 但不是對面。 如果您在容器內創建符號鏈接,它們不會在 windows 中創建。

因此,在掛載的卷中,始終從 git-bash 設置符號鏈接並從容器中使用它們。 如果您從容器中創建它們,它們仍然可以從容器中使用。 但不能從 windows 使用。

結論

它可以通過 git-bash 從 linux 風味命令完全完成。 只是您需要成為管理員才能創建鏈接並告訴 git-bash 運行時使用該功能。 並且鏈接需要從 windows 完成,而不是從 ubuntu 內部完成。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM