Не удалось запустить cygwin в Windows Docker Container

Я работал с Docker для Windows, пытаясь создать контейнер для Windows, который может запускать cygwin в качестве оболочки внутри самого контейнера. Мне не повезло, что все это закончилось. Здесь 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, чтобы попасть в оболочку, но, похоже, ничего не делает. Я не получаю сообщение об ошибке, он просто возвращается в командную строку, как будто ничего не произошло.

Возможно ли запустить другую оболочку в контейнере Windows, или я просто делаю что-то неправильно?

Благодарю!

Ответ 1

Вы не "прикрепляетесь" к контейнеру с docker run: вы запускаете с ним контейнер.

В вашем случае, как показано здесь, docker run -it - правильный подход.

Вы можете попробовать как точку входа, используя c:\cygwin\bin\bash, как видно из этой проблемы.

Как отмечалось в выпуске 32330:

Не поймите меня неправильно, cygwin должен работать в контейнерах Docker Windows.

Но также немного парадоксально, что контейнеры были тщательно обработаны в Windows, смоделированные на контейнерах в Linux, только для людей, которые затем хотят запускать Linux-utils в этих недавно отчеканенных контейнерах Docker Windows...

Этот же вопрос все еще остается нерешенным, поскольку в мае и июне 2018 года был рассмотрен новый случай:

У нас есть среда, которая компилируется с помощью Visual Studio, но мы все же хотим использовать git и некоторые очень полезные команды, взятые из linux.
Также мы используем утилиты-shelve (например, git-repo), которые используют команды linux (например, curl, grep,...)

Некоторые сборки требуют Cygwin как ICU (кросс-платформенная библиотека глобализации на основе Unicode), и хуже всего: наши сборки требуют создания из источника.


Вы можете увидеть пример сбоя в выпуске MS392-пакетов 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

Как упоминалось в этом потоке, выход теряется где-то в контейнере, тем самым отправляя его в текстовый файл.

Ответ 2

После игры с ним в течение долгого времени мои выводы были следующими:

  • Если ваши утилиты Cygwin разбивают ваш контейнер, вам необходимо использовать изоляцию процесса. См. Https://docs.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/version-compatibility для требований (по сути, вам необходимо использовать Windows Server 2016 и образ Docker Image). Я потратил некоторое время, пытаясь понять причину, по которой гипер-v изоляция не работает, и до сих пор я не пришел к какому-либо заключению;

  • Если ваши утилиты Cygwin, по-видимому, ничего не делают, но они не разбивают контейнер - вам нужно удалить флаг -t (флаг -i по-прежнему в порядке) или альтернативно играть с перенаправлением stdout. По-видимому, проблема с MSYS2 возникает, когда речь идет о некоторых псевдо -t tys. Вы можете проверить, что программы все еще выполняются, если вы перенаправляете stdout в файл (например, whoami ничего не выводит при запуске без перенаправления stdout, но whoami> out.txt выводит ожидаемый результат в файл). Возможно, это можно исправить, заменив псевдо -t ty, но я не пробовал. Я подозреваю, что проблема - это недопустимый дескриптор где-то внутри библиотек MSYS2, поскольку другие консольные приложения могут печатать вещи на терминале, но я этого не проверял.

Надеюсь, это поможет всем вам с той же проблемой.

Ответ 3

Я смог получить предварительно установленную (скопированную с хоста) копию Cygwin для работы в контейнере на основе наносервера с этими двумя шагами:

  1. Используя рекомендацию Żubrówka для -t в командной строке docker rund (при запуске докера в интерактивном режиме)
  2. Копирование хоста (Windows Server 2016) kernel32.dll в контейнер c:\windows\system32

Я нашел серверные версии kernel32.dll в своей системе и использовал один из c:\windows\system32 с хешем md5 d8948a7af764f7153b3e396ad44992ff

Это также привело к большому количеству других исполняемых файлов. Обратите внимание, что без tty использование контейнера еще более громоздко, а оболочка bash не отображает приглашение. Тем не менее, скрипты (через Jenkins, в моем случае), которые полагаются на компоненты cygwin, работают нормально.

Если это не поможет, попробуйте это руководство, это очень помогло мне. Если ваше приложение Windows (кроме cygwin) является законно отсутствующим DLL, инструкции в этом руководстве могут помочь. Мне никогда не приходило в голову, что procmon.exe SysInternals может быть запущен на хосте и все еще сообщать о событиях из контейнера!