В *nix-системах изначально реализована многозадачность и предлагаются средства, позволяющие изолировать и контролировать процессы. Такие технологии, как chroot(), обеспечивающая изоляцию на уровне файловой системы, FreeBSD Jail, ограничивающая доступ к структурам ядра, LXC и OpenVZ, давно известны и широко используются. Но импульсом в развитии технологии стал Docker, позволивший удобно распространять приложения. Теперь подобное добралось и до Windows.

 

Контейнеры в Windows

Современные серверы обладают избыточной производительностью, и приложения порой не используют даже их части. В результате системы какое-то время «простаивают», нагревая воздух. Выходом стала виртуализация, позволяющая запускать несколько ОС на одном сервере, гарантированно разделяя их между собой и выделяя каждой нужное количество ресурсов. Но прогресс не стоит на месте. Следующий этап — микросервисы, когда каждая часть приложения развертывается отдельно, как самодостаточный компонент, который легко масштабируется под нужную нагрузку и обновляется. Изоляция предотвращает вмешательство в работу микросервиса со стороны других приложений. С появлением проекта Docker, упростившего процесс упаковки и доставки приложений вместе с окружением, архитектура микросервисов получила дополнительный толчок в развитии.

Контейнеры — это иной тип виртуализации, предоставляющий обособленную среду для выполнения приложений, называемую OS Virtualization. Реализуются контейнеры за счет использования изолированного пространства имен, включающего все необходимые для работы ресурсы (виртуализированные имена), с которыми можно взаимодействовать (файлы, сетевые порты, процессы и прочее) и выйти за которые нельзя. То есть ОС показывает контейнеру только то, что выделено. Приложение внутри контейнера считает, что оно единственное, и работает в полноценной ОС без каких-либо ограничений. Если необходимо изменить существующий файл или создать новый, контейнер получает копии с основной ОС хоста, сохраняя только измененные участки. Поэтому развертывание нескольких контейнеров на одном хосте очень эффективно.

Отличие контейнеров от виртуальных машин заключается в том, что контейнеры не загружают собственные копии ОС, библиотеки, системные файлы и прочее. Операционная система как бы делится с контейнером. Единственное, что дополнительно требуется, — это ресурсы, необходимые для запуска приложения в контейнере. В результате контейнер стартует в считаные секунды и меньше нагружает систему, чем в случае применения виртуальных машин. Docker в настоящее время предлагает 180 тысяч приложений в репозитории, а формат унифицирован в Open Container Initiative (OCI). Но зависимость от ядра подразумевает, что в другой ОС контейнеры не будут работать. Контейнеры Linux требуют Linux API, соответственно Windows в Linux работать не станет.

Разработчики Windows до недавнего времени предлагали две технологии виртуализации: виртуальные машины и виртуальные приложения Server App-V. Каждая имеет свою нишу применения, свои плюсы и минусы. Теперь ассортимент стал шире — в Windows Server 2016 анонсированы контейнеры (Windows Server Containers). И хотя на момент TP4 разработка еще не была завершена, уже вполне можно посмотреть новую технологию в действии и сделать выводы. Нужно отметить, что, догоняя и имея на руках готовые технологии, разработчики MS пошли в некоторых вопросах чуть дальше, так что использование контейнеров стало проще и более универсальным. Главное отличие в том, что предложены два вида контейнеров: контейнеры Windows и контейнеры Hyper-V. В TP3 были доступны только первые.

Контейнеры Windows используют одно ядро с ОС, которое динамично разделяют между собой. Процесс распределения (CPU, ОЗУ, сеть) берет на себя ОС. При необходимости можно ограничить максимально доступные ресурсы, выделяемые контейнеру. Файлы ОС и запущенные службы проецируются в пространство имен каждого контейнера. Такой тип контейнера эффективно использует ресурсы, уменьшая накладные расходы, а значит, позволяет более плотно размещать приложения. Этот режим в чем-то напоминает FreeBSD Jail или Linux OpenVZ.

