Чем Docker отличается от виртуальной машины.

docker containers virtual-machine virtualization


Я продолжаю перечитывать документацию Docker, чтобы попытаться понять разницу между Docker и полной виртуальной машиной. Как ему удается обеспечить полную файловую систему, изолированную сетевую среду и т. Д., Не будучи таким тяжелым?

Почему развертывание ПО на образ Docker (если это правильный термин)проще,чем простое развертывание в последовательной производственной среде?




Answer 1 Ken Cochrane


Изначально Docker использовал контейнеры LinuX (LXC), но позже переключился на runC (ранее известный как libcontainer ), который работает в той же операционной системе, что и его хост. Это позволяет ему совместно использовать много ресурсов операционной системы хоста. Кроме того, он использует многоуровневую файловую систему ( AuFS ) и управляет сетью.

AuFS является многоуровневой файловой системой,так что вы можете иметь часть только для чтения и часть для записи,которые объединены вместе.Можно иметь общие части операционной системы только для чтения (и разделить их между всеми контейнерами),а затем дать каждому контейнеру свою собственную монтировку для записи.

Итак, допустим, у вас есть изображение контейнера в 1 ГБ; если вы хотите использовать полную виртуальную машину, вам потребуется 1 ГБ x количество виртуальных машин, которое вы хотите. С Docker и AuFS вы можете разделить большую часть 1 ГБ между всеми контейнерами, и если у вас есть 1000 контейнеров, у вас все еще может быть только чуть более 1 ГБ пространства для ОС контейнеров (при условии, что все они работают под одним и тем же образом ОС) ,

Полноценная виртуализированная система получает собственный набор выделенных ей ресурсов и делает минимальное совместное использование.Вы получаете больше изоляции,но она намного тяжелее (требует больше ресурсов).С Docker вы получаете меньше изоляции,но контейнеры легкие (требуют меньше ресурсов).Поэтому вы можете легко запускать тысячи контейнеров на хосте,и он даже не моргнет.Попробуйте сделать это с Xen,и если у вас нет действительно большого хоста,я не думаю,что это возможно.

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

Для каждого типа виртуализированных систем есть свои плюсы и минусы.Если вы хотите полную изоляцию с гарантированными ресурсами,то полная ВМ-это то,что нужно.Если вы просто хотите изолировать процессы друг от друга и хотите запустить тонну процессов на хосте разумного размера,то DockerLXCrunC,похоже,будет правильным решением.

Для получения дополнительной информации, ознакомьтесь с этим набором постов в блоге, которые хорошо объясняют, как работает LXC.

Почему развертывание программного обеспечения на образ докеров (если это правильный термин)проще,чем простое развертывание в последовательной производственной среде?

Развертывание согласованной производственной среды легче сказать, чем сделать. Даже если вы используете такие инструменты, как Chef и Puppet , всегда есть обновления ОС и другие вещи, которые меняются между хостами и средами.

Docker дает вам возможность создавать снимки ОС в общий образ,а также упрощает развертывание на других хостах Docker.Локально,dev,qa,prod и т.д.:все один и тот же образ.Конечно,вы можете сделать это с помощью других инструментов,но не так просто и быстро.

Это отлично подходит для тестирования; Допустим, у вас есть тысячи тестов, которые необходимо подключить к базе данных, и каждый тест требует первоначальной копии базы данных и внесет изменения в данные. Классический подход к этому - сбросить базу данных после каждого теста либо с помощью пользовательского кода, либо с помощью таких инструментов, как Flyway - это может занять очень много времени и означает, что тесты должны запускаться последовательно. Однако с помощью Docker вы можете создать образ вашей базы данных и запустить один экземпляр на тест, а затем запустить все тесты параллельно, поскольку вы знаете, что все они будут работать с одним и тем же снимком базы данных. Поскольку тесты выполняются параллельно и в контейнерах Docker, они могут выполняться одновременно на одном и том же блоке и должны заканчиваться намного быстрее. Попробуйте сделать это с полной виртуальной машиной.

Из комментариев...

Интересно! Полагаю,меня все еще смущает понятие "моментальный снимок[ting]операционной системы".Как это сделать без,ну,создания образа ОС?

