【问题标题】:Unable to run cygwin in Windows Docker Container无法在 Windows Docker 容器中运行 cygwin
【发布时间】:2017-03-30 16:48:08
【问题描述】:

我一直在使用 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 附加到容器并启动了 cygwin 命令以进入 shell,但它似乎没有做任何事情。我没有收到错误,它只是返回到命令提示符,就好像什么都没发生一样。

是否可以在 Windows 容器中运行另一个 shell,或者我只是做错了什么?

谢谢!

【问题讨论】:

  • 似乎有一整类二进制文件不在 Windows docker 容器中运行(静默退出)。 Cygwin 二进制文件就是一个例子。 64 位不是问题,因为它发生在 nanoserver 和 windowsservercore 上。如果有人知道这笔交易是什么,请插话。
  • @Akom 对此有何想法/进展?遇到了同样的问题,容器只是崩溃了
  • 我将为此开一个赏金,因为这是一个需要解决的重要主题 - 在 DevOps 环境中非常相关
  • @Żubrówka 我已经编辑了我的答案:没有决定性的进展,除了可能的解决方法。
  • @Żubrówka,我没有看到容器崩溃,这是无法在容器中运行的可执行文件。我对此一无所知。我看到有几张类似症状的票被打开,但没有找到解释。

标签: windows shell docker cygwin


【解决方案1】:

你不能用docker run“附加”到一个容器:你用它来启动一个容器。

在您的情况下,seen heredocker run -it 是正确的方法。

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

正如issue 32330中评论的那样:

别误会,cygwin 应该在 Docker Windows 容器中工作。

但是,同样有点自相矛盾的是,容器被精心打造到 Windows 中,以 Linux 上的容器为模型,只是为了让人们想要在这些新创建的 Docker Windows 容器中运行 Linux-utils...

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

我们有一个使用 Visual Studio 编译的环境,但我们仍然想使用 git 和一些从 linux 获取的非常有用的命令。
我们还使用使用 linux 命令(例如 curl、grep、...)的现成实用程序(例如 git-repo)

有些构建需要 Cygwin like ICU (a cross-platform Unicode based globalization library),最糟糕的是:我们的构建需要从源代码构建它。


你可以在MSYS2-packages issue 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 *

The workaround 是:

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

正如该线程中提到的,输出在容器中的某处丢失,因此将其发送到文本文件。

【讨论】:

    【解决方案2】:

    玩了很久,我的发现如下:

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

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

    希望对遇到同样问题的大家有所帮助。

    【讨论】:

    • 有趣的设置,比我的回答更精确。 +1
    【解决方案3】:

    通过以下两个步骤,我能够获得预安装(从主机复制)的 Cygwin 副本,以便在基于 nanoserver 的容器中工作:

    1. 在 docker run 命令行中使用 Żubrówka 对 no -t 的建议(以交互方式运行 docker 时)
    2. 将主机的 (Windows Server 2016) kernel32.dll 复制到容器的 c:\windows\system32

    我在我的系统上找到了多个版本的 kernel32.dll,并使用了来自 c:\windows\system32 的带有 md5 哈希的版本d8948a7af764f7153b3e396ad44992ff

    这也使大量其他可执行文件工作。请注意,没有 tty,使用容器更加麻烦,并且 bash shell 不会呈现提示。但是,依赖 cygwin 组件的脚本(在我的例子中是通过 Jenkins)可以正常工作。

    如果这没有帮助,请尝试this guide,它对我帮助很大。如果您的 Windows 应用程序(cygwin 除外)合法缺少 DLL,则本指南中的说明可以提供帮助。我从来没有想过 SysInternals 的 procmon.exe 可以在主机上运行并且仍然报告来自容器的事件!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-08-10
      • 2020-04-12
      • 1970-01-01
      • 2022-07-18
      • 1970-01-01
      • 2019-05-05
      • 2017-03-02
      • 2018-09-21
      相关资源
      最近更新 更多