Контейнеры Hyper-V обеспечивают дополнительный уровень изоляции при помощи Hyper-V. Каждому контейнеру выделяется свое ядро и память, изоляцию осуществляет не ядро ОС, а гипервизор Hyper-V. В результате достигается такой же уровень изоляции, как и в виртуальных машинах, при меньших накладных расходах по сравнению с VM, но больший, если сравнить с контейнерами Windows. Для использования такого вида контейнеров нужно установить на хосте роль Hyper-V. Контейнеры Windows больше подходят для использования в доверенной среде, например когда на сервере запускаются приложения одной организации. Когда же сервером пользуются множество компаний и необходимо обеспечить больший уровень изоляции, контейнеры Hyper-V, вероятно, будут более рациональны.

Важная особенность контейнеров в Win 2016 состоит в том, что тип выбирается не в момент создания, а в момент деплоя. То есть любой контейнер может быть запущен и как Windows, и как Hyper-V.

В Win 2016 за контейнеры отвечает слой абстракции Contаiner Management stack, реализующий все нужные функции. Для хранения используется формат образа жесткого диска VHDX. Контейнеры, как и в случае с Docker, сохраняются в образы в репозитории. Причем каждый сохраняет не полный набор данных, а только отличия создаваемого образа от базового, и в момент запуска все нужные данные проецируются в память. Для управления сетевым трафиком между контейнером и физической сетью служит Virtual Switch.

В качестве ОС в контейнере может использоваться Server Core или Nano Server. Первый, в общем-то, давно не новинка и обеспечивает высокий уровень совместимости с имеющимися приложениями. Второй — еще более урезанная версия для работы без монитора, позволяющая запускать сервер в минимально возможной конфигурации для использования с Hyper-V, файловым сервером (SOFS) и облачными службами. Графический интерфейс, естественно, отсутствует. Содержит только самые необходимые компоненты (.NET с CoreCLR, Hyper-V, Clustering и так далее). Но в итоге занимает на 93% меньше места, требует меньше критических исправлений.

Еще интересный момент. Для управления контейнерами, кроме традиционного PowerShell, можно использовать и Docker. И чтобы обеспечить возможность запуска неродных утилит на Win, MS заключила партнерское соглашение для расширения API Docker и набора инструментов. Все разработки открыты и доступны в официальном GitHub проекта Docker. Команды управления Docker применимы ко всем контейнерам как Win, так и Linux. Хотя, естественно, контейнер, созданный на Linux, запустить в Windows невозможно (как и наоборот). В настоящий момент PowerShell по функциям ограничен и позволяет работать только с локальным репозиторием.

 

Установка Containers

В Azure есть необходимый образ Windows Server 2016 Core with Containers Tech Preview 4, который можно развернуть и использовать для изучения контейнеров. Иначе необходимо все настроить самому. Для локальной установки нужен Win 2016, причем, так как Hyper-V в Win 2016 поддерживает вложенную виртуализацию (Nested virtualization), это может быть как физический, так и виртуальный сервер. Сам процесс установки компонента стандартен. Выбираем соответствующий пункт в мастере добавления ролей и компонентов или, используя PowerShell, даем команду

PS> Install-WindowsFeature Containers
Установка компонента Containers в диспетчере серверов
Установка компонента Containers в диспетчере серверов

В процессе установится и сетевой контроллер Virtual Switch, его сразу необходимо настроить, иначе дальнейшие действия будут выдавать ошибку. Смотрим названия сетевых адаптеров:

PS> Get-NetAdapter

Для работы нам нужен контроллер с типом External. У командлета New-VMSwitch много параметров, но для примера обойдемся минимальными установками:

PS> New-VMSwitch -Name External -NetAdapterName Ethernet0

Проверяем:

PS> Get-VMSwitch | where {$_.SwitchType –eq "External"}
Настройка Virtual Switch
Настройка Virtual Switch

Файрвол Windows будет блокировать соединения к контейнеру. Поэтому необходимо создать разрешающее правило, как минимум для возможности подключаться удаленно при помощи PowerShell remoting, для этого разрешим TCP/80 и создадим правило NAT:

