В *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.

Продолжение статьи доступно только подписчикам

Вариант 1. Оформи подписку на «Хакер», чтобы читать все статьи на сайте

Подписка позволит тебе в течение указанного срока читать ВСЕ платные материалы сайта, включая эту статью. Мы принимаем оплату банковскими картами, электронными деньгами и переводами со счетов мобильных операторов. Подробнее о подписке

Вариант 2. Купи одну статью

Заинтересовала статья, но нет возможности оплатить подписку? Тогда этот вариант для тебя! Обрати внимание: этот способ покупки доступен только для статей, опубликованных более двух месяцев назад.


Комментарии

Подпишитесь на ][, чтобы участвовать в обсуждении

Обсуждение этой статьи доступно только нашим подписчикам. Вы можете войти в свой аккаунт или зарегистрироваться и оплатить подписку, чтобы свободно участвовать в обсуждении.

Check Also

Кеш-атаки по сторонним каналам. Что произошло в области утечек на аппаратном уровне за последние два года

Несмотря на то что до 2016 года существовало лишь несколько публикаций о кеш-атаках на сма…