Что ж, посмотрим, смогу ли я объяснить. Вы начинаете с базового образа, затем вносите свои изменения и фиксируете эти изменения с помощью Docker, и он создает изображение. Это изображение содержит только отличия от базы. Когда вы хотите запустить ваше изображение, вам также нужна база, и она накладывает ваше изображение поверх базы, используя многоуровневую файловую систему: как упоминалось выше, Docker использует AuFS. AuFS объединяет разные слои, и вы получаете то, что хотите; вам просто нужно запустить его. Вы можете продолжать добавлять все больше и больше изображений (слоев), и он будет продолжать сохранять только различия. Поскольку Docker обычно строится поверх готовых образов из реестра , вам редко приходится «снимать» всю ОС самостоятельно.




Answer 2 manu97


Хорошие ответы.Просто чтобы получить изображение представления контейнера против VM,посмотрите на изображение ниже.

enter image description here

Source




Answer 3 Shital Shah


Было бы полезно понять,как виртуализация и контейнеры работают на низком уровне.Это многое прояснит.

Примечание:Я немного упрощаю описание ниже.См.ссылки для получения дополнительной информации.

Как работает виртуализация на низком уровне?

В этом случае диспетчер виртуальных машин захватывает кольцо ЦП 0 (или «корневой режим» в более новых процессорах) и перехватывает все привилегированные вызовы, сделанные гостевой ОС, чтобы создать иллюзию того, что гостевая ОС имеет собственное оборудование. Интересный факт: до 1998 года считалось невозможным достичь этого в архитектуре x86, потому что такого перехвата не было. Люди в VMWare были первыми, кому пришла в голову идея переписать исполняемые байты в памяти для привилегированных вызовов гостевой ОС, чтобы добиться этого.

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

Как контейнеры работают на низком уровне?

Приблизительно в 2006 году люди, в том числе некоторые сотрудники Google, внедрили новую функцию уровня ядра, называемую пространствами имен (однако идея, существовавшая задолго до того, существовала во FreeBSD).). Одной из функций ОС является обеспечение совместного использования глобальных ресурсов, таких как сеть и диск, процессам. Что если эти глобальные ресурсы были обернуты в пространства имен, чтобы они были видны только тем процессам, которые выполняются в одном и том же пространстве имен? Скажем, вы можете получить кусок диска и поместить его в пространство имен X, а затем процессы, выполняющиеся в пространстве имен Y, не смогут увидеть или получить к нему доступ. Точно так же процессы в пространстве имен X не могут получить доступ к чему-либо в памяти, которая выделена для пространства имен Y. Конечно, процессы в X не могут видеть или общаться с процессами в пространстве имен Y. Это обеспечивает своего рода виртуализацию и изоляцию для глобальных ресурсов. Вот как работает Docker: каждый контейнер работает в своем собственном пространстве имен, но использует точно так жеЯдро, как и все другие контейнеры. Изоляция происходит потому, что ядру известно пространство имен, которое было назначено процессу, и во время вызовов API оно обеспечивает доступ к ресурсам только в своем собственном пространстве имен.

Теперь ограничения контейнеров и виртуальных машин должны быть очевидны: вы не можете запускать совершенно разные ОС в контейнерах, как в виртуальных машинах. Однако вы можете использовать разные дистрибутивы Linux, потому что они используют одно и то же ядро. Уровень изоляции не такой сильный, как в ВМ. На самом деле, в ранних реализациях для гостевого контейнера был способ получить хост. Также вы можете видеть, что при загрузке нового контейнера вся новая копия ОС запускается не так, как в VM. Все контейнеры имеют одно и то же ядро, Вот почему контейнеры имеют легкий вес. Кроме того, в отличие от ВМ, вам не нужно предварительно выделять значительный кусок памяти для контейнеров, потому что мы не запускаем новую копию ОС. Это позволяет запускать тысячи контейнеров в одной ОС, в то же время помещая их в «песочницу», что может быть невозможно, если бы мы работали с отдельной копией ОС на собственной виртуальной машине.




Answer 4 aholbreich


Мне нравится ответ Кена Кокрейна.

Но я хочу добавить дополнительную точку зрения,не описанную здесь подробно.На мой взгляд,Докер отличается и в целом.В отличие от ВМ,Docker-это не (только)оптимальное разделение ресурсов на оборудование,более того,он предоставляет "систему" для упаковочного применения (предпочтительнее,но не обязательнее,как набор микроуслуг).

Для меня это соответствует разрыву между инструментами, ориентированными на разработчика, такими как rpm, пакеты Debian , Maven , npm + Git с одной стороны, и инструментами ops, такими как Puppet , VMware, Xen, вы называете это ...