PS> New-NetFirewallRule -Name "TCP80" -DisplayName "HTTP on TCP/80" -Protocol tcp -LocalPort 80 -Action Allow -Enabled True
PS> Add-NetNatStaticMapping -NatName "ContainerNat" -Protocol TCP -ExternalIPAddress 0.0.0.0 -InternalIPAddress 192.168.1.2 -InternalPort 80 -ExternalPort 80

Есть еще один вариант простого развертывания. Разработчики приготовили скрипт, позволяющий установить все зависимости автоматически и настроить хост. При желании можно воспользоваться им. Параметры внутри скрипта помогут понять все механизмы:

PS> https://aka.ms/tp4/Install-ContainerHost -OutFile C:\Install-ContainerHost.ps1
PS> C:\Install-ContainerHost.ps1

Есть еще один вариант — развернуть готовую виртуальную машину с поддержкой контейнера. Для этого на том же ресурсе есть скрипт, автоматически производящий все нужные операции. Подробная инструкция приведена на MSDN. Скачиваем и запускаем скрипт:

PS> wget -uri https://aka.ms/tp4/New-ContainerHost -OutFile c:\New-ContainerHost.ps1
PS> C:\New-ContainerHost.ps1 –VmName WinContainer -WindowsImage ServerDatacenterCore
Готовим контейнер
Готовим контейнер

Имя задаем произвольное, а -WindowsImage говорит о типе собираемого образа. Вариантами могут быть NanoServer, ServerDatacenter. Сразу ставится и Docker, за его отсутствие или наличие отвечает параметр SkipDocker и IncludeDocker. После запуска начнется загрузка и преобразование образа, в процессе нужно будет указать пароль для входа в VM. Сам ISO-файл достаточно большой, почти 5 Гбайт. Если канал медленный, файл можно скачать на другом компьютере, после чего переименовать в WindowsServerTP4 и скопировать в С:\Users\Public\Documents\Hyper-V\Virtual Hard Disks. Можем залогиниться в установленную виртуальную машину, указав пароль, заданный при сборке, и работать.

Теперь можно переходить непосредственно к использованию контейнеров.

 

Использование контейнеров с PowerShell

Модуль Containers содержит 32 командлета PowerShell, документация по некоторым еще неполная, хотя, в общем, чтобы заставить все работать, достаточная. Перечень вывести просто:

PS> Get-Command -module Containers
Список командлетов модуля Containers
Список командлетов модуля Containers

Получить список доступных образов можно при помощи командлета Get-ContainerImage, контейнеров — Get-Container. В случае с контейнером в колонке Status будет показан его текущий статус: остановлен или запущен. Но пока технология находится в стадии разработки, MS не представила репозиторий, да и, как говорилось, пока PowerShell работает с локальным репозиторием, поэтому для экспериментов его придется создать самому.

Итак, сервер с поддержкой у нас есть, теперь нужны сами контейнеры. Для этого ставим провайдер пакетов ContainerProvider.

PS> Install-PackageProvider ContainerProvider -Force

Смотрим список доступных в OneGet образов.

PS> Find-ContainerImage

Выбираем и ставим нужный.

PS> Install-ContainerImage -Name WindowsServerCore
Устанавливаем контейнер на локальный сервер
Устанавливаем контейнер на локальный сервер

Проверяем, что образ действительно находится в локальном репозитории:

PS> Get-ContainerImage

Name Publisher Version IsOSImage
---- --------- ------- ---------
WindowsServerCore CN=Microsoft 10.0.10586.0        True

Для создания контейнера из образа нужно указать его имя, исходный образ и имя Virtual Switch:

PS> New-Container -Name "WindowsCore" -ContainerImageName "WindowsServerCore" -SwitchName External

В результате в ОС появляются файлы, содержащие описание нового контейнера. Дополнительно можно указать максимальный размер памяти, аккаунт для доступа, версию, издателя, путь, где создать контейнер, и так далее. Можем проверить его наличие при помощи Get-Container. И запускаем:

