[Перевод] Сравнительный анализ Docker Engine на платформах Windows Server и Linux
На конференции было много новостей. Но, пожалуй, самой горячей стала новость о партнёрстве Docker Inc. и Microsoft в области поддержки Docker Engine на платформе Windows Server 2016.
В рамках этого партнёрства Microsoft позволит пользователям Windows Server 2016 бесплатно работать с Docker Engine и обеспечит базовую техническую поддержку. Сложными проблемами будет заниматься техподдержка Docker Inc.
В Windows Server 2016 теперь имеется встроенная поддержка контейнеров Docker и предлагается два способа развёртывания контейнеров: Windows Server Containers и Hyper-V Containers, что предусматривает дополнительный уровень изоляции для многоарендных сред. Поддержка Docker интегрирована в широкий набор средств разработки от Microsoft, в операционные системы и облачную инфраструктуру, в том числе в следующие технологии:
- Windows Server 2016
- Hyper-V
- Visual Studio
- Microsoft Azure
Если вы — приверженец Linux, вроде меня, то вам, должно быть, не терпится узнать, насколько различается Docker Engine на платформах Windows Server и Linux. В этом материале я собираюсь рассказать об архитектурных различиях, об интерфейсе командной строки, который работает под обеими платформами, о сборке образов с помощью Dockerfile, о некоторых других особенностях работы с Docker на платформе Windows.
Начнём с архитектурных различий контейнеров Windows и Linux.
Docker Engine на платформе Linux
Если рассмотреть Docker Engine на платформе Linux, то сразу бросаются в глаза инструменты командной строки вроде Docker Compose, Docker Client, Docker Registry, и так далее, которые используют Docker REST API. Пользователи взаимодействуют с Docker Engine, а, в свою очередь, Docker Engine работает с демоном containerd. Демон использует runC или другую OCI-совместимую среду выполнения для запуска контейнеров.
В основе этой архитектуры находятся функции ядра, наподобие пространств имён, которые обеспечивают изоляцию контейнеров. Тут же находятся контрольные группы и другие низкоуровневые механизмы. Всё это позволяет реализовать изоляцию контейнеров, распределение и ограничение ресурсов. В результате каждому контейнеру можно выделить необходимую ему долю памяти, процессорного времени, ресурсов дискового накопителя. При этом, что очень важно, отдельный контейнер не может нарушить работу системы, единолично захватив один из этих ресурсов.
Docker Engine на платформе Linux
Docker Engine на платформе Windows
В Windows всё устроено несколько иначе. Архитектура большинства высокоуровневых компонентов выглядит точно так же, как на Linux. Это и то же самое Remote API, те же рабочие инструменты (Docker Compose, например), но глубже, ближе к ядру, всё уже не так, как в Linux. Тут, для тех, кто не очень хорошо ориентируется в вопросах, связанных с ядром Windows, хочу отметить, что ядра Windows и Linux — это далеко не одно и то же. Дело в том, что Microsoft применяет несколько иной подход к проектированию ядра, нежели тот, которому следует сообщество разработчиков Linux. А именно, термин «режим ядра» на языке Microsoft относится не только к самому ядру системы, но и к уровню аппаратных абстракций (hal.dll), и к различным системным службам. Здесь имеются модули, предназначенные для управления объектами, процессами, памятью, безопасностью, кэшем, технологией PnP, электропитанием, настройками, операциями ввода-вывода. Всё вместе это называется исполнительной системой Windows (Windows Executive, ntoskrnl.exe).
Среди возможностей ядра в Windows нет пространств имён и контрольных групп. Вместо этого команда Microsoft, работая над новой версией Windows Server 2016, представила так называемый «Compute Service Layer», дополнительный слой служб на уровне операционной системы, который предоставляет функции пространств имён, управление ресурсами, и возможности, похожие на UFS. Кроме того, как вы увидите ниже, на платформе Windows нет чего-либо, соответствующего демону containerd и среде runC. Compute Service Layer предоставляет общедоступный интерфейс к контейнеру и несёт ответственность за управление контейнерами, за выполнение операций вроде их запуска и остановки, но он не контролирует их состояние, как таковое. Если в двух словах, то он заменяет containerd на Windows и абстрагирует низкоуровневые возможности, которые предоставляет ядро.
Docker Engine на платформе Windows
На рисунке ниже показаны механизмы ядра Windows, созданные для поддержки контейнеров. В самом низу — совместно используемое ядро, то же самое мы уже видели на Linux. Блок Host User Mode — это хост-система Windows, в основном — системные процессы. Гораздо более важные компоненты размещены в правой части рисунка — это System Processes и Application Processes, системные процессы и процессы приложений в контейнерах Windows Server, которые, в сравнении с Linux, работают иначе. Обычная для Linux практика — хорошее документирование механизма вызова системы, а также гарантия его стабильности для разных версий ядра. В Windows механизм вызова системы не документирован, при этом речь не идёт и о гарантиях его единообразного поведения. Единственный способ сделать системный вызов в Windows заключается в обращении к ntdll.dll. В контейнеры Windows входит множество взаимосвязанных процессов, вызывающих друг друга, поэтому они имеют довольно большой размер.
Контейнеры в Windows Server (источник: DockerCon 2016)
Важно отметить, что в файлах Dockerfile для Windows не используется команда «FROM scratch», то есть, нет такого понятия, как «пустой образ». Это так из-за большого числа взаимосвязанных системных процессов, необходимых для предоставления базовой функциональности. Microsoft сделала свои базовые образы в следующих двух вариантах:
- Microsoft/windowsservercore — это обычный Windows Server с .NET 4.5, он занимает 9.3 Гб, что немало, поддерживает существующие приложения Windows.
- Microsoft/nanoserver — размер этого образа значительно меньше, около 600 Мб, здесь не предусмотрено графической среды. Этот сервер работает быстро, требует меньше памяти, но предоставляет меньше API и может быть несовместим с некоторыми существующими приложениями.
Пара слов о пространствах имён в Windows
В Windows нет концепции «пространств имён», соответствующей пространствам имён в Linux. Однако, на пространства имён Linux здесь весьма похожа концепция приёмников команд (silos) — расширение к объектам-заданиям Windows (Windows Job objects) — набору процессов, ресурсами которых можно управлять. При этом появляется то, что называется пространством имён процесса, пользователя, объекта, сети, и так далее. Пространство имён объекта — это пространство имён системного уровня, скрытое от пользователя. Так же, как и Linux, Windows имеет корневую папку (\) на уровне NT для всех устройств. Например, «C\Windows» отображается на \DosDevices\C:\Windows, или на \Device\Tcp, если речь идёт о сети.
Начало работы с Docker на Windows 2016 Server
Обратите внимание на то, что для того, чтобы опробовать то, о чём я сейчас расскажу, вам понадобится Windows 2016 Server Evaluation сборки 14393. Если попытаться выполнить стандартную процедуру установки Docker на старую версию Windows 2016 TP5, появится сообщение об ошибке.
Сообщение об ошибке
Не забудьте и о том, что обновить систему TP5 на новую версию не получится. Поэтому для того, чтобы попробовать новейший Docker 1.12.2, понадобится установить ОС Windows Server Evaluation, которую можно загрузить отсюда.
Когда нужная версия Windows Server будет установлена, выполните нижеприведённые команды, соблюдая их последовательность:
Invoke-WebRequest "https://download.docker.com/components/engine/windows-server/cs-1.12/docker.zip" -OutFile "$env:TEMP\docker.zip" -UseBasicParsing
Expand-Archive -Path "$env:TEMP\docker.zip" -DestinationPath $env:ProgramFiles
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\Program Files\Docker", [EnvironmentVariableTarget]::Machine)
dockerd --register-service
Start-Service Docker
Этих команд в большинстве случаев будет вполне достаточно для того, чтобы установить Docker и не столкнуться при этом с какими-либо проблемами.
Кстати, 10 ноября я узнал, что Windows 2016 Final Release и Nano Server доступны на платформе Azure.
Приступая к работе с контейнерами в Windows Server 2016, в которой установлен соответствующий компонент, проверьте, запущен ли сервис Docker:
docker version
Если вы столкнулись с сообщениями об ошибках, наподобие показанных ниже, которые довелось увидеть мне, выполните такую команду:
Start-Service Docker
Сообщения об ошибках и запуск Docker
Теперь вы можете найти Windows-приложения, подготовленные для Docker, используя такую команду:
docker search microsoft
Вот, например, что удалось найти мне.
Результаты поиска приложений
Ещё можно воспользоваться такой командой:
docker search windows
В ответ система выведет примерно такой список:
Результаты поиска приложений
Об ограничениях Docker на Windows
- На платформе Windows Linux-контейнеры работать не будут. Вот что система сообщает по этому поводу:
Docker на Windows и Linux-контейнеры - На платформе Windows всё ещё не поддерживается DTR.
- Нельзя, с помощью команды
docker commit
, зафиксировать изменения в исполняющемся контейнере и создать на его основе новый образ (на Linux это — обычное дело). - Docker для Windows пока не поддерживает Swarm Mode.
Использование Dockerfile в Windows и образ с MySQL
На платформе Windows Server можно создавать контейнеры с использованием файлов Dockerfile. Возьмём пример такого файла для MySQL и соберём на его основе контейнер MySQL. Мне подходящий файл попался где-то на GitHub и я решил взглянуть на то, как механизм создания образов с помощью Dockerfile работает на Windows. Этот файл выглядит так:
FROM microsoft/windowsservercore
LABEL Description="MySql" Vendor="Oracle" Version="5.6.29″
RUN powershell -Command \
$ErrorActionPreference = ‘Stop’; \
Invoke-WebRequest -Method Get -Uri https://dev.mysql.com/get/Downloads/MySQL-5.6/mysql-5.6.29-winx64.zip -OutFile c:\mysql.zip ; \
Expand-Archive -Path c:\mysql.zip -DestinationPath c:\ ; \
Remove-Item c:\mysql.zip -Force
RUN SETX /M Path %path%;C:\mysql-5.6.29-winx64\bin
RUN powershell -Command \
$ErrorActionPreference = ‘Stop’; \
mysqld.exe –install ; \
Start-Service mysql ; \
Stop-Service mysql ; \
Start-Service mysql
RUN type NUL > C:\mysql-5.6.29-winx64\bin\foo.mysql
RUN echo UPDATE user SET Password=PASSWORD(‘mysql123′) WHERE User=’root’; FLUSH PRIVILEGES; .> C:\mysql-5.6.29-winx64\bin\foo.mysql
RUN mysql -u root mysql < C:\mysql-5.6.29-winx64\bin\foo.mysql
Всё сработало как ожидалось, образ MySQL был собран быстро и без проблем. Вот мой репозиторий «докеризованного» MySQL для Windows (правда, мне ещё надо заполнить его описание).
MySQL для Windows
Итоги
Docker для Windows — технология очень молодая, поэтому она пока не поддерживает все те возможности, которые имеются у Linux-версии. Однако, существующие наработки, усилия компаний и сообществ независимых разработчиков, вселяют надежду в то, что полноценное использование Docker на платформе Windows — дело недалёкого будущего.
Кстати, если вы хотите продолжить знакомство с Docker для Windows — взгляните на этот регулярно пополняемый и обновляемый набор материалов от Microsoft.