Почему развертывание программного обеспечения на образ докеров (если это правильный термин)проще,чем простое развертывание в последовательной производственной среде?

Ваш вопрос предполагает некоторую непротиворечивую производственную среду. Но как сохранить это последовательным? Рассмотрим некоторое количество (> 10) серверов и приложений, этапов в конвейере.

Чтобы синхронизировать это, вы начнете использовать что-то вроде Puppet, Chef или ваших собственных сценариев инициализации, неопубликованных правил и / или большого количества документации ... Теоретически серверы могут работать неограниченное время и быть полностью согласованными и актуальными. Практика не позволяет полностью управлять конфигурацией сервера, поэтому существуют значительные возможности для отклонения конфигурации и неожиданных изменений в работающих серверах.

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

С экосистемой Docker вам никогда не придется перемещаться по гигабайтам при "небольших изменениях" (спасибо aufs и Registry),и вам не придется беспокоиться о потере производительности при упаковке приложений в контейнер Docker во время работы.Вам не нужно беспокоиться о версиях этого образа.

И,наконец,Вы даже часто сможете воспроизводить сложные производственные среды даже на своем ноутбуке под управлением Linux (не звоните мне,если в Вашем случае это не сработает ;)).

И,конечно же,вы можете запускать контейнеры Docker в ВМ (это хорошая идея).Сократите время инициализации сервера на уровне ВМ.Все вышеперечисленное может управляться Docker.

PS Между тем Docker использует собственную реализацию "libcontainer" вместо LXC. Но LXC все еще можно использовать.




Answer 5 Ashish Bista


Докер-это не методология виртуализации.Он полагается на другие инструменты,которые на самом деле реализуют виртуализацию на базе контейнеров или на уровне операционной системы.Для этого Docker изначально использовал LXC драйвер,а затем перешел на libcontainer,который теперь переименован в runc.В основном Docker концентрируется на автоматизации развертывания приложений внутри контейнеров приложений.Контейнеры приложений предназначены для упаковки и запуска одной службы,в то время как системные контейнеры предназначены для запуска нескольких процессов,таких как виртуальные машины.Таким образом,Docker рассматривается в качестве инструмента управления контейнерами или развертывания приложений на контейнерных системах.

Чтобы узнать,чем она отличается от других виртуализаций,давайте рассмотрим виртуализацию и ее типы.Тогда будет проще понять,в чем разница.

Virtualization

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

Hypervisor

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

Стремительное развитие технологий виртуализации,в первую очередь в облаке,привело к дальнейшему использованию виртуализации,позволив создать несколько виртуальных серверов на одном физическом сервере с помощью гипервизоров,таких как Xen,VMware Player,KVM и т.д.,а также включить поддержку аппаратного обеспечения в товарные процессоры,такие как Intel VT и AMD-V.

Типы виртуализации

Метод виртуализации можно разделить на категории в зависимости от того,как он имитирует аппаратное обеспечение гостевой операционной системы и эмулирует гостевую операционную среду.В основном,существует три типа виртуализации:

  • Emulation
  • Paravirtualization
  • Виртуализация на базе контейнеров

Emulation

Эмуляция,также известная как полная виртуализация,запускает ядро ОС виртуальной машины полностью в программном обеспечении.Гипервизор,используемый в этом типе,известен как гипервизор типа 2.Он устанавливается в верхней части операционной системы хоста,которая отвечает за трансляцию кода гостевого ядра ОС в инструкции к программному обеспечению.Перевод осуществляется полностью в программном обеспечении и не требует аппаратного обеспечения.Эмуляция позволяет запустить любую немодифицированную операционную систему,поддерживающую эмулируемое окружение.Недостатком такого типа виртуализации является дополнительная нагрузка на системные ресурсы,что приводит к снижению производительности по сравнению с другими типами виртуализации.

Emulation

Примеры в этой категории включают VMware Player,VirtualBox,QEMU,Bochs,Parallels и др.

Paravirtualization

Паравиртуализация, также известная как гипервизор 1-го типа, выполняется непосредственно на аппаратном уровне или «голым железом» и предоставляет услуги виртуализации непосредственно для виртуальных машин, работающих на нем. Это помогает операционной системе, виртуализированному оборудованию и реальному оборудованию сотрудничать для достижения оптимальной производительности. Эти гипервизоры, как правило, занимают довольно мало места и сами по себе не требуют обширных ресурсов.