PS> Start-Container "WindowsCore"

В этот момент контейнеру выделяются ресурсы, и, в отличие от виртуальной машины, контейнер стартует практически мгновенно. Остановка производится при помощи командлета Stop-Container.
Подключаемся при помощи PowerShell remoting:

PS> Enter-PSSession -ContainerName WindowsCore -RunAsAdministrator

Теперь можем выполнить любые действия как с обычной виртуальной машиной. Например, установить новую роль:

PS> Install-WindowsFeature web-server

Чтобы сохранить установки, на основе контейнера можем создать образ. При этом система автоматически регистрирует зависимости между новым и базовым образом:

PS> New-ContainerImage -Name "WindowsIIS" -ContainerImageName "WindowsCore"

Можем проверить данные об образе — имя и родительский образ:

PS> Get-ContainerImage | select Name, ParentImage

Если теперь запустить образ WindowsIIS и проверить установленные службы, то увидим наличие IIS.

 

Дополнительные операции

Для изменения настроек параметров контейнера предложен целый набор командлетов Add-Container и Set-Container, назначение большинства понятно из названия.

Добавим сетевой адаптер внутрь контейнера, подключим его к созданному ранее Virtual Switch и активируем соединение:

PS> Add-ContainerNetworkAdapter -ContainerName "WindowsIIS" -SwitchName "External"
PS> Connect-ContainerNetworkAdapter -ContainerName "WindowsIIS" -SwitchName "External"

Так же просто создаются общие папки между контейнером и сервером. Добавим в контейнере новый каталог:

PS> New-Item -Type Directory С:\share

Затем создаем новую общую папку, выполнив на сервере

PS> Add-ContainerSharedFolder -ContainerName "WindowsIIS" -SourcePath c:\share -DestinationPath c:\share\WindowsIIS

После этого необходимо перезапустить контейнер.

 

Использование Docker

Как уже говорилось, кроме PowerShell, для управления контейнерами могут быть использованы утилиты Docker. С точки зрения унификации это большой плюс: тем, кто раньше работал с Docker, не нужно изучать новые инструменты. Docker не устанавливается при развертывании на хосте контейнеров, это нужно сделать самому или использовать скрипты New-ContainerHost или Install-ContainerHost, о которых говорилось выше. В процессе потребуется установить клиент и запустить демон Docker с нужными параметрами. Возможно, в будущем процесс упростится и нужный пакет появится в OneGet. Пока в нем находится лишь пакет posh-docker, реализующий автодополнение команд Docker в командной строке PowerShell:

PS> Install-Module -Name posh-docker

Разработчики предлагают свой вариант установки и настройки Docker, предполагающий использование NSSM, по ссылке есть все команды и скрипт. Для тестирования можно поступить проще. Скачиваем docker.exe и помещаем в каталог system32:

PS> wget https://aka.ms/tp4/docker -OutFile $env:SystemRoot\system32\docker.exe

Запускаем службу Docker, не забыв открыть в файрволе стандартный для Docker 2375-й порт:

PS> Start-Process cmd "/k docker daemon -D -b External -H 0.0.0.0:2375”

Теперь можем работать как с обычным Docker, только в Windows. Смотрим список доступных локальных образов:

PS> docker images

Должны увидеть установленные при помощи PowerShell образы, можем их использовать. Но также есть готовые образы и в репозитории Docker:

PS> docker search microsoft

Запускаем нужный:

PS> docker run -it --name demo microsoft/nano-iis cmd

Получаем в результате доступ к командной строке. Выполняем все настройки, выходим и сохраняем результат в образ:

C:\> exit
PS> docker commit demo windowsiis
Ищем образ в репозитории Docker
Ищем образ в репозитории Docker
 

Вывод

Возможность запускать приложения в безопасной изолированной среде без увеличения нагрузки на ОС — несомненно, большой плюс новой версии Windows Server 2016. Поэтому новая фича будет востребована при развертывании и масштабировании сервисов среди разработчиков. Остается дождаться окончательного релиза.

  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    1 Комментарий
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии