簡體   English   中英

無法在 Windows Docker 容器中運行 cygwin

[英]Unable to run cygwin in Windows Docker Container

我一直在使用 Docker for Windows,嘗試創建一個 Windows 容器,該容器可以將 cygwin 作為容器本身內的 shell 運行。 我還沒有運氣好讓這一切順利進行。 這是我一直在搞亂的 Dockerfile。

# escape=`
FROM microsoft/windowsservercore

SHELL ["powershell", "-command"]

RUN Invoke-WebRequest https://chocolatey.org/install.ps1 -UseBasicParsing | Invoke-Expression
RUN choco install cygwin -y
RUN refreshenv
RUN [Environment]::SetEnvironmentVariable('Path', $env:Path + ';C:\tools\cygwin\bin', [EnvironmentVariableTarget]::Machine)

我試過設置 ENTRYPOINT 和 CMD 來嘗試進入 cygwin,但似乎都沒有做任何事情。 我還使用docker run -it連接到容器並docker run -it了 cygwin 命令以進入 shell,但它似乎沒有做任何事情。 我沒有收到錯誤,它只是返回到命令提示符,就好像什么都沒發生一樣。

是否可以在 Windows 容器中運行另一個 shell,或者我只是做錯了什么?

謝謝!

您不會使用docker run “附加”到容器:您使用它啟動容器。

在您的情況下,如此處所見docker run -it是正確的方法。

您可以嘗試使用c:\\cygwin\\bin\\bash作為入口點,如本期所示

正如問題 32330 中所評論的:

不要誤會我的意思,cygwin 應該在 Docker Windows 容器中工作。

但是,也有點自相矛盾的是,容器被精心制作到 Windows 中,以 Linux 上的容器為模型,只是為了讓人們想要在這些新創建的 Docker Windows 容器中運行 Linux-utils ......

同樣的問題仍未解決,新案例出現在 2018 年 5 月和 6 月:

我們有一個使用 Visual Studio 編譯的環境,但我們仍然想使用 git 和一些來自 linux 的非常有用的命令。
此外,我們還使用了使用 linux 命令(例如 curl、grep...)的現成實用程序(例如 git-repo)

一些構建需要 Cygwin,比如 ICU(一個基於 Unicode 的跨平台全球化庫) ,最糟糕的是:我們的構建需要從源代碼構建它。


您可以在MSYS2-packages 問題 1239 中看到崩潰的示例:

Step 5/5 : RUN "C:\\msys64\\usr\\bin\\ls.exe"
 ---> Running in 5d7867a1f8da
The command 'cmd /S /C "C:\\msys64\\usr\\bin\\ls.exe"' returned a non-zero code: 3221225794

這可以獲得有關崩潰的更多信息:

PS C:\msys64\usr\bin> 
  Get-EventLog -Index 28,29,30 -LogName "Application" | Format-List -Property *

解決方法是:

PS > xcopy /S C:\Git C:\Git_Copy
PS > C:\Git_Copy\usr\bin\sh.exe --version > v.txt
PS > type v.txt

如該線程中所述,輸出在容器中的某處丟失,因此將其發送到文本文件。

玩了很長時間后,我的發現如下:

  • 如果 Cygwin 實用程序使容器崩潰,則需要使用進程隔離 請參閱https://docs.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/version-compatibility了解要求(本質上您需要使用 Windows Server 2016 和構建匹配的 Docker 映像)。 我花了一些時間試圖理解 hyper-v 隔離不起作用的原因,到目前為止我沒有得出任何結論;

  • 如果您的 Cygwin 實用程序顯然什么都不做- 但它們不會使容器崩潰 -您需要刪除 -t 標志(-i 標志仍然可以)或者使用 stdout redirection 顯然,MSYS2 在處理一些偽 tty 時似乎存在問題。 如果您將 stdout 重定向到文件,您可以驗證程序仍然運行(例如,當您在沒有任何 stdout 重定向的情況下運行它時 whoami 不會輸出任何內容,但是 whoami > out.txt 會將預期結果輸出到文件)。 可以通過替換偽 tty 來解決這個問題,但我沒有嘗試過。 我懷疑問題是 MSYS2 庫內某處的句柄無效 - 因為其他控制台應用程序可以將內容打印到終端 - 但我沒有驗證這一點。

希望對遇到同樣問題的大家有所幫助。

通過以下兩個步驟,我能夠獲得 Cygwin 的預安裝(從主機復制)副本,以在基於 nanoserver 的容器中工作:

  1. 在 docker run cmd-line 中使用 Żubrówka 對no -t的建議(以交互方式運行 docker 時)
  2. 將主機(Windows Server 2016)的kernel32.dll復制到容器的 c:\\windows\\system32

我在我的系統上找到了 kernel32.dll 的多個版本,並使用了來自 c:\\windows\\system32 和 md5 hash d8948a7af764f7153b3e396ad44992ff 的版本

這也使大量其他可執行文件工作。 請注意,如果沒有 tty,使用容器會更加麻煩,而且 bash shell 不會呈現提示。 但是,依賴於 cygwin 組件的腳本(通過 Jenkins,在我的例子中)運行良好。

如果那沒有幫助,請嘗試本指南,它對我幫助很大。 如果您的 Windows 應用程序(除了 cygwin)合法地缺少 DLL,本指南中的說明可以提供幫助。 我從來沒有想過 SysInternals 的 procmon.exe 可以在主機上運行並且仍然報告來自容器的事件!

暫無
暫無

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

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