关于shell:无法在Windows Docker Container中运行cygwin

Unable to run cygwin in Windows Docker Container

我一直在与Docker for Windows合作,试图创建一个Windows容器,它可以将cygwin作为容器内部的shell运行。我还没来得及把这事办好。这是我搞砸的码头文件。

1
2
3
4
5
6
7
8
9
# 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连接到容器上,并发出cygwin命令进入外壳,但它似乎没有任何作用。我没有得到错误,它只是返回到命令提示符,好像什么都没有发生。

是否可以在Windows容器中运行另一个shell,或者我只是做了一些不正确的事情?

谢谢!


使用docker run时,不能"附加"到容器:使用它启动容器。

在您的案例中,如这里所见,docker run -it是正确的方法。

您可以尝试使用c:\cygwin\bin\bash作为入口点,如本期所示。

如第32330期所述:

Don't get me wrong, cygwin should work in Docker Windows containers.

But, it's also a little paradoxical that containers were painstakingly wrought into Windows, modeled on containers on Linux, only for people to then want to run Linux-utils in these newly minted Docker Windows containers...

同样的问题仍未解决,2018年5月和6月出现了新的案例:

We have an environment that compiles with Visual Studio but still we want to use git and some very useful commands taken from linux.
Also we use of-the-shelve utilities (e.g. git-repo) that uses linux commands (e.g. curl, grep,...)

Some builds require Cygwin like ICU (a cross-platform Unicode based globalization library), and worst: our builds require building it from source.

您可以看到MSys2软件包问题1239中的崩溃示例:

1
2
3
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

这可以获得关于车祸的更多信息:

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

解决方法是:

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

As mentioned in that thread, the output gets lost somewhere in the container, thus sending it to a text file.


我可以通过以下两个步骤将cygwin的预安装(从主机复制)副本安装到基于NanoServer的容器中:

  • 使用?ubr_wka对docker run cmd行中no-t的建议(交互运行docker时)
  • 将主机(Windows Server 2016)kernel32.dll复制到容器的C:windowssystem32
  • 我在系统上找到了kernel32.dll的服务器版本,并使用了c:windowssystem32中带有MD5哈希D8948A7AF764F7153B3E396AD44992FF的版本。

    这也使得许多其他可执行文件都可以工作。注意,如果没有tty,使用容器会更麻烦,bash shell不会呈现提示。但是,依赖Cygwin组件的脚本(在我的例子中是通过Jenkins)工作正常。

    如果这没有帮助,试试这个指南,它帮助了我很多。如果您的Windows应用程序(Cygwin除外)合法地丢失了DLL,本指南中的说明将有所帮助。我从未想过SysInternals的procmon.exe可以在主机上运行,并且仍然可以从容器中报告事件!


    在玩了很长时间之后,我的发现是:

    • 如果您的cygwin实用程序崩溃您的容器,您需要使用进程隔离。有关要求,请参阅https://docs.microsoft.com/en-us/virtualization/windows containers/deploy-containers/version-compatibility(基本上,您需要使用Windows Server 2016和构建匹配的Docker映像)。我花了一段时间试图理解为什么超V隔离不起作用,到目前为止我还没有得出任何结论;

    • 如果您的cygwin实用程序显然什么都不做-但它们不会崩溃容器-您需要删除-t标志(i标志仍然可以),或者使用stdout重定向进行播放。显然,当msys2处理一些伪tty时,它似乎存在一个问题。如果将stdout重定向到一个文件,您可以验证程序是否仍然运行(例如,在没有stdout重定向的情况下运行时,whoami不会输出任何内容,但whoami>out.txt会将预期结果输出到一个文件)。可能可以通过替换伪tty来解决这个问题,但我没有尝试过。我怀疑这个问题是MSys2libs中某个地方的一个无效句柄——因为其他控制台应用程序可以将内容打印到终端上——但是我没有验证这个问题。

    希望它能帮助你们所有遇到同样问题的人。