Примеры в этой категории включают Xen,KVM и т.д.

Paravirtualization

Контейнерная виртуализация

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

Container-based virtualization

Концепция контейнера стала возможной благодаря функции пространств имен, добавленной в ядро ​​Linux версии 2.6.24. Контейнер добавляет свой идентификатор для каждого процесса и добавляет новые проверки контроля доступа к каждому системному вызову. Доступ к нему осуществляется с помощью системного вызова clone (), который позволяет создавать отдельные экземпляры ранее глобальных пространств имен.

Пространства имен могут использоваться различными способами,но наиболее распространенным подходом является создание изолированного контейнера,не имеющего видимости или доступа к объектам вне контейнера.Процессы,запущенные внутри контейнера,кажутся запущенными на обычной системе Linux,хотя они разделяют базовое ядро с процессами,расположенными в других пространствах имен,то же самое происходит и с другими типами объектов.Например,при использовании пространств имен,пользователь root внутри контейнера не рассматривается как пользователь root вне контейнера,добавляя дополнительную безопасность.

Подсистема Linux Control Groups (cgroups),следующий основной компонент для обеспечения виртуализации на основе контейнеров,используется для группировки процессов и управления их совокупным потреблением ресурсов.Она обычно используется для ограничения потребления памяти и процессора контейнеров.Так как контейнерная система Linux имеет только одно ядро и ядро имеет полную видимость контейнеров,существует только один уровень выделения и планирования ресурсов.

Для контейнеров Linux доступно несколько инструментов управления,в том числе LXC,LXD,systemd-nspawn,lmctfy,Warden,Linux-VServer,OpenVZ,Docker и др.

Контейнеры против виртуальных машин

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

Так как виртуализация на базе контейнеров практически не вносит никаких накладных расходов в работу хост-машины,виртуализация на базе контейнеров имеет практически собственную производительность.

Для контейнерной виртуализации,в отличие от других виртуализаций,не требуется никакого дополнительного программного обеспечения.

Все контейнеры на хост-машине совместно используют планировщик хост-машины,что позволяет экономить дополнительные ресурсы.

Состояния контейнеров (изображения докера или LXC)имеют небольшой размер по сравнению с изображениями виртуальных машин,поэтому изображения контейнеров легко распространять.

Управление ресурсами в контейнерах осуществляется через cgroups. Cgroups не позволяет контейнерам потреблять больше ресурсов, чем выделено им. Однако на данный момент все ресурсы хост-машины видны в виртуальных машинах, но не могут быть использованы. Это можно реализовать, запустив top или htop одновременно на контейнерах и хост-машине. Вывод во всех средах будет выглядеть одинаково.

Update:

Как Docker запускает контейнеры в системах, отличных от Linux?

Если контейнеры возможны благодаря возможностям,имеющимся в ядре Linux,то очевидным вопросом является то,как не-Linux системы запускают контейнеры.И в Docker'е для Mac,и в Windows для запуска контейнеров используются Linux VM.Docker Toolbox используется для запуска контейнеров на виртуальных ВМ.Но последний Docker использует Hyper-V в Windows и Hypervisor.framework в Mac.

Теперь позвольте мне подробно описать,как Docker for Mac управляет контейнерами.

Docker для Mac использует https://github.com/moby/hyperkit для эмуляции возможностей гипервизора, а Hyperkit использует hypervisor.framework в своей основе. Hypervisor.framework - это родное гипервизорное решение для Mac. Hyperkit также использует VPNKit и DataKit для пространства имен сети и файловой системы соответственно.

Linux VM,которую Docker запускает на Mac,доступна только для чтения.Тем не менее,вы можете использовать ее,запустив:

screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty .

Теперь мы даже можем проверить версию ядра этой ВМ:

# uname -a Linux linuxkit-025000000001 4.9.93-linuxkit-aufs #1 SMP Wed Jun 6 16:86_64 Linux .

Все контейнеры проходят внутри этой ВМ.

Есть некоторые ограничения для hypervisor.framework. Из-за этого Docker не предоставляет сетевой интерфейс docker0 в Mac. Таким образом, вы не можете получить доступ к контейнерам с хоста. На данный момент docker0 доступен только внутри виртуальной машины.

Hyper-v-это встроенный гипервизор в Windows.Они также пытаются использовать возможности Windows 10 для естественного запуска систем